mirror of
https://github.com/libretro/Mesen.git
synced 2025-01-10 10:50:10 +00:00
Debugger: Source-level debugging (for CC65/CA65 projects)
This commit is contained in:
parent
e1a74e90e5
commit
acf49e4226
@ -30,6 +30,7 @@ namespace Mesen.GUI.Config
|
||||
|
||||
public class DebugViewInfo
|
||||
{
|
||||
public bool ShowSourceAsComments = false;
|
||||
public ByteCodePosition ByteCodePosition = ByteCodePosition.Hidden;
|
||||
public PrgAddressPosition PrgAddressPosition = PrgAddressPosition.Hidden;
|
||||
public int TextZoom = 100;
|
||||
|
@ -124,6 +124,8 @@ namespace Mesen.GUI.Config
|
||||
public XmlKeys CodeWindow_ToggleBreakpoint = Keys.F9;
|
||||
[ShortcutName("Code Window: Disable/Enable Breakpoint")]
|
||||
public XmlKeys CodeWindow_DisableEnableBreakpoint = Keys.Control | Keys.F9;
|
||||
[ShortcutName("Code Window: Switch View (Disassembly / Source View)")]
|
||||
public XmlKeys CodeWindow_SwitchView = Keys.Control | Keys.Q;
|
||||
|
||||
[ShortcutName("Function List: Edit Label")]
|
||||
public XmlKeys FunctionList_EditLabel = Keys.F2;
|
||||
|
@ -84,7 +84,7 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
public static void ToggleBreakpoint(int relativeAddress, AddressTypeInfo info, bool toggleEnabled)
|
||||
{
|
||||
if(relativeAddress >= 0) {
|
||||
if(relativeAddress >= 0 || info.Address >= 0) {
|
||||
Breakpoint breakpoint = BreakpointManager.GetMatchingBreakpoint(relativeAddress, info);
|
||||
if(breakpoint != null) {
|
||||
if(toggleEnabled) {
|
||||
|
184
GUI.NET/Debugger/CodeTooltipManager.cs
Normal file
184
GUI.NET/Debugger/CodeTooltipManager.cs
Normal file
@ -0,0 +1,184 @@
|
||||
using Mesen.GUI.Config;
|
||||
using Mesen.GUI.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
class CodeTooltipManager
|
||||
{
|
||||
private bool _preventCloseTooltip = false;
|
||||
private string _hoverLastWord = "";
|
||||
private int _hoverLastLineAddress = -1;
|
||||
private Point _previousLocation;
|
||||
private Form _codeTooltip = null;
|
||||
private Control _owner = null;
|
||||
private ctrlScrollableTextbox _codeViewer = null;
|
||||
|
||||
public string Code { get; set; }
|
||||
public Ld65DbgImporter SymbolProvider { get; set; }
|
||||
|
||||
public CodeTooltipManager(Control owner, ctrlScrollableTextbox codeViewer)
|
||||
{
|
||||
_owner = owner;
|
||||
_codeViewer = codeViewer;
|
||||
}
|
||||
|
||||
public void ShowTooltip(string word, Dictionary<string, string> values, int lineAddress, AddressTypeInfo? previewAddress)
|
||||
{
|
||||
if(_hoverLastWord != word || _hoverLastLineAddress != lineAddress || _codeTooltip == null) {
|
||||
if(!_preventCloseTooltip && _codeTooltip != null) {
|
||||
_codeTooltip.Close();
|
||||
_codeTooltip = null;
|
||||
}
|
||||
|
||||
if(ConfigManager.Config.DebugInfo.ShowOpCodeTooltips && frmOpCodeTooltip.IsOpCode(word)) {
|
||||
_codeTooltip = new frmOpCodeTooltip(word, lineAddress);
|
||||
} else {
|
||||
_codeTooltip = new frmCodeTooltip(values, previewAddress.HasValue && previewAddress.Value.Type == AddressType.PrgRom ? previewAddress : null, Code, SymbolProvider);
|
||||
}
|
||||
_codeTooltip.Left = Cursor.Position.X + 10;
|
||||
_codeTooltip.Top = Cursor.Position.Y + 10;
|
||||
_codeTooltip.Show(_owner);
|
||||
}
|
||||
_codeTooltip.Left = Cursor.Position.X + 10;
|
||||
_codeTooltip.Top = Cursor.Position.Y + 10;
|
||||
|
||||
_preventCloseTooltip = true;
|
||||
_hoverLastWord = word;
|
||||
_hoverLastLineAddress = lineAddress;
|
||||
}
|
||||
|
||||
public void Close(bool forceClose = false)
|
||||
{
|
||||
if((!_preventCloseTooltip || forceClose) && _codeTooltip != null) {
|
||||
_codeTooltip.Close();
|
||||
_codeTooltip = null;
|
||||
}
|
||||
_preventCloseTooltip = false;
|
||||
}
|
||||
|
||||
public void DisplayAddressTooltip(string word, UInt32 address)
|
||||
{
|
||||
byte byteValue = InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, address);
|
||||
UInt16 wordValue = (UInt16)(byteValue | (InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, address + 1) << 8));
|
||||
|
||||
var values = new Dictionary<string, string>() {
|
||||
{ "Address", "$" + address.ToString("X4") },
|
||||
{ "Value", $"${byteValue.ToString("X2")} (byte){Environment.NewLine}${wordValue.ToString("X4")} (word)" }
|
||||
};
|
||||
|
||||
this.ShowTooltip(word, values, -1, new AddressTypeInfo() { Address = (int)address, Type = AddressType.Register });
|
||||
}
|
||||
|
||||
private void DisplayLabelTooltip(string word, CodeLabel label)
|
||||
{
|
||||
int relativeAddress = InteropEmu.DebugGetRelativeAddress(label.Address, label.AddressType);
|
||||
byte byteValue = relativeAddress >= 0 ? InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, (UInt32)relativeAddress) : (byte)0;
|
||||
UInt16 wordValue = relativeAddress >= 0 ? (UInt16)(byteValue | (InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, (UInt32)relativeAddress + 1) << 8)) : (UInt16)0;
|
||||
|
||||
var values = new Dictionary<string, string>() {
|
||||
{ "Label", label.Label },
|
||||
{ "Address", "$" + relativeAddress.ToString("X4") },
|
||||
{ "Value", (relativeAddress >= 0 ? $"${byteValue.ToString("X2")} (byte){Environment.NewLine}${wordValue.ToString("X4")} (word)" : "n/a") },
|
||||
};
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(label.Comment)) {
|
||||
values["Comment"] = label.Comment;
|
||||
}
|
||||
|
||||
ShowTooltip(word, values, -1, new AddressTypeInfo() { Address = (int)label.Address, Type = label.AddressType });
|
||||
}
|
||||
|
||||
private void DisplaySymbolTooltip(Ld65DbgImporter.SymbolInfo symbol)
|
||||
{
|
||||
int relativeAddress = symbol.Address.HasValue ? symbol.Address.Value : -1;
|
||||
byte byteValue = relativeAddress >= 0 ? InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, (UInt32)relativeAddress) : (byte)0;
|
||||
UInt16 wordValue = relativeAddress >= 0 ? (UInt16)(byteValue | (InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, (UInt32)relativeAddress + 1) << 8)) : (UInt16)0;
|
||||
|
||||
AddressTypeInfo? addressInfo = SymbolProvider.GetSymbolAddressInfo(symbol);
|
||||
|
||||
if(addressInfo != null) {
|
||||
var values = new Dictionary<string, string>() {
|
||||
{ "Symbol", symbol.Name }
|
||||
};
|
||||
|
||||
if(relativeAddress >= 0) {
|
||||
values["CPU Address"] = "$" + relativeAddress.ToString("X4");
|
||||
};
|
||||
|
||||
if(addressInfo.Value.Type == AddressType.PrgRom) {
|
||||
values["PRG Offset"] = "$" + addressInfo.Value.Address.ToString("X4");
|
||||
}
|
||||
|
||||
values["Value"] = (relativeAddress >= 0 ? $"${byteValue.ToString("X2")} (byte){Environment.NewLine}${wordValue.ToString("X4")} (word)" : "n/a");
|
||||
|
||||
ShowTooltip(symbol.Name, values, -1, addressInfo);
|
||||
} else {
|
||||
var values = new Dictionary<string, string>() {
|
||||
{ "Symbol", symbol.Name },
|
||||
{ "Constant", "$" + relativeAddress.ToString("X2") }
|
||||
};
|
||||
ShowTooltip(symbol.Name, values, -1, addressInfo);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessMouseMove(Point location)
|
||||
{
|
||||
if(_previousLocation != location) {
|
||||
this.Close();
|
||||
|
||||
_previousLocation = location;
|
||||
|
||||
string word = _codeViewer.GetWordUnderLocation(location);
|
||||
if(word.StartsWith("$")) {
|
||||
try {
|
||||
UInt32 address = UInt32.Parse(word.Substring(1), NumberStyles.AllowHexSpecifier);
|
||||
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(address, ref info);
|
||||
|
||||
if(info.Address >= 0) {
|
||||
CodeLabel label = LabelManager.GetLabel((UInt32)info.Address, info.Type);
|
||||
if(label == null) {
|
||||
DisplayAddressTooltip(word, address);
|
||||
} else {
|
||||
DisplayLabelTooltip(word, label);
|
||||
}
|
||||
} else {
|
||||
DisplayAddressTooltip(word, address);
|
||||
}
|
||||
} catch { }
|
||||
} else {
|
||||
int address = _codeViewer.GetLineNumberAtPosition(location.Y);
|
||||
if(SymbolProvider != null) {
|
||||
int rangeStart, rangeEnd;
|
||||
if(_codeViewer.GetNoteRangeAtLocation(location.Y, out rangeStart, out rangeEnd)) {
|
||||
Ld65DbgImporter.SymbolInfo symbol = SymbolProvider.GetSymbol(word, rangeStart, rangeEnd);
|
||||
if(symbol != null) {
|
||||
DisplaySymbolTooltip(symbol);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CodeLabel label = LabelManager.GetLabel(word);
|
||||
if(label != null) {
|
||||
DisplayLabelTooltip(word, label);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(ConfigManager.Config.DebugInfo.ShowOpCodeTooltips && frmOpCodeTooltip.IsOpCode(word)) {
|
||||
ShowTooltip(word, null, -1, new AddressTypeInfo() { Address = address, Type = AddressType.Register });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,20 +20,6 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public Font BaseFont
|
||||
{
|
||||
get { return this.ScrollableTextbox.BaseFont; }
|
||||
set { this.ScrollableTextbox.BaseFont = value; }
|
||||
}
|
||||
|
||||
public int TextZoom
|
||||
{
|
||||
get { return this.ScrollableTextbox?.TextZoom ?? 100; }
|
||||
set { this.ScrollableTextbox.TextZoom = value; }
|
||||
}
|
||||
|
||||
public void OpenSearchBox()
|
||||
{
|
||||
this.ScrollableTextbox.OpenSearchBox();
|
||||
@ -80,9 +66,9 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
this.ScrollableTextbox.ScrollToLineNumber(0);
|
||||
}
|
||||
|
||||
public string GetWordUnderLocation(Point position, bool useCompareText = false)
|
||||
public string GetWordUnderLocation(Point position)
|
||||
{
|
||||
return this.ScrollableTextbox.GetWordUnderLocation(position, useCompareText);
|
||||
return this.ScrollableTextbox.GetWordUnderLocation(position);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
458
GUI.NET/Debugger/Controls/CodeViewerActions.Designer.cs
generated
Normal file
458
GUI.NET/Debugger/Controls/CodeViewerActions.Designer.cs
generated
Normal file
@ -0,0 +1,458 @@
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
partial class CodeViewerActions
|
||||
{
|
||||
/// <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.components = new System.ComponentModel.Container();
|
||||
this.contextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.mnuMarkSelectionAs = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMarkAsCode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMarkAsData = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMarkAsUnidentifiedData = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuEditSelectedCode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuEditSubroutine = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuUndoPrgChrEdit = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuCopySelection = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuShowNextStatement = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuSetNextStatement = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuShowCodeNotes = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuShowByteCodeOnLeft = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuShowByteCodeBelow = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuHideByteCode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuShowLineNotes = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPrgShowInline = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPrgAddressReplace = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPrgAddressBelow = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuHidePrgAddresses = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.sepEditLabel = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuEditLabel = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuEditInMemoryViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuToggleBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.sepAddToWatch = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuAddToWatch = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuFindOccurrences = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuGoToLocation = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuShowInSplitView = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.sepNavigation = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuNavigateBackward = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuNavigateForward = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.sepSwitchView = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuSwitchView = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuShowSourceAsComments = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.contextMenu.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// contextMenu
|
||||
//
|
||||
this.contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuMarkSelectionAs,
|
||||
this.toolStripMenuItem4,
|
||||
this.mnuEditSelectedCode,
|
||||
this.mnuEditSubroutine,
|
||||
this.mnuUndoPrgChrEdit,
|
||||
this.mnuCopySelection,
|
||||
this.toolStripMenuItem7,
|
||||
this.mnuShowNextStatement,
|
||||
this.mnuSetNextStatement,
|
||||
this.toolStripMenuItem1,
|
||||
this.mnuShowCodeNotes,
|
||||
this.mnuShowLineNotes,
|
||||
this.sepEditLabel,
|
||||
this.mnuEditLabel,
|
||||
this.mnuEditInMemoryViewer,
|
||||
this.mnuToggleBreakpoint,
|
||||
this.sepAddToWatch,
|
||||
this.mnuAddToWatch,
|
||||
this.mnuFindOccurrences,
|
||||
this.toolStripMenuItem2,
|
||||
this.mnuGoToLocation,
|
||||
this.mnuShowInSplitView,
|
||||
this.sepNavigation,
|
||||
this.mnuNavigateBackward,
|
||||
this.mnuNavigateForward,
|
||||
this.sepSwitchView,
|
||||
this.mnuSwitchView,
|
||||
this.mnuShowSourceAsComments});
|
||||
this.contextMenu.Name = "contextMenuWatch";
|
||||
this.contextMenu.Size = new System.Drawing.Size(254, 514);
|
||||
this.contextMenu.Closed += new System.Windows.Forms.ToolStripDropDownClosedEventHandler(this.contextMenuCode_Closed);
|
||||
this.contextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuCode_Opening);
|
||||
//
|
||||
// mnuMarkSelectionAs
|
||||
//
|
||||
this.mnuMarkSelectionAs.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuMarkAsCode,
|
||||
this.mnuMarkAsData,
|
||||
this.mnuMarkAsUnidentifiedData});
|
||||
this.mnuMarkSelectionAs.Name = "mnuMarkSelectionAs";
|
||||
this.mnuMarkSelectionAs.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuMarkSelectionAs.Text = "Mark selection as...";
|
||||
//
|
||||
// mnuMarkAsCode
|
||||
//
|
||||
this.mnuMarkAsCode.Image = global::Mesen.GUI.Properties.Resources.Accept;
|
||||
this.mnuMarkAsCode.Name = "mnuMarkAsCode";
|
||||
this.mnuMarkAsCode.Size = new System.Drawing.Size(199, 22);
|
||||
this.mnuMarkAsCode.Text = "Verified Code";
|
||||
this.mnuMarkAsCode.Click += new System.EventHandler(this.mnuMarkAsCode_Click);
|
||||
//
|
||||
// mnuMarkAsData
|
||||
//
|
||||
this.mnuMarkAsData.Image = global::Mesen.GUI.Properties.Resources.CheatCode;
|
||||
this.mnuMarkAsData.Name = "mnuMarkAsData";
|
||||
this.mnuMarkAsData.Size = new System.Drawing.Size(199, 22);
|
||||
this.mnuMarkAsData.Text = "Verified Data";
|
||||
this.mnuMarkAsData.Click += new System.EventHandler(this.mnuMarkAsData_Click);
|
||||
//
|
||||
// mnuMarkAsUnidentifiedData
|
||||
//
|
||||
this.mnuMarkAsUnidentifiedData.Image = global::Mesen.GUI.Properties.Resources.Help;
|
||||
this.mnuMarkAsUnidentifiedData.Name = "mnuMarkAsUnidentifiedData";
|
||||
this.mnuMarkAsUnidentifiedData.Size = new System.Drawing.Size(199, 22);
|
||||
this.mnuMarkAsUnidentifiedData.Text = "Unidentified Code/Data";
|
||||
this.mnuMarkAsUnidentifiedData.Click += new System.EventHandler(this.mnuMarkAsUnidentifiedData_Click);
|
||||
//
|
||||
// toolStripMenuItem4
|
||||
//
|
||||
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
|
||||
this.toolStripMenuItem4.Size = new System.Drawing.Size(250, 6);
|
||||
//
|
||||
// mnuEditSelectedCode
|
||||
//
|
||||
this.mnuEditSelectedCode.Image = global::Mesen.GUI.Properties.Resources.Edit;
|
||||
this.mnuEditSelectedCode.Name = "mnuEditSelectedCode";
|
||||
this.mnuEditSelectedCode.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuEditSelectedCode.Text = "Edit Selected Code";
|
||||
this.mnuEditSelectedCode.Click += new System.EventHandler(this.mnuEditSelectedCode_Click);
|
||||
//
|
||||
// mnuEditSubroutine
|
||||
//
|
||||
this.mnuEditSubroutine.Image = global::Mesen.GUI.Properties.Resources.Edit;
|
||||
this.mnuEditSubroutine.Name = "mnuEditSubroutine";
|
||||
this.mnuEditSubroutine.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuEditSubroutine.Text = "Edit Subroutine";
|
||||
this.mnuEditSubroutine.Click += new System.EventHandler(this.mnuEditSubroutine_Click);
|
||||
//
|
||||
// mnuUndoPrgChrEdit
|
||||
//
|
||||
this.mnuUndoPrgChrEdit.Image = global::Mesen.GUI.Properties.Resources.Undo;
|
||||
this.mnuUndoPrgChrEdit.Name = "mnuUndoPrgChrEdit";
|
||||
this.mnuUndoPrgChrEdit.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuUndoPrgChrEdit.Text = "Undo PRG/CHR Edit";
|
||||
this.mnuUndoPrgChrEdit.Click += new System.EventHandler(this.mnuUndoPrgChrEdit_Click);
|
||||
//
|
||||
// mnuCopySelection
|
||||
//
|
||||
this.mnuCopySelection.Image = global::Mesen.GUI.Properties.Resources.Copy;
|
||||
this.mnuCopySelection.Name = "mnuCopySelection";
|
||||
this.mnuCopySelection.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuCopySelection.Text = "Copy Selection";
|
||||
this.mnuCopySelection.Click += new System.EventHandler(this.mnuCopySelection_Click);
|
||||
//
|
||||
// toolStripMenuItem7
|
||||
//
|
||||
this.toolStripMenuItem7.Name = "toolStripMenuItem7";
|
||||
this.toolStripMenuItem7.Size = new System.Drawing.Size(250, 6);
|
||||
//
|
||||
// mnuShowNextStatement
|
||||
//
|
||||
this.mnuShowNextStatement.Name = "mnuShowNextStatement";
|
||||
this.mnuShowNextStatement.ShortcutKeyDisplayString = "";
|
||||
this.mnuShowNextStatement.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuShowNextStatement.Text = "Show Next Statement";
|
||||
this.mnuShowNextStatement.Click += new System.EventHandler(this.mnuShowNextStatement_Click);
|
||||
//
|
||||
// mnuSetNextStatement
|
||||
//
|
||||
this.mnuSetNextStatement.Name = "mnuSetNextStatement";
|
||||
this.mnuSetNextStatement.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuSetNextStatement.Text = "Set Next Statement";
|
||||
this.mnuSetNextStatement.Click += new System.EventHandler(this.mnuSetNextStatement_Click);
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(250, 6);
|
||||
//
|
||||
// mnuShowCodeNotes
|
||||
//
|
||||
this.mnuShowCodeNotes.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuShowByteCodeOnLeft,
|
||||
this.mnuShowByteCodeBelow,
|
||||
this.toolStripMenuItem5,
|
||||
this.mnuHideByteCode});
|
||||
this.mnuShowCodeNotes.Name = "mnuShowCodeNotes";
|
||||
this.mnuShowCodeNotes.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuShowCodeNotes.Text = "Byte Code Display";
|
||||
//
|
||||
// mnuShowByteCodeOnLeft
|
||||
//
|
||||
this.mnuShowByteCodeOnLeft.Name = "mnuShowByteCodeOnLeft";
|
||||
this.mnuShowByteCodeOnLeft.Size = new System.Drawing.Size(130, 22);
|
||||
this.mnuShowByteCodeOnLeft.Text = "On the left";
|
||||
this.mnuShowByteCodeOnLeft.Click += new System.EventHandler(this.mnuShowByteCodeOnLeft_Click);
|
||||
//
|
||||
// mnuShowByteCodeBelow
|
||||
//
|
||||
this.mnuShowByteCodeBelow.Name = "mnuShowByteCodeBelow";
|
||||
this.mnuShowByteCodeBelow.Size = new System.Drawing.Size(130, 22);
|
||||
this.mnuShowByteCodeBelow.Text = "Below";
|
||||
this.mnuShowByteCodeBelow.Click += new System.EventHandler(this.mnuShowByteCodeBelow_Click);
|
||||
//
|
||||
// toolStripMenuItem5
|
||||
//
|
||||
this.toolStripMenuItem5.Name = "toolStripMenuItem5";
|
||||
this.toolStripMenuItem5.Size = new System.Drawing.Size(127, 6);
|
||||
//
|
||||
// mnuHideByteCode
|
||||
//
|
||||
this.mnuHideByteCode.Name = "mnuHideByteCode";
|
||||
this.mnuHideByteCode.Size = new System.Drawing.Size(130, 22);
|
||||
this.mnuHideByteCode.Text = "Hidden";
|
||||
this.mnuHideByteCode.Click += new System.EventHandler(this.mnuHideByteCode_Click);
|
||||
//
|
||||
// mnuShowLineNotes
|
||||
//
|
||||
this.mnuShowLineNotes.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuPrgShowInline,
|
||||
this.mnuPrgAddressReplace,
|
||||
this.mnuPrgAddressBelow,
|
||||
this.toolStripMenuItem6,
|
||||
this.mnuHidePrgAddresses});
|
||||
this.mnuShowLineNotes.Name = "mnuShowLineNotes";
|
||||
this.mnuShowLineNotes.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuShowLineNotes.Text = "PRG Address Display";
|
||||
//
|
||||
// mnuPrgShowInline
|
||||
//
|
||||
this.mnuPrgShowInline.Name = "mnuPrgShowInline";
|
||||
this.mnuPrgShowInline.Size = new System.Drawing.Size(196, 22);
|
||||
this.mnuPrgShowInline.Text = "Inline Compact Display";
|
||||
this.mnuPrgShowInline.Click += new System.EventHandler(this.mnuShowInlineCompactDisplay_Click);
|
||||
//
|
||||
// mnuPrgAddressReplace
|
||||
//
|
||||
this.mnuPrgAddressReplace.Name = "mnuPrgAddressReplace";
|
||||
this.mnuPrgAddressReplace.Size = new System.Drawing.Size(196, 22);
|
||||
this.mnuPrgAddressReplace.Text = "Replace CPU address";
|
||||
this.mnuPrgAddressReplace.Click += new System.EventHandler(this.mnuReplaceCpuAddress_Click);
|
||||
//
|
||||
// mnuPrgAddressBelow
|
||||
//
|
||||
this.mnuPrgAddressBelow.Name = "mnuPrgAddressBelow";
|
||||
this.mnuPrgAddressBelow.Size = new System.Drawing.Size(196, 22);
|
||||
this.mnuPrgAddressBelow.Text = "Below CPU address";
|
||||
this.mnuPrgAddressBelow.Click += new System.EventHandler(this.mnuBelowCpuAddress_Click);
|
||||
//
|
||||
// toolStripMenuItem6
|
||||
//
|
||||
this.toolStripMenuItem6.Name = "toolStripMenuItem6";
|
||||
this.toolStripMenuItem6.Size = new System.Drawing.Size(193, 6);
|
||||
//
|
||||
// mnuHidePrgAddresses
|
||||
//
|
||||
this.mnuHidePrgAddresses.Name = "mnuHidePrgAddresses";
|
||||
this.mnuHidePrgAddresses.Size = new System.Drawing.Size(196, 22);
|
||||
this.mnuHidePrgAddresses.Text = "Hidden";
|
||||
this.mnuHidePrgAddresses.Click += new System.EventHandler(this.mnuHidePrgAddresses_Click);
|
||||
//
|
||||
// sepEditLabel
|
||||
//
|
||||
this.sepEditLabel.Name = "sepEditLabel";
|
||||
this.sepEditLabel.Size = new System.Drawing.Size(250, 6);
|
||||
//
|
||||
// mnuEditLabel
|
||||
//
|
||||
this.mnuEditLabel.Image = global::Mesen.GUI.Properties.Resources.EditLabel;
|
||||
this.mnuEditLabel.Name = "mnuEditLabel";
|
||||
this.mnuEditLabel.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuEditLabel.Text = "Edit Label";
|
||||
this.mnuEditLabel.Click += new System.EventHandler(this.mnuEditLabel_Click);
|
||||
//
|
||||
// mnuEditInMemoryViewer
|
||||
//
|
||||
this.mnuEditInMemoryViewer.Image = global::Mesen.GUI.Properties.Resources.CheatCode;
|
||||
this.mnuEditInMemoryViewer.Name = "mnuEditInMemoryViewer";
|
||||
this.mnuEditInMemoryViewer.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuEditInMemoryViewer.Text = "Edit in Memory Viewer";
|
||||
this.mnuEditInMemoryViewer.Click += new System.EventHandler(this.mnuEditInMemoryViewer_Click);
|
||||
//
|
||||
// mnuToggleBreakpoint
|
||||
//
|
||||
this.mnuToggleBreakpoint.Image = global::Mesen.GUI.Properties.Resources.Breakpoint;
|
||||
this.mnuToggleBreakpoint.Name = "mnuToggleBreakpoint";
|
||||
this.mnuToggleBreakpoint.ShortcutKeyDisplayString = "";
|
||||
this.mnuToggleBreakpoint.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuToggleBreakpoint.Text = "Toggle Breakpoint";
|
||||
this.mnuToggleBreakpoint.Click += new System.EventHandler(this.mnuToggleBreakpoint_Click);
|
||||
//
|
||||
// sepAddToWatch
|
||||
//
|
||||
this.sepAddToWatch.Name = "sepAddToWatch";
|
||||
this.sepAddToWatch.Size = new System.Drawing.Size(250, 6);
|
||||
//
|
||||
// mnuAddToWatch
|
||||
//
|
||||
this.mnuAddToWatch.Name = "mnuAddToWatch";
|
||||
this.mnuAddToWatch.ShortcutKeyDisplayString = "Ctrl+Click";
|
||||
this.mnuAddToWatch.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuAddToWatch.Text = "Add to Watch";
|
||||
this.mnuAddToWatch.Click += new System.EventHandler(this.mnuAddToWatch_Click);
|
||||
//
|
||||
// mnuFindOccurrences
|
||||
//
|
||||
this.mnuFindOccurrences.Image = global::Mesen.GUI.Properties.Resources.Find;
|
||||
this.mnuFindOccurrences.Name = "mnuFindOccurrences";
|
||||
this.mnuFindOccurrences.ShortcutKeyDisplayString = "Alt+Click";
|
||||
this.mnuFindOccurrences.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuFindOccurrences.Text = "Find Occurrences";
|
||||
this.mnuFindOccurrences.Click += new System.EventHandler(this.mnuFindOccurrences_Click);
|
||||
//
|
||||
// toolStripMenuItem2
|
||||
//
|
||||
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
|
||||
this.toolStripMenuItem2.Size = new System.Drawing.Size(250, 6);
|
||||
//
|
||||
// mnuGoToLocation
|
||||
//
|
||||
this.mnuGoToLocation.Name = "mnuGoToLocation";
|
||||
this.mnuGoToLocation.ShortcutKeyDisplayString = "Double Click";
|
||||
this.mnuGoToLocation.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuGoToLocation.Text = "Go to Location";
|
||||
this.mnuGoToLocation.Click += new System.EventHandler(this.mnuGoToLocation_Click);
|
||||
//
|
||||
// mnuShowInSplitView
|
||||
//
|
||||
this.mnuShowInSplitView.Image = global::Mesen.GUI.Properties.Resources.SplitView;
|
||||
this.mnuShowInSplitView.Name = "mnuShowInSplitView";
|
||||
this.mnuShowInSplitView.ShortcutKeyDisplayString = "Ctrl+Alt+Click";
|
||||
this.mnuShowInSplitView.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuShowInSplitView.Text = "Show in Split View";
|
||||
this.mnuShowInSplitView.Click += new System.EventHandler(this.mnuShowInSplitView_Click);
|
||||
//
|
||||
// sepNavigation
|
||||
//
|
||||
this.sepNavigation.Name = "sepNavigation";
|
||||
this.sepNavigation.Size = new System.Drawing.Size(250, 6);
|
||||
//
|
||||
// mnuNavigateBackward
|
||||
//
|
||||
this.mnuNavigateBackward.Image = global::Mesen.GUI.Properties.Resources.NavigateBack;
|
||||
this.mnuNavigateBackward.Name = "mnuNavigateBackward";
|
||||
this.mnuNavigateBackward.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuNavigateBackward.Text = "Navigate Backward";
|
||||
this.mnuNavigateBackward.Click += new System.EventHandler(this.mnuNavigateBackward_Click);
|
||||
//
|
||||
// mnuNavigateForward
|
||||
//
|
||||
this.mnuNavigateForward.Image = global::Mesen.GUI.Properties.Resources.NavigateForward;
|
||||
this.mnuNavigateForward.Name = "mnuNavigateForward";
|
||||
this.mnuNavigateForward.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuNavigateForward.Text = "Navigate Forward";
|
||||
this.mnuNavigateForward.Click += new System.EventHandler(this.mnuNavigateForward_Click);
|
||||
//
|
||||
// sepSwitchView
|
||||
//
|
||||
this.sepSwitchView.Name = "sepSwitchView";
|
||||
this.sepSwitchView.Size = new System.Drawing.Size(250, 6);
|
||||
//
|
||||
// mnuSwitchView
|
||||
//
|
||||
this.mnuSwitchView.Image = global::Mesen.GUI.Properties.Resources.SwitchView;
|
||||
this.mnuSwitchView.Name = "mnuSwitchView";
|
||||
this.mnuSwitchView.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuSwitchView.Text = "Switch to Source View";
|
||||
this.mnuSwitchView.Click += new System.EventHandler(this.mnuSwitchView_Click);
|
||||
//
|
||||
// mnuShowSourceAsComments
|
||||
//
|
||||
this.mnuShowSourceAsComments.CheckOnClick = true;
|
||||
this.mnuShowSourceAsComments.Name = "mnuShowSourceAsComments";
|
||||
this.mnuShowSourceAsComments.Size = new System.Drawing.Size(253, 22);
|
||||
this.mnuShowSourceAsComments.Text = "Show source code as comments";
|
||||
this.mnuShowSourceAsComments.Click += new System.EventHandler(this.mnuShowSourceAsComments_Click);
|
||||
//
|
||||
// CodeViewerActions
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Name = "CodeViewerActions";
|
||||
this.contextMenu.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuMarkSelectionAs;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuMarkAsCode;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuMarkAsData;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuMarkAsUnidentifiedData;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditSelectedCode;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditSubroutine;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuUndoPrgChrEdit;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuCopySelection;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem7;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowNextStatement;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuSetNextStatement;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowCodeNotes;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowByteCodeOnLeft;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowByteCodeBelow;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuHideByteCode;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowLineNotes;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPrgShowInline;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPrgAddressReplace;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPrgAddressBelow;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem6;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuHidePrgAddresses;
|
||||
private System.Windows.Forms.ToolStripSeparator sepEditLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditInMemoryViewer;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuToggleBreakpoint;
|
||||
private System.Windows.Forms.ToolStripSeparator sepAddToWatch;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAddToWatch;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuFindOccurrences;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGoToLocation;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowInSplitView;
|
||||
private System.Windows.Forms.ToolStripSeparator sepNavigation;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNavigateBackward;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNavigateForward;
|
||||
private System.Windows.Forms.ToolStripSeparator sepSwitchView;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuSwitchView;
|
||||
public System.Windows.Forms.ContextMenuStrip contextMenu;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowSourceAsComments;
|
||||
}
|
||||
}
|
561
GUI.NET/Debugger/Controls/CodeViewerActions.cs
Normal file
561
GUI.NET/Debugger/Controls/CodeViewerActions.cs
Normal file
@ -0,0 +1,561 @@
|
||||
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.Config;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
public partial class CodeViewerActions : UserControl
|
||||
{
|
||||
public event SetNextStatementEventHandler OnSetNextStatement;
|
||||
public event ShowInSplitViewEventHandler OnShowInSplitView;
|
||||
public event SwitchToSourceEventHandler OnSwitchView;
|
||||
|
||||
private int _lastClickedAddress = Int32.MaxValue;
|
||||
private string _newWatchValue = string.Empty;
|
||||
private string _lastWord = string.Empty;
|
||||
private Point _lastLocation = Point.Empty;
|
||||
private DebugViewInfo _config;
|
||||
|
||||
public ICodeViewer Viewer { get; set; }
|
||||
public bool SourceView { get; set; }
|
||||
|
||||
public CodeViewerActions()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public CodeViewerActions(ICodeViewer viewer, bool isSourceView) : this()
|
||||
{
|
||||
Viewer = viewer;
|
||||
SourceView = isSourceView;
|
||||
|
||||
this.InitShortcuts();
|
||||
}
|
||||
|
||||
private void InitShortcuts()
|
||||
{
|
||||
mnuEditInMemoryViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditInMemoryViewer));
|
||||
mnuEditLabel.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditLabel));
|
||||
mnuSetNextStatement.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_SetNextStatement));
|
||||
mnuShowNextStatement.InitShortcut(this, nameof(DebuggerShortcutsConfig.GoToProgramCounter));
|
||||
mnuToggleBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_ToggleBreakpoint));
|
||||
|
||||
mnuUndoPrgChrEdit.InitShortcut(this, nameof(DebuggerShortcutsConfig.Undo));
|
||||
mnuCopySelection.InitShortcut(this, nameof(DebuggerShortcutsConfig.Copy));
|
||||
|
||||
mnuSwitchView.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_SwitchView));
|
||||
|
||||
if(!SourceView) {
|
||||
mnuNavigateBackward.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateBack));
|
||||
mnuNavigateForward.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateForward));
|
||||
|
||||
mnuEditSelectedCode.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditSelectedCode));
|
||||
mnuEditSubroutine.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditSubroutine));
|
||||
|
||||
mnuMarkAsCode.InitShortcut(this, nameof(DebuggerShortcutsConfig.MarkAsCode));
|
||||
mnuMarkAsData.InitShortcut(this, nameof(DebuggerShortcutsConfig.MarkAsData));
|
||||
mnuMarkAsUnidentifiedData.InitShortcut(this, nameof(DebuggerShortcutsConfig.MarkAsUnidentified));
|
||||
}
|
||||
}
|
||||
|
||||
public void InitMenu(DebugViewInfo config)
|
||||
{
|
||||
_config = config;
|
||||
mnuPrgShowInline.Checked = false;
|
||||
mnuPrgAddressReplace.Checked = false;
|
||||
mnuPrgAddressBelow.Checked = false;
|
||||
mnuHidePrgAddresses.Checked = false;
|
||||
|
||||
mnuShowByteCodeOnLeft.Checked = false;
|
||||
mnuShowByteCodeBelow.Checked = false;
|
||||
mnuHideByteCode.Checked = false;
|
||||
|
||||
mnuShowSourceAsComments.Checked = config.ShowSourceAsComments;
|
||||
|
||||
switch(config.ByteCodePosition) {
|
||||
case ByteCodePosition.Left:
|
||||
Viewer.CodeViewer.ShowContentNotes = true;
|
||||
Viewer.CodeViewer.ShowSingleContentLineNotes = true;
|
||||
this.mnuShowByteCodeOnLeft.Checked = true;
|
||||
break;
|
||||
|
||||
case ByteCodePosition.Below:
|
||||
Viewer.CodeViewer.ShowContentNotes = true;
|
||||
Viewer.CodeViewer.ShowSingleContentLineNotes = false;
|
||||
this.mnuShowByteCodeBelow.Checked = true;
|
||||
break;
|
||||
|
||||
case ByteCodePosition.Hidden:
|
||||
Viewer.CodeViewer.ShowContentNotes = false;
|
||||
Viewer.CodeViewer.ShowSingleContentLineNotes = false;
|
||||
this.mnuHideByteCode.Checked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(config.PrgAddressPosition) {
|
||||
case PrgAddressPosition.Inline:
|
||||
Viewer.CodeViewer.ShowCompactPrgAddresses = true;
|
||||
Viewer.CodeViewer.ShowLineNumberNotes = false;
|
||||
Viewer.CodeViewer.ShowSingleLineLineNumberNotes = false;
|
||||
this.mnuPrgShowInline.Checked = true;
|
||||
break;
|
||||
|
||||
case PrgAddressPosition.Replace:
|
||||
Viewer.CodeViewer.ShowCompactPrgAddresses = false;
|
||||
Viewer.CodeViewer.ShowLineNumberNotes = true;
|
||||
Viewer.CodeViewer.ShowSingleLineLineNumberNotes = true;
|
||||
this.mnuPrgAddressReplace.Checked = true;
|
||||
break;
|
||||
|
||||
case PrgAddressPosition.Below:
|
||||
Viewer.CodeViewer.ShowCompactPrgAddresses = false;
|
||||
Viewer.CodeViewer.ShowLineNumberNotes = true;
|
||||
Viewer.CodeViewer.ShowSingleLineLineNumberNotes = false;
|
||||
this.mnuPrgAddressBelow.Checked = true;
|
||||
break;
|
||||
|
||||
case PrgAddressPosition.Hidden:
|
||||
Viewer.CodeViewer.ShowCompactPrgAddresses = false;
|
||||
Viewer.CodeViewer.ShowLineNumberNotes = false;
|
||||
Viewer.CodeViewer.ShowSingleLineLineNumberNotes = false;
|
||||
this.mnuHidePrgAddresses.Checked = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateConfig()
|
||||
{
|
||||
this.InitMenu(_config);
|
||||
ConfigManager.ApplyChanges();
|
||||
}
|
||||
|
||||
private void contextMenuCode_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
UpdateContextMenuItemVisibility(true);
|
||||
|
||||
int startAddress, endAddress;
|
||||
string range;
|
||||
GetSelectedAddressRange(out startAddress, out endAddress, out range);
|
||||
mnuMarkSelectionAs.Enabled = startAddress >= 0 && endAddress >= 0 && startAddress <= endAddress;
|
||||
if(mnuMarkSelectionAs.Enabled) {
|
||||
mnuMarkSelectionAs.Text = "Mark selection as... (" + range + ")";
|
||||
} else {
|
||||
mnuMarkSelectionAs.Text = "Mark selection as...";
|
||||
}
|
||||
}
|
||||
|
||||
private void GetSelectedAddressRange(out int start, out int end, out string range)
|
||||
{
|
||||
int firstLineOfSelection = Viewer.CodeViewer.SelectionStart;
|
||||
while(Viewer.CodeViewer.GetLineNumber(firstLineOfSelection) < 0) {
|
||||
firstLineOfSelection++;
|
||||
}
|
||||
int firstLineAfterSelection = Viewer.CodeViewer.SelectionStart + Viewer.CodeViewer.SelectionLength + 1;
|
||||
while(Viewer.CodeViewer.GetLineNumber(firstLineAfterSelection) < 0) {
|
||||
firstLineAfterSelection++;
|
||||
}
|
||||
start = Viewer.CodeViewer.GetLineNumber(firstLineOfSelection);
|
||||
end = Viewer.CodeViewer.GetLineNumber(firstLineAfterSelection) - 1;
|
||||
|
||||
range = "";
|
||||
if(start >= 0 && end >= 0) {
|
||||
range = $"${start.ToString("X4")} - ${end.ToString("X4")}";
|
||||
start = InteropEmu.DebugGetAbsoluteAddress((UInt32)start);
|
||||
end = InteropEmu.DebugGetAbsoluteAddress((UInt32)end);
|
||||
}
|
||||
}
|
||||
|
||||
private void MarkSelectionAs(CdlPrgFlags type)
|
||||
{
|
||||
int startAddress, endAddress;
|
||||
string range;
|
||||
GetSelectedAddressRange(out startAddress, out endAddress, out range);
|
||||
|
||||
if(startAddress >= 0 && endAddress >= 0 && startAddress <= endAddress) {
|
||||
InteropEmu.DebugMarkPrgBytesAs((UInt32)startAddress, (UInt32)endAddress, type);
|
||||
|
||||
frmDebugger debugger = DebugWindowManager.GetDebugger();
|
||||
if(debugger != null) {
|
||||
debugger.UpdateDebugger(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuMarkAsCode_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.MarkSelectionAs(CdlPrgFlags.Code);
|
||||
}
|
||||
|
||||
private void mnuMarkAsData_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.MarkSelectionAs(CdlPrgFlags.Data);
|
||||
}
|
||||
|
||||
private void mnuMarkAsUnidentifiedData_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.MarkSelectionAs(CdlPrgFlags.None);
|
||||
}
|
||||
|
||||
private void mnuGoToLocation_Click(object sender, EventArgs e)
|
||||
{
|
||||
GoToLocation();
|
||||
}
|
||||
|
||||
private void GoToLocation()
|
||||
{
|
||||
Viewer.ScrollToLineNumber((int)_lastClickedAddress);
|
||||
}
|
||||
|
||||
private void mnuAddToWatch_Click(object sender, EventArgs e)
|
||||
{
|
||||
AddWatch();
|
||||
}
|
||||
|
||||
private void AddWatch()
|
||||
{
|
||||
WatchManager.AddWatch(_newWatchValue);
|
||||
}
|
||||
|
||||
private void mnuShowInSplitView_Click(object sender, EventArgs e)
|
||||
{
|
||||
ShowInSplitView();
|
||||
}
|
||||
|
||||
private void ShowInSplitView()
|
||||
{
|
||||
this.OnShowInSplitView?.Invoke(Viewer, new AddressEventArgs() { Address = (UInt32)_lastClickedAddress });
|
||||
}
|
||||
|
||||
private void mnuEditLabel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(UpdateContextMenu(_lastLocation)) {
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)_lastClickedAddress, ref info);
|
||||
if(info.Address >= 0) {
|
||||
ctrlLabelList.EditLabel((UInt32)info.Address, info.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuNavigateForward_Click(object sender, EventArgs e)
|
||||
{
|
||||
Viewer.CodeViewer.NavigateForward();
|
||||
}
|
||||
|
||||
private void mnuNavigateBackward_Click(object sender, EventArgs e)
|
||||
{
|
||||
Viewer.CodeViewer.NavigateBackward();
|
||||
}
|
||||
|
||||
private void mnuToggleBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.ToggleBreakpoint(false);
|
||||
}
|
||||
|
||||
public void ToggleBreakpoint(bool toggleEnabledFlag)
|
||||
{
|
||||
int relativeAddress = Viewer.CodeViewer.CurrentLine;
|
||||
AddressTypeInfo info = Viewer.GetAddressInfo(Viewer.CodeViewer.SelectedLine);
|
||||
|
||||
BreakpointManager.ToggleBreakpoint(relativeAddress, info, toggleEnabledFlag);
|
||||
}
|
||||
|
||||
private void mnuShowByteCodeOnLeft_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.ByteCodePosition = ByteCodePosition.Left;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuShowByteCodeBelow_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.ByteCodePosition = ByteCodePosition.Below;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuHideByteCode_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.ByteCodePosition = ByteCodePosition.Hidden;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuShowSourceAsComments_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.ShowSourceAsComments = mnuShowSourceAsComments.Checked;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuShowInlineCompactDisplay_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.PrgAddressPosition = PrgAddressPosition.Inline;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuReplaceCpuAddress_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.PrgAddressPosition = PrgAddressPosition.Replace;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuBelowCpuAddress_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.PrgAddressPosition = PrgAddressPosition.Below;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuHidePrgAddresses_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.PrgAddressPosition = PrgAddressPosition.Hidden;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuCopySelection_Click(object sender, EventArgs e)
|
||||
{
|
||||
Viewer.CodeViewer.CopySelection(ConfigManager.Config.DebugInfo.CopyAddresses, ConfigManager.Config.DebugInfo.CopyByteCode);
|
||||
}
|
||||
|
||||
private void mnuShowNextStatement_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.ScrollToActiveAddress();
|
||||
}
|
||||
|
||||
public void ScrollToActiveAddress()
|
||||
{
|
||||
if(Viewer.ActiveAddress.HasValue) {
|
||||
Viewer.ScrollToLineNumber((int)Viewer.ActiveAddress.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuShowLineNotes_Click(object sender, EventArgs e)
|
||||
{
|
||||
Viewer.CodeViewer.ShowLineNumberNotes = this.mnuShowLineNotes.Checked;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuFindOccurrences_Click(object sender, EventArgs e)
|
||||
{
|
||||
Viewer.FindAllOccurrences(_lastWord, true, true);
|
||||
}
|
||||
|
||||
private void mnuUndoPrgChrEdit_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(InteropEmu.DebugHasUndoHistory()) {
|
||||
InteropEmu.DebugPerformUndo();
|
||||
frmDebugger debugger = DebugWindowManager.GetDebugger();
|
||||
if(debugger != null) {
|
||||
debugger.UpdateDebugger(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuSetNextStatement_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.OnSetNextStatement?.Invoke(new AddressEventArgs() { Address = (UInt32)Viewer.CodeViewer.CurrentLine });
|
||||
}
|
||||
|
||||
private void mnuEditSubroutine_Click(object sender, EventArgs e)
|
||||
{
|
||||
Viewer.EditSubroutine();
|
||||
}
|
||||
|
||||
private void mnuEditSelectedCode_Click(object sender, EventArgs e)
|
||||
{
|
||||
Viewer.EditSelectedCode();
|
||||
}
|
||||
|
||||
private void mnuEditInMemoryViewer_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(UpdateContextMenu(_lastLocation)) {
|
||||
DebugWindowManager.OpenMemoryViewer(_lastClickedAddress, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuSwitchView_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(Viewer.SymbolProvider != null) {
|
||||
this.OnSwitchView?.Invoke(Viewer);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessMouseUp(Point location, MouseButtons button)
|
||||
{
|
||||
if(UpdateContextMenu(location)) {
|
||||
if(button == MouseButtons.Left) {
|
||||
if(ModifierKeys.HasFlag(Keys.Control) && ModifierKeys.HasFlag(Keys.Alt)) {
|
||||
ShowInSplitView();
|
||||
} else if(ModifierKeys.HasFlag(Keys.Control)) {
|
||||
AddWatch();
|
||||
} else if(ModifierKeys.HasFlag(Keys.Alt)) {
|
||||
Viewer.FindAllOccurrences(_lastWord, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessMouseDoubleClick(Point location)
|
||||
{
|
||||
if(UpdateContextMenu(location) && mnuGoToLocation.Enabled) {
|
||||
GoToLocation();
|
||||
}
|
||||
}
|
||||
|
||||
private void contextMenuCode_Closed(object sender, ToolStripDropDownClosedEventArgs e)
|
||||
{
|
||||
mnuEditSelectedCode.Enabled = true;
|
||||
mnuEditSubroutine.Enabled = true;
|
||||
}
|
||||
|
||||
public void UpdateContextMenuItemVisibility(bool? visible = null)
|
||||
{
|
||||
mnuUndoPrgChrEdit.Enabled = InteropEmu.DebugHasUndoHistory();
|
||||
mnuShowNextStatement.Enabled = Viewer.ActiveAddress.HasValue;
|
||||
mnuSetNextStatement.Enabled = Viewer.ActiveAddress.HasValue;
|
||||
mnuEditSelectedCode.Enabled = mnuEditSubroutine.Enabled = InteropEmu.DebugIsExecutionStopped() && Viewer.CodeViewer.CurrentLine >= 0;
|
||||
|
||||
if(visible.HasValue) {
|
||||
mnuAddToWatch.Visible = visible.Value;
|
||||
mnuEditLabel.Visible = visible.Value;
|
||||
mnuGoToLocation.Visible = visible.Value;
|
||||
mnuToggleBreakpoint.Visible = visible.Value;
|
||||
sepAddToWatch.Visible = visible.Value;
|
||||
sepEditLabel.Visible = visible.Value;
|
||||
mnuFindOccurrences.Visible = visible.Value;
|
||||
}
|
||||
|
||||
if(SourceView) {
|
||||
mnuMarkSelectionAs.Visible = false;
|
||||
mnuShowCodeNotes.Visible = false;
|
||||
|
||||
mnuFindOccurrences.Visible = false;
|
||||
mnuEditSubroutine.Visible = false;
|
||||
mnuEditSelectedCode.Visible = false;
|
||||
mnuNavigateForward.Visible = false;
|
||||
mnuNavigateBackward.Visible = false;
|
||||
mnuEditLabel.Visible = false;
|
||||
sepNavigation.Visible = false;
|
||||
mnuShowSourceAsComments.Visible = false;
|
||||
}
|
||||
|
||||
if(Viewer.SymbolProvider == null) {
|
||||
mnuShowSourceAsComments.Visible = false;
|
||||
mnuSwitchView.Visible = false;
|
||||
sepSwitchView.Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool UpdateContextMenu(Point mouseLocation)
|
||||
{
|
||||
_lastLocation = mouseLocation;
|
||||
|
||||
UpdateContextMenuItemVisibility(true);
|
||||
|
||||
mnuSwitchView.Text = SourceView ? "Switch to Disassembly View" : "Switch to Source View";
|
||||
|
||||
string word = Viewer.CodeViewer.GetWordUnderLocation(mouseLocation);
|
||||
Ld65DbgImporter.SymbolInfo symbol = null;
|
||||
CodeLabel codeLabel = null;
|
||||
|
||||
if(!word.StartsWith("$")) {
|
||||
codeLabel = LabelManager.GetLabel(word);
|
||||
|
||||
if(Viewer.SymbolProvider != null) {
|
||||
int rangeStart, rangeEnd;
|
||||
if(Viewer.CodeViewer.GetNoteRangeAtLocation(mouseLocation.Y, out rangeStart, out rangeEnd)) {
|
||||
symbol = Viewer.SymbolProvider.GetSymbol(word, rangeStart, rangeEnd);
|
||||
if(symbol?.SegmentID == null) {
|
||||
symbol = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(word.StartsWith("$") || codeLabel != null || symbol != null) {
|
||||
//Cursor is on a numeric value or label
|
||||
_lastWord = word;
|
||||
|
||||
if(word.StartsWith("$")) {
|
||||
//CPU Address
|
||||
_lastClickedAddress = Int32.Parse(word.Substring(1), NumberStyles.AllowHexSpecifier);
|
||||
_newWatchValue = "[$" + _lastClickedAddress.ToString("X") + "]";
|
||||
} else if(symbol != null) {
|
||||
//Symbol
|
||||
AddressTypeInfo addressInfo = (AddressTypeInfo)Viewer.SymbolProvider.GetSymbolAddressInfo(symbol);
|
||||
_lastClickedAddress = (Int32)InteropEmu.DebugGetRelativeAddress((uint)addressInfo.Address, addressInfo.Type);
|
||||
bool matchingLabelExists = codeLabel != null && codeLabel.Label == symbol.Name;
|
||||
_newWatchValue = matchingLabelExists ? $"[{word}]" : $"[${_lastClickedAddress.ToString("X2")}]";
|
||||
} else if(codeLabel != null) {
|
||||
//Label
|
||||
_lastClickedAddress = (Int32)InteropEmu.DebugGetRelativeAddress(codeLabel.Address, codeLabel.AddressType);
|
||||
_newWatchValue = "[" + word + "]";
|
||||
}
|
||||
|
||||
mnuGoToLocation.Enabled = true;
|
||||
mnuGoToLocation.Text = $"Go to Location ({word})";
|
||||
|
||||
mnuShowInSplitView.Enabled = true;
|
||||
mnuShowInSplitView.Text = $"Show in Split View ({word})";
|
||||
|
||||
mnuAddToWatch.Enabled = true;
|
||||
mnuAddToWatch.Text = $"Add to Watch ({word})";
|
||||
|
||||
mnuFindOccurrences.Enabled = true;
|
||||
mnuFindOccurrences.Text = $"Find Occurrences ({word})";
|
||||
|
||||
mnuEditLabel.Enabled = true;
|
||||
mnuEditLabel.Text = $"Edit Label ({word})";
|
||||
|
||||
mnuEditInMemoryViewer.Enabled = true;
|
||||
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer ({word})";
|
||||
|
||||
return true;
|
||||
} else {
|
||||
mnuGoToLocation.Enabled = false;
|
||||
mnuGoToLocation.Text = "Go to Location";
|
||||
mnuShowInSplitView.Enabled = false;
|
||||
mnuShowInSplitView.Text = "Show in Split View";
|
||||
mnuAddToWatch.Enabled = false;
|
||||
mnuAddToWatch.Text = "Add to Watch";
|
||||
mnuFindOccurrences.Enabled = false;
|
||||
mnuFindOccurrences.Text = "Find Occurrences";
|
||||
mnuEditLabel.Enabled = false;
|
||||
mnuEditLabel.Text = "Edit Label";
|
||||
mnuEditInMemoryViewer.Enabled = false;
|
||||
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer";
|
||||
|
||||
if(mouseLocation.X < Viewer.CodeViewer.CodeMargin) {
|
||||
_lastClickedAddress = Viewer.CodeViewer.GetLineNumberAtPosition(mouseLocation.Y);
|
||||
} else {
|
||||
_lastClickedAddress = Viewer.CodeViewer.LastSelectedLine;
|
||||
}
|
||||
|
||||
if(_lastClickedAddress >= 0) {
|
||||
//Cursor is in the margin, over an address label
|
||||
string address = $"${_lastClickedAddress.ToString("X4")}";
|
||||
_newWatchValue = $"[{address}]";
|
||||
_lastWord = address;
|
||||
|
||||
mnuShowInSplitView.Enabled = true;
|
||||
mnuShowInSplitView.Text = $"Show in Split View ({address})";
|
||||
mnuAddToWatch.Enabled = true;
|
||||
mnuAddToWatch.Text = $"Add to Watch ({address})";
|
||||
mnuFindOccurrences.Enabled = true;
|
||||
mnuFindOccurrences.Text = $"Find Occurrences ({address})";
|
||||
mnuEditLabel.Enabled = true;
|
||||
mnuEditLabel.Text = $"Edit Label ({address})";
|
||||
mnuEditInMemoryViewer.Enabled = true;
|
||||
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer ({address})";
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
123
GUI.NET/Debugger/Controls/CodeViewerActions.resx
Normal file
123
GUI.NET/Debugger/Controls/CodeViewerActions.resx
Normal file
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="contextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
38
GUI.NET/Debugger/Controls/ICodeViewer.cs
Normal file
38
GUI.NET/Debugger/Controls/ICodeViewer.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using Mesen.GUI.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
public delegate void SetNextStatementEventHandler(AddressEventArgs args);
|
||||
public delegate void ShowInSplitViewEventHandler(ICodeViewer sender, AddressEventArgs args);
|
||||
public delegate void SwitchToSourceEventHandler(ICodeViewer sender);
|
||||
|
||||
public interface ICodeViewer
|
||||
{
|
||||
void ScrollToLineNumber(int lineNumber, bool scrollToTop = false);
|
||||
void ScrollToAddress(AddressTypeInfo addressInfo, bool scrollToTop = false);
|
||||
void SetConfig(DebugViewInfo config);
|
||||
void EditSubroutine();
|
||||
void EditSelectedCode();
|
||||
|
||||
CodeViewerActions CodeViewerActions { get; }
|
||||
ctrlScrollableTextbox CodeViewer { get; }
|
||||
Ld65DbgImporter SymbolProvider { get; set; }
|
||||
|
||||
UInt32? ActiveAddress { get; }
|
||||
|
||||
void FindAllOccurrences(string text, bool matchWholeWord, bool matchCase);
|
||||
void SelectActiveAddress(UInt32 activeAddress);
|
||||
void ClearActiveAddress();
|
||||
AddressTypeInfo GetAddressInfo(int lineIndex);
|
||||
}
|
||||
|
||||
public class AddressEventArgs : EventArgs
|
||||
{
|
||||
public UInt32 Address { get; set; }
|
||||
}
|
||||
}
|
@ -176,7 +176,7 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
this._tmrScroll.Stop();
|
||||
}
|
||||
|
||||
frmCodeTooltip _codeTooltip = null;
|
||||
frmCodePreviewTooltip _codeTooltip = null;
|
||||
int _lastPreviewScrollPosition = -1;
|
||||
protected override void OnMouseMove(MouseEventArgs e)
|
||||
{
|
||||
@ -269,6 +269,6 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
Color GetMarkerColor(float position, int linesPerPixel);
|
||||
int GetActiveLine();
|
||||
int GetSelectedLine();
|
||||
frmCodeTooltip GetPreview(int lineIndex);
|
||||
frmCodePreviewTooltip GetPreview(int lineIndex);
|
||||
}
|
||||
}
|
||||
|
500
GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs
generated
500
GUI.NET/Debugger/Controls/ctrlDebuggerCode.Designer.cs
generated
@ -28,44 +28,6 @@
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.contextMenuCode = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.mnuMarkSelectionAs = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMarkAsCode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMarkAsData = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMarkAsUnidentifiedData = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuEditSelectedCode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuEditSubroutine = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuUndoPrgChrEdit = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuCopySelection = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuShowNextStatement = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuSetNextStatement = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuShowCodeNotes = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuShowByteCodeOnLeft = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuShowByteCodeBelow = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuHideByteCode = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuShowLineNotes = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPrgShowInline = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPrgAddressReplace = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPrgAddressBelow = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuHidePrgAddresses = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.sepEditLabel = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuEditLabel = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuEditInMemoryViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuToggleBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.sepAddToWatch = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuAddToWatch = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuFindOccurrences = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuGoToLocation = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuShowInSplitView = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuNavigateBackward = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuNavigateForward = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.ctrlCodeViewer = new Mesen.GUI.Debugger.ctrlScrollableTextbox();
|
||||
this.contextMenuMargin = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
@ -73,333 +35,18 @@
|
||||
this.mnuDisableBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuRemoveBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.splitContainer = new System.Windows.Forms.SplitContainer();
|
||||
this.tlpSearchResults = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lstSearchResult = new System.Windows.Forms.ListView();
|
||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.picCloseOccurrenceList = new System.Windows.Forms.PictureBox();
|
||||
this.lblSearchResult = new System.Windows.Forms.Label();
|
||||
this.contextMenuCode.SuspendLayout();
|
||||
this.ctrlFindOccurrences = new Mesen.GUI.Debugger.Controls.ctrlFindOccurrences();
|
||||
this.contextMenuMargin.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
||||
this.splitContainer.Panel1.SuspendLayout();
|
||||
this.splitContainer.Panel2.SuspendLayout();
|
||||
this.splitContainer.SuspendLayout();
|
||||
this.tlpSearchResults.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picCloseOccurrenceList)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// contextMenuCode
|
||||
//
|
||||
this.contextMenuCode.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuMarkSelectionAs,
|
||||
this.toolStripMenuItem4,
|
||||
this.mnuEditSelectedCode,
|
||||
this.mnuEditSubroutine,
|
||||
this.mnuUndoPrgChrEdit,
|
||||
this.mnuCopySelection,
|
||||
this.toolStripMenuItem7,
|
||||
this.mnuShowNextStatement,
|
||||
this.mnuSetNextStatement,
|
||||
this.toolStripMenuItem1,
|
||||
this.mnuShowCodeNotes,
|
||||
this.mnuShowLineNotes,
|
||||
this.sepEditLabel,
|
||||
this.mnuEditLabel,
|
||||
this.mnuEditInMemoryViewer,
|
||||
this.mnuToggleBreakpoint,
|
||||
this.sepAddToWatch,
|
||||
this.mnuAddToWatch,
|
||||
this.mnuFindOccurrences,
|
||||
this.toolStripMenuItem2,
|
||||
this.mnuGoToLocation,
|
||||
this.mnuShowInSplitView,
|
||||
this.toolStripMenuItem3,
|
||||
this.mnuNavigateBackward,
|
||||
this.mnuNavigateForward});
|
||||
this.contextMenuCode.Name = "contextMenuWatch";
|
||||
this.contextMenuCode.Size = new System.Drawing.Size(259, 464);
|
||||
this.contextMenuCode.Closed += new System.Windows.Forms.ToolStripDropDownClosedEventHandler(this.contextMenuCode_Closed);
|
||||
this.contextMenuCode.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuCode_Opening);
|
||||
//
|
||||
// mnuMarkSelectionAs
|
||||
//
|
||||
this.mnuMarkSelectionAs.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuMarkAsCode,
|
||||
this.mnuMarkAsData,
|
||||
this.mnuMarkAsUnidentifiedData});
|
||||
this.mnuMarkSelectionAs.Name = "mnuMarkSelectionAs";
|
||||
this.mnuMarkSelectionAs.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuMarkSelectionAs.Text = "Mark selection as...";
|
||||
//
|
||||
// mnuMarkAsCode
|
||||
//
|
||||
this.mnuMarkAsCode.Image = global::Mesen.GUI.Properties.Resources.Accept;
|
||||
this.mnuMarkAsCode.Name = "mnuMarkAsCode";
|
||||
this.mnuMarkAsCode.Size = new System.Drawing.Size(199, 22);
|
||||
this.mnuMarkAsCode.Text = "Verified Code";
|
||||
this.mnuMarkAsCode.Click += new System.EventHandler(this.mnuMarkAsCode_Click);
|
||||
//
|
||||
// mnuMarkAsData
|
||||
//
|
||||
this.mnuMarkAsData.Image = global::Mesen.GUI.Properties.Resources.CheatCode;
|
||||
this.mnuMarkAsData.Name = "mnuMarkAsData";
|
||||
this.mnuMarkAsData.Size = new System.Drawing.Size(199, 22);
|
||||
this.mnuMarkAsData.Text = "Verified Data";
|
||||
this.mnuMarkAsData.Click += new System.EventHandler(this.mnuMarkAsData_Click);
|
||||
//
|
||||
// mnuMarkAsUnidentifiedData
|
||||
//
|
||||
this.mnuMarkAsUnidentifiedData.Image = global::Mesen.GUI.Properties.Resources.Help;
|
||||
this.mnuMarkAsUnidentifiedData.Name = "mnuMarkAsUnidentifiedData";
|
||||
this.mnuMarkAsUnidentifiedData.Size = new System.Drawing.Size(199, 22);
|
||||
this.mnuMarkAsUnidentifiedData.Text = "Unidentified Code/Data";
|
||||
this.mnuMarkAsUnidentifiedData.Click += new System.EventHandler(this.mnuMarkAsUnidentifiedData_Click);
|
||||
//
|
||||
// toolStripMenuItem4
|
||||
//
|
||||
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
|
||||
this.toolStripMenuItem4.Size = new System.Drawing.Size(255, 6);
|
||||
//
|
||||
// mnuEditSelectedCode
|
||||
//
|
||||
this.mnuEditSelectedCode.Image = global::Mesen.GUI.Properties.Resources.Edit;
|
||||
this.mnuEditSelectedCode.Name = "mnuEditSelectedCode";
|
||||
this.mnuEditSelectedCode.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuEditSelectedCode.Text = "Edit Selected Code";
|
||||
this.mnuEditSelectedCode.Click += new System.EventHandler(this.mnuEditSelectedCode_Click);
|
||||
//
|
||||
// mnuEditSubroutine
|
||||
//
|
||||
this.mnuEditSubroutine.Image = global::Mesen.GUI.Properties.Resources.Edit;
|
||||
this.mnuEditSubroutine.Name = "mnuEditSubroutine";
|
||||
this.mnuEditSubroutine.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuEditSubroutine.Text = "Edit Subroutine";
|
||||
this.mnuEditSubroutine.Click += new System.EventHandler(this.mnuEditSubroutine_Click);
|
||||
//
|
||||
// mnuUndoPrgChrEdit
|
||||
//
|
||||
this.mnuUndoPrgChrEdit.Image = global::Mesen.GUI.Properties.Resources.Undo;
|
||||
this.mnuUndoPrgChrEdit.Name = "mnuUndoPrgChrEdit";
|
||||
this.mnuUndoPrgChrEdit.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuUndoPrgChrEdit.Text = "Undo PRG/CHR Edit";
|
||||
this.mnuUndoPrgChrEdit.Click += new System.EventHandler(this.mnuUndoPrgChrEdit_Click);
|
||||
//
|
||||
// mnuCopySelection
|
||||
//
|
||||
this.mnuCopySelection.Image = global::Mesen.GUI.Properties.Resources.Copy;
|
||||
this.mnuCopySelection.Name = "mnuCopySelection";
|
||||
this.mnuCopySelection.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuCopySelection.Text = "Copy Selection";
|
||||
this.mnuCopySelection.Click += new System.EventHandler(this.mnuCopySelection_Click);
|
||||
//
|
||||
// toolStripMenuItem7
|
||||
//
|
||||
this.toolStripMenuItem7.Name = "toolStripMenuItem7";
|
||||
this.toolStripMenuItem7.Size = new System.Drawing.Size(255, 6);
|
||||
//
|
||||
// mnuShowNextStatement
|
||||
//
|
||||
this.mnuShowNextStatement.Name = "mnuShowNextStatement";
|
||||
this.mnuShowNextStatement.ShortcutKeyDisplayString = "Alt+*";
|
||||
this.mnuShowNextStatement.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuShowNextStatement.Text = "Show Next Statement";
|
||||
this.mnuShowNextStatement.Click += new System.EventHandler(this.mnuShowNextStatement_Click);
|
||||
//
|
||||
// mnuSetNextStatement
|
||||
//
|
||||
this.mnuSetNextStatement.Name = "mnuSetNextStatement";
|
||||
this.mnuSetNextStatement.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuSetNextStatement.Text = "Set Next Statement";
|
||||
this.mnuSetNextStatement.Click += new System.EventHandler(this.mnuSetNextStatement_Click);
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(255, 6);
|
||||
//
|
||||
// mnuShowCodeNotes
|
||||
//
|
||||
this.mnuShowCodeNotes.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuShowByteCodeOnLeft,
|
||||
this.mnuShowByteCodeBelow,
|
||||
this.toolStripMenuItem5,
|
||||
this.mnuHideByteCode});
|
||||
this.mnuShowCodeNotes.Name = "mnuShowCodeNotes";
|
||||
this.mnuShowCodeNotes.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuShowCodeNotes.Text = "Byte Code Display";
|
||||
//
|
||||
// mnuShowByteCodeOnLeft
|
||||
//
|
||||
this.mnuShowByteCodeOnLeft.Name = "mnuShowByteCodeOnLeft";
|
||||
this.mnuShowByteCodeOnLeft.Size = new System.Drawing.Size(130, 22);
|
||||
this.mnuShowByteCodeOnLeft.Text = "On the left";
|
||||
this.mnuShowByteCodeOnLeft.Click += new System.EventHandler(this.mnuShowByteCodeOnLeft_Click);
|
||||
//
|
||||
// mnuShowByteCodeBelow
|
||||
//
|
||||
this.mnuShowByteCodeBelow.Name = "mnuShowByteCodeBelow";
|
||||
this.mnuShowByteCodeBelow.Size = new System.Drawing.Size(130, 22);
|
||||
this.mnuShowByteCodeBelow.Text = "Below";
|
||||
this.mnuShowByteCodeBelow.Click += new System.EventHandler(this.mnuShowByteCodeBelow_Click);
|
||||
//
|
||||
// toolStripMenuItem5
|
||||
//
|
||||
this.toolStripMenuItem5.Name = "toolStripMenuItem5";
|
||||
this.toolStripMenuItem5.Size = new System.Drawing.Size(127, 6);
|
||||
//
|
||||
// mnuHideByteCode
|
||||
//
|
||||
this.mnuHideByteCode.Name = "mnuHideByteCode";
|
||||
this.mnuHideByteCode.Size = new System.Drawing.Size(130, 22);
|
||||
this.mnuHideByteCode.Text = "Hidden";
|
||||
this.mnuHideByteCode.Click += new System.EventHandler(this.mnuHideByteCode_Click);
|
||||
//
|
||||
// mnuShowLineNotes
|
||||
//
|
||||
this.mnuShowLineNotes.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuPrgShowInline,
|
||||
this.mnuPrgAddressReplace,
|
||||
this.mnuPrgAddressBelow,
|
||||
this.toolStripMenuItem6,
|
||||
this.mnuHidePrgAddresses});
|
||||
this.mnuShowLineNotes.Name = "mnuShowLineNotes";
|
||||
this.mnuShowLineNotes.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuShowLineNotes.Text = "PRG Address Display";
|
||||
this.mnuShowLineNotes.Click += new System.EventHandler(this.mnuShowLineNotes_Click);
|
||||
//
|
||||
// mnuPrgShowInline
|
||||
//
|
||||
this.mnuPrgShowInline.Name = "mnuPrgShowInline";
|
||||
this.mnuPrgShowInline.Size = new System.Drawing.Size(196, 22);
|
||||
this.mnuPrgShowInline.Text = "Inline Compact Display";
|
||||
this.mnuPrgShowInline.Click += new System.EventHandler(this.mnuShowInlineCompactDisplay_Click);
|
||||
//
|
||||
// mnuPrgAddressReplace
|
||||
//
|
||||
this.mnuPrgAddressReplace.Name = "mnuPrgAddressReplace";
|
||||
this.mnuPrgAddressReplace.Size = new System.Drawing.Size(196, 22);
|
||||
this.mnuPrgAddressReplace.Text = "Replace CPU address";
|
||||
this.mnuPrgAddressReplace.Click += new System.EventHandler(this.mnuReplaceCpuAddress_Click);
|
||||
//
|
||||
// mnuPrgAddressBelow
|
||||
//
|
||||
this.mnuPrgAddressBelow.Name = "mnuPrgAddressBelow";
|
||||
this.mnuPrgAddressBelow.Size = new System.Drawing.Size(196, 22);
|
||||
this.mnuPrgAddressBelow.Text = "Below CPU address";
|
||||
this.mnuPrgAddressBelow.Click += new System.EventHandler(this.mnuBelowCpuAddress_Click);
|
||||
//
|
||||
// toolStripMenuItem6
|
||||
//
|
||||
this.toolStripMenuItem6.Name = "toolStripMenuItem6";
|
||||
this.toolStripMenuItem6.Size = new System.Drawing.Size(193, 6);
|
||||
//
|
||||
// mnuHidePrgAddresses
|
||||
//
|
||||
this.mnuHidePrgAddresses.Name = "mnuHidePrgAddresses";
|
||||
this.mnuHidePrgAddresses.Size = new System.Drawing.Size(196, 22);
|
||||
this.mnuHidePrgAddresses.Text = "Hidden";
|
||||
this.mnuHidePrgAddresses.Click += new System.EventHandler(this.mnuHidePrgAddresses_Click);
|
||||
//
|
||||
// sepEditLabel
|
||||
//
|
||||
this.sepEditLabel.Name = "sepEditLabel";
|
||||
this.sepEditLabel.Size = new System.Drawing.Size(255, 6);
|
||||
//
|
||||
// mnuEditLabel
|
||||
//
|
||||
this.mnuEditLabel.Image = global::Mesen.GUI.Properties.Resources.EditLabel;
|
||||
this.mnuEditLabel.Name = "mnuEditLabel";
|
||||
this.mnuEditLabel.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuEditLabel.Text = "Edit Label";
|
||||
this.mnuEditLabel.Click += new System.EventHandler(this.mnuEditLabel_Click);
|
||||
//
|
||||
// mnuEditInMemoryViewer
|
||||
//
|
||||
this.mnuEditInMemoryViewer.Image = global::Mesen.GUI.Properties.Resources.CheatCode;
|
||||
this.mnuEditInMemoryViewer.Name = "mnuEditInMemoryViewer";
|
||||
this.mnuEditInMemoryViewer.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuEditInMemoryViewer.Text = "Edit in Memory Viewer";
|
||||
this.mnuEditInMemoryViewer.Click += new System.EventHandler(this.mnuEditInMemoryViewer_Click);
|
||||
//
|
||||
// mnuToggleBreakpoint
|
||||
//
|
||||
this.mnuToggleBreakpoint.Image = global::Mesen.GUI.Properties.Resources.Breakpoint;
|
||||
this.mnuToggleBreakpoint.Name = "mnuToggleBreakpoint";
|
||||
this.mnuToggleBreakpoint.ShortcutKeyDisplayString = "F9";
|
||||
this.mnuToggleBreakpoint.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuToggleBreakpoint.Text = "Toggle Breakpoint";
|
||||
this.mnuToggleBreakpoint.Click += new System.EventHandler(this.mnuToggleBreakpoint_Click);
|
||||
//
|
||||
// sepAddToWatch
|
||||
//
|
||||
this.sepAddToWatch.Name = "sepAddToWatch";
|
||||
this.sepAddToWatch.Size = new System.Drawing.Size(255, 6);
|
||||
//
|
||||
// mnuAddToWatch
|
||||
//
|
||||
this.mnuAddToWatch.Name = "mnuAddToWatch";
|
||||
this.mnuAddToWatch.ShortcutKeyDisplayString = "Ctrl+Click";
|
||||
this.mnuAddToWatch.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuAddToWatch.Text = "Add to Watch";
|
||||
this.mnuAddToWatch.Click += new System.EventHandler(this.mnuAddToWatch_Click);
|
||||
//
|
||||
// mnuFindOccurrences
|
||||
//
|
||||
this.mnuFindOccurrences.Name = "mnuFindOccurrences";
|
||||
this.mnuFindOccurrences.ShortcutKeyDisplayString = "Alt+Click";
|
||||
this.mnuFindOccurrences.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuFindOccurrences.Text = "Find Occurrences";
|
||||
this.mnuFindOccurrences.Click += new System.EventHandler(this.mnuFindOccurrences_Click);
|
||||
//
|
||||
// toolStripMenuItem2
|
||||
//
|
||||
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
|
||||
this.toolStripMenuItem2.Size = new System.Drawing.Size(255, 6);
|
||||
//
|
||||
// mnuGoToLocation
|
||||
//
|
||||
this.mnuGoToLocation.Name = "mnuGoToLocation";
|
||||
this.mnuGoToLocation.ShortcutKeyDisplayString = "Double Click";
|
||||
this.mnuGoToLocation.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuGoToLocation.Text = "Go to Location";
|
||||
this.mnuGoToLocation.Click += new System.EventHandler(this.mnuGoToLocation_Click);
|
||||
//
|
||||
// mnuShowInSplitView
|
||||
//
|
||||
this.mnuShowInSplitView.Image = global::Mesen.GUI.Properties.Resources.SplitView;
|
||||
this.mnuShowInSplitView.Name = "mnuShowInSplitView";
|
||||
this.mnuShowInSplitView.ShortcutKeyDisplayString = "Ctrl+Alt+Click";
|
||||
this.mnuShowInSplitView.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuShowInSplitView.Text = "Show in Split View";
|
||||
this.mnuShowInSplitView.Click += new System.EventHandler(this.mnuShowInSplitView_Click);
|
||||
//
|
||||
// toolStripMenuItem3
|
||||
//
|
||||
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
|
||||
this.toolStripMenuItem3.Size = new System.Drawing.Size(255, 6);
|
||||
//
|
||||
// mnuNavigateBackward
|
||||
//
|
||||
this.mnuNavigateBackward.Image = global::Mesen.GUI.Properties.Resources.NavigateBack;
|
||||
this.mnuNavigateBackward.Name = "mnuNavigateBackward";
|
||||
this.mnuNavigateBackward.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuNavigateBackward.Text = "Navigate Backward";
|
||||
this.mnuNavigateBackward.Click += new System.EventHandler(this.mnuNavigateBackward_Click);
|
||||
//
|
||||
// mnuNavigateForward
|
||||
//
|
||||
this.mnuNavigateForward.Image = global::Mesen.GUI.Properties.Resources.NavigateForward;
|
||||
this.mnuNavigateForward.Name = "mnuNavigateForward";
|
||||
this.mnuNavigateForward.Size = new System.Drawing.Size(258, 22);
|
||||
this.mnuNavigateForward.Text = "Navigate Forward";
|
||||
this.mnuNavigateForward.Click += new System.EventHandler(this.mnuNavigateForward_Click);
|
||||
//
|
||||
// ctrlCodeViewer
|
||||
//
|
||||
this.ctrlCodeViewer.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.ctrlCodeViewer.CodeHighlightingEnabled = true;
|
||||
this.ctrlCodeViewer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlCodeViewer.HideSelection = false;
|
||||
this.ctrlCodeViewer.Location = new System.Drawing.Point(0, 0);
|
||||
@ -471,94 +118,20 @@
|
||||
//
|
||||
// splitContainer.Panel2
|
||||
//
|
||||
this.splitContainer.Panel2.Controls.Add(this.tlpSearchResults);
|
||||
this.splitContainer.Panel2.Controls.Add(this.ctrlFindOccurrences);
|
||||
this.splitContainer.Size = new System.Drawing.Size(479, 318);
|
||||
this.splitContainer.SplitterDistance = 150;
|
||||
this.splitContainer.TabIndex = 12;
|
||||
//
|
||||
// tlpSearchResults
|
||||
// ctrlFindOccurrences
|
||||
//
|
||||
this.tlpSearchResults.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single;
|
||||
this.tlpSearchResults.ColumnCount = 1;
|
||||
this.tlpSearchResults.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpSearchResults.Controls.Add(this.lstSearchResult, 0, 1);
|
||||
this.tlpSearchResults.Controls.Add(this.tableLayoutPanel2, 0, 0);
|
||||
this.tlpSearchResults.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tlpSearchResults.Location = new System.Drawing.Point(0, 0);
|
||||
this.tlpSearchResults.Name = "tlpSearchResults";
|
||||
this.tlpSearchResults.RowCount = 2;
|
||||
this.tlpSearchResults.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpSearchResults.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpSearchResults.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tlpSearchResults.Size = new System.Drawing.Size(479, 164);
|
||||
this.tlpSearchResults.TabIndex = 12;
|
||||
//
|
||||
// lstSearchResult
|
||||
//
|
||||
this.lstSearchResult.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.lstSearchResult.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.columnHeader1,
|
||||
this.columnHeader2});
|
||||
this.lstSearchResult.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lstSearchResult.FullRowSelect = true;
|
||||
this.lstSearchResult.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
|
||||
this.lstSearchResult.Location = new System.Drawing.Point(1, 24);
|
||||
this.lstSearchResult.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.lstSearchResult.Name = "lstSearchResult";
|
||||
this.lstSearchResult.Size = new System.Drawing.Size(477, 139);
|
||||
this.lstSearchResult.TabIndex = 9;
|
||||
this.lstSearchResult.UseCompatibleStateImageBehavior = false;
|
||||
this.lstSearchResult.View = System.Windows.Forms.View.Details;
|
||||
this.lstSearchResult.SizeChanged += new System.EventHandler(this.lstSearchResult_SizeChanged);
|
||||
this.lstSearchResult.DoubleClick += new System.EventHandler(this.lstSearchResult_DoubleClick);
|
||||
//
|
||||
// columnHeader1
|
||||
//
|
||||
this.columnHeader1.Text = "";
|
||||
//
|
||||
// columnHeader2
|
||||
//
|
||||
this.columnHeader2.Text = "";
|
||||
this.columnHeader2.Width = 160;
|
||||
//
|
||||
// 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.picCloseOccurrenceList, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblSearchResult, 0, 0);
|
||||
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(1, 1);
|
||||
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(477, 22);
|
||||
this.tableLayoutPanel2.TabIndex = 11;
|
||||
//
|
||||
// picCloseOccurrenceList
|
||||
//
|
||||
this.picCloseOccurrenceList.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.picCloseOccurrenceList.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.picCloseOccurrenceList.Image = global::Mesen.GUI.Properties.Resources.Close;
|
||||
this.picCloseOccurrenceList.Location = new System.Drawing.Point(458, 3);
|
||||
this.picCloseOccurrenceList.Name = "picCloseOccurrenceList";
|
||||
this.picCloseOccurrenceList.Size = new System.Drawing.Size(16, 16);
|
||||
this.picCloseOccurrenceList.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
||||
this.picCloseOccurrenceList.TabIndex = 10;
|
||||
this.picCloseOccurrenceList.TabStop = false;
|
||||
this.picCloseOccurrenceList.Click += new System.EventHandler(this.picCloseOccurrenceList_Click);
|
||||
//
|
||||
// lblSearchResult
|
||||
//
|
||||
this.lblSearchResult.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblSearchResult.AutoSize = true;
|
||||
this.lblSearchResult.Location = new System.Drawing.Point(3, 4);
|
||||
this.lblSearchResult.Name = "lblSearchResult";
|
||||
this.lblSearchResult.Size = new System.Drawing.Size(95, 13);
|
||||
this.lblSearchResult.TabIndex = 11;
|
||||
this.lblSearchResult.Text = "Search results for: ";
|
||||
this.ctrlFindOccurrences.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlFindOccurrences.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlFindOccurrences.Name = "ctrlFindOccurrences";
|
||||
this.ctrlFindOccurrences.Size = new System.Drawing.Size(479, 164);
|
||||
this.ctrlFindOccurrences.TabIndex = 0;
|
||||
this.ctrlFindOccurrences.Viewer = null;
|
||||
this.ctrlFindOccurrences.OnSearchResultsClosed += new System.EventHandler(this.ctrlFindOccurrences_OnSearchResultsClosed);
|
||||
//
|
||||
// ctrlDebuggerCode
|
||||
//
|
||||
@ -567,16 +140,11 @@
|
||||
this.Controls.Add(this.splitContainer);
|
||||
this.Name = "ctrlDebuggerCode";
|
||||
this.Size = new System.Drawing.Size(479, 318);
|
||||
this.contextMenuCode.ResumeLayout(false);
|
||||
this.contextMenuMargin.ResumeLayout(false);
|
||||
this.splitContainer.Panel1.ResumeLayout(false);
|
||||
this.splitContainer.Panel2.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
|
||||
this.splitContainer.ResumeLayout(false);
|
||||
this.tlpSearchResults.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picCloseOccurrenceList)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
@ -584,56 +152,12 @@
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.ContextMenuStrip contextMenuCode;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowNextStatement;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuSetNextStatement;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
|
||||
private System.Windows.Forms.ToolStripSeparator sepEditLabel;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGoToLocation;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuAddToWatch;
|
||||
private Mesen.GUI.Debugger.ctrlScrollableTextbox ctrlCodeViewer;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowLineNotes;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowCodeNotes;
|
||||
private System.Windows.Forms.ContextMenuStrip contextMenuMargin;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuRemoveBreakpoint;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditBreakpoint;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuDisableBreakpoint;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuFindOccurrences;
|
||||
private System.Windows.Forms.SplitContainer splitContainer;
|
||||
private System.Windows.Forms.TableLayoutPanel tlpSearchResults;
|
||||
private System.Windows.Forms.ListView lstSearchResult;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader1;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader2;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.PictureBox picCloseOccurrenceList;
|
||||
private System.Windows.Forms.Label lblSearchResult;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNavigateForward;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNavigateBackward;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditLabel;
|
||||
private System.Windows.Forms.ToolStripSeparator sepAddToWatch;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuToggleBreakpoint;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowByteCodeOnLeft;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowByteCodeBelow;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuHideByteCode;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPrgAddressReplace;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPrgAddressBelow;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuHidePrgAddresses;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem6;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem7;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditSubroutine;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditSelectedCode;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuCopySelection;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditInMemoryViewer;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowInSplitView;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuMarkSelectionAs;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuMarkAsCode;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuMarkAsData;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuMarkAsUnidentifiedData;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuUndoPrgChrEdit;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPrgShowInline;
|
||||
private Controls.ctrlFindOccurrences ctrlFindOccurrences;
|
||||
}
|
||||
}
|
||||
|
@ -13,83 +13,45 @@ using Mesen.GUI.Controls;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class ctrlDebuggerCode : BaseScrollableTextboxUserControl
|
||||
public partial class ctrlDebuggerCode : BaseScrollableTextboxUserControl, ICodeViewer
|
||||
{
|
||||
public delegate void AddressEventHandler(ctrlDebuggerCode sender, AddressEventArgs args);
|
||||
public delegate void WatchEventHandler(WatchEventArgs args);
|
||||
public delegate void AssemblerEventHandler(AssemblerEventArgs args);
|
||||
public event AssemblerEventHandler OnEditCode;
|
||||
public event AddressEventHandler OnSetNextStatement;
|
||||
public event AddressEventHandler OnScrollToAddress;
|
||||
private DebugViewInfo _config;
|
||||
|
||||
List<int> _lineNumbers = new List<int>(10000);
|
||||
List<string> _lineNumberNotes = new List<string>(10000);
|
||||
List<char> _lineMemoryType = new List<char>(10000);
|
||||
List<int> _absoluteLineNumbers = new List<int>(10000);
|
||||
List<string> _codeNotes = new List<string>(10000);
|
||||
List<string> _codeLines = new List<string>(10000);
|
||||
private List<int> _lineNumbers = new List<int>(10000);
|
||||
private List<string> _lineNumberNotes = new List<string>(10000);
|
||||
private List<char> _lineMemoryType = new List<char>(10000);
|
||||
private List<int> _absoluteLineNumbers = new List<int>(10000);
|
||||
private List<string> _codeNotes = new List<string>(10000);
|
||||
private List<string> _codeLines = new List<string>(10000);
|
||||
private HashSet<int> _unexecutedAddresses = new HashSet<int>();
|
||||
private HashSet<int> _verifiedDataAddresses = new HashSet<int>();
|
||||
private HashSet<int> _speculativeCodeAddreses = new HashSet<int>();
|
||||
Dictionary<int, string> _codeContent = new Dictionary<int, string>(10000);
|
||||
Dictionary<int, string> _codeComments = new Dictionary<int, string>(10000);
|
||||
Dictionary<int, string> _codeByteCode = new Dictionary<int, string>(10000);
|
||||
List<string> _addressing = new List<string>(10000);
|
||||
List<string> _comments = new List<string>(10000);
|
||||
List<int> _lineIndentations = new List<int>(10000);
|
||||
private Dictionary<int, string> _codeContent = new Dictionary<int, string>(10000);
|
||||
private Dictionary<int, string> _codeComments = new Dictionary<int, string>(10000);
|
||||
private Dictionary<int, string> _codeByteCode = new Dictionary<int, string>(10000);
|
||||
private List<string> _addressing = new List<string>(10000);
|
||||
private List<string> _comments = new List<string>(10000);
|
||||
private List<int> _lineIndentations = new List<int>(10000);
|
||||
|
||||
private UInt32? _currentActiveAddress { get; set; } = null;
|
||||
|
||||
private Form _codeTooltip = null;
|
||||
private Point _previousLocation;
|
||||
private DebugViewInfo _config;
|
||||
private CodeTooltipManager _tooltipManager = null;
|
||||
private CodeViewerActions _codeViewerActions;
|
||||
|
||||
public ctrlDebuggerCode()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.lstSearchResult.Font = new System.Drawing.Font(BaseControl.MonospaceFontFamily, 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
splitContainer.Panel2Collapsed = true;
|
||||
_tooltipManager = new CodeTooltipManager(this, this.ctrlCodeViewer);
|
||||
|
||||
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
|
||||
if(!designMode) {
|
||||
this.InitShortcuts();
|
||||
}
|
||||
}
|
||||
_codeViewerActions = new CodeViewerActions(this, false);
|
||||
|
||||
private void InitShortcuts()
|
||||
{
|
||||
mnuEditInMemoryViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditInMemoryViewer));
|
||||
mnuEditLabel.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditLabel));
|
||||
mnuEditSelectedCode.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditSelectedCode));
|
||||
mnuEditSubroutine.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditSubroutine));
|
||||
mnuNavigateBackward.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateBack));
|
||||
mnuNavigateForward.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateForward));
|
||||
mnuSetNextStatement.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_SetNextStatement));
|
||||
mnuShowNextStatement.InitShortcut(this, nameof(DebuggerShortcutsConfig.GoToProgramCounter));
|
||||
mnuToggleBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_ToggleBreakpoint));
|
||||
|
||||
mnuUndoPrgChrEdit.InitShortcut(this, nameof(DebuggerShortcutsConfig.Undo));
|
||||
mnuCopySelection.InitShortcut(this, nameof(DebuggerShortcutsConfig.Copy));
|
||||
|
||||
mnuMarkAsCode.InitShortcut(this, nameof(DebuggerShortcutsConfig.MarkAsCode));
|
||||
mnuMarkAsData.InitShortcut(this, nameof(DebuggerShortcutsConfig.MarkAsData));
|
||||
mnuMarkAsUnidentifiedData.InitShortcut(this, nameof(DebuggerShortcutsConfig.MarkAsUnidentified));
|
||||
}
|
||||
|
||||
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public List<ToolStripItem> ContextMenuItems
|
||||
{
|
||||
get
|
||||
{
|
||||
List<ToolStripItem> items = new List<ToolStripItem>();
|
||||
foreach(ToolStripItem item in this.contextMenuCode.Items) {
|
||||
items.Add(item);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.contextMenuCode.Items.AddRange(value.ToArray());
|
||||
ctrlFindOccurrences.Viewer = this;
|
||||
splitContainer.Panel2Collapsed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,67 +59,10 @@ namespace Mesen.GUI.Debugger
|
||||
{
|
||||
_config = config;
|
||||
|
||||
mnuPrgShowInline.Checked = false;
|
||||
mnuPrgAddressReplace.Checked = false;
|
||||
mnuPrgAddressBelow.Checked = false;
|
||||
mnuHidePrgAddresses.Checked = false;
|
||||
_codeViewerActions.InitMenu(config);
|
||||
|
||||
mnuShowByteCodeOnLeft.Checked = false;
|
||||
mnuShowByteCodeBelow.Checked = false;
|
||||
mnuHideByteCode.Checked = false;
|
||||
|
||||
switch(config.ByteCodePosition) {
|
||||
case ByteCodePosition.Left:
|
||||
this.ctrlCodeViewer.ShowContentNotes = true;
|
||||
this.ctrlCodeViewer.ShowSingleContentLineNotes = true;
|
||||
this.mnuShowByteCodeOnLeft.Checked = true;
|
||||
break;
|
||||
|
||||
case ByteCodePosition.Below:
|
||||
this.ctrlCodeViewer.ShowContentNotes = true;
|
||||
this.ctrlCodeViewer.ShowSingleContentLineNotes = false;
|
||||
this.mnuShowByteCodeBelow.Checked = true;
|
||||
break;
|
||||
|
||||
case ByteCodePosition.Hidden:
|
||||
this.ctrlCodeViewer.ShowContentNotes = false;
|
||||
this.ctrlCodeViewer.ShowSingleContentLineNotes = false;
|
||||
this.mnuHideByteCode.Checked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
switch(config.PrgAddressPosition) {
|
||||
case PrgAddressPosition.Inline:
|
||||
this.ctrlCodeViewer.ShowCompactPrgAddresses = true;
|
||||
this.ctrlCodeViewer.ShowLineNumberNotes = false;
|
||||
this.ctrlCodeViewer.ShowSingleLineLineNumberNotes = false;
|
||||
this.mnuPrgShowInline.Checked = true;
|
||||
break;
|
||||
|
||||
case PrgAddressPosition.Replace:
|
||||
this.ctrlCodeViewer.ShowCompactPrgAddresses = false;
|
||||
this.ctrlCodeViewer.ShowLineNumberNotes = true;
|
||||
this.ctrlCodeViewer.ShowSingleLineLineNumberNotes = true;
|
||||
this.mnuPrgAddressReplace.Checked = true;
|
||||
break;
|
||||
|
||||
case PrgAddressPosition.Below:
|
||||
this.ctrlCodeViewer.ShowCompactPrgAddresses = false;
|
||||
this.ctrlCodeViewer.ShowLineNumberNotes = true;
|
||||
this.ctrlCodeViewer.ShowSingleLineLineNumberNotes = false;
|
||||
this.mnuPrgAddressBelow.Checked = true;
|
||||
break;
|
||||
|
||||
case PrgAddressPosition.Hidden:
|
||||
this.ctrlCodeViewer.ShowCompactPrgAddresses = false;
|
||||
this.ctrlCodeViewer.ShowLineNumberNotes = false;
|
||||
this.ctrlCodeViewer.ShowSingleLineLineNumberNotes = false;
|
||||
this.mnuHidePrgAddresses.Checked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(this.TextZoom != config.TextZoom) {
|
||||
this.TextZoom = config.TextZoom;
|
||||
if(this.ctrlCodeViewer.TextZoom != config.TextZoom) {
|
||||
this.ctrlCodeViewer.TextZoom = config.TextZoom;
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,6 +77,13 @@ namespace Mesen.GUI.Debugger
|
||||
get { return this.ctrlCodeViewer; }
|
||||
}
|
||||
|
||||
private Ld65DbgImporter _symbolProvider;
|
||||
public Ld65DbgImporter SymbolProvider
|
||||
{
|
||||
get { return _symbolProvider; }
|
||||
set { _symbolProvider = value; }
|
||||
}
|
||||
|
||||
private string _code;
|
||||
private bool _codeChanged;
|
||||
public string Code
|
||||
@ -182,36 +94,28 @@ namespace Mesen.GUI.Debugger
|
||||
if(value != null) {
|
||||
_codeChanged = true;
|
||||
_code = value;
|
||||
_tooltipManager.Code = value;
|
||||
UpdateCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool ShowScrollbars
|
||||
{
|
||||
get { return this.ctrlCodeViewer.ShowScrollbars; }
|
||||
set { this.ctrlCodeViewer.ShowScrollbars = value; }
|
||||
}
|
||||
|
||||
public bool ShowMemoryValues
|
||||
{
|
||||
get { return this.ctrlCodeViewer.ShowMemoryValues; }
|
||||
set { this.ctrlCodeViewer.ShowMemoryValues = value; }
|
||||
}
|
||||
|
||||
public ctrlScrollableTextbox CodeViewer { get { return this.ctrlCodeViewer; } }
|
||||
public CodeViewerActions CodeViewerActions { get { return _codeViewerActions; } }
|
||||
public uint? ActiveAddress { get { return _currentActiveAddress; } }
|
||||
|
||||
public void SelectActiveAddress(UInt32 address)
|
||||
{
|
||||
this.SetActiveAddress(address);
|
||||
this.ctrlCodeViewer.ScrollToLineNumber((int)address, eHistoryType.OnScroll);
|
||||
}
|
||||
|
||||
public void ScrollToActiveAddress()
|
||||
{
|
||||
if(_currentActiveAddress.HasValue) {
|
||||
this.ctrlCodeViewer.ScrollToLineNumber((int)_currentActiveAddress.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetActiveAddress(UInt32 address)
|
||||
{
|
||||
_currentActiveAddress = address;
|
||||
@ -225,11 +129,19 @@ namespace Mesen.GUI.Debugger
|
||||
public void UpdateLineColors()
|
||||
{
|
||||
this.ctrlCodeViewer.StyleProvider = new LineStyleProvider(this);
|
||||
if(this.ShowScrollbars) {
|
||||
if(this.ctrlCodeViewer.ShowScrollbars) {
|
||||
this.ctrlCodeViewer.ScrollbarColorProvider = new ScrollbarColorProvider(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void ScrollToAddress(AddressTypeInfo addressInfo, bool scrollToTop = false)
|
||||
{
|
||||
int relativeAddress = InteropEmu.DebugGetRelativeAddress((uint)addressInfo.Address, addressInfo.Type);
|
||||
if(relativeAddress >= 0) {
|
||||
this.ctrlCodeViewer.ScrollToLineNumber(relativeAddress, eHistoryType.Always , scrollToTop);
|
||||
}
|
||||
}
|
||||
|
||||
public List<string> GetCode(out int byteLength, ref int startAddress, int endAddress = -1)
|
||||
{
|
||||
List<string> result = new List<string>();
|
||||
@ -426,264 +338,41 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
#region Events
|
||||
private Point _previousLocation;
|
||||
private bool _preventCloseTooltip = false;
|
||||
private string _hoverLastWord = "";
|
||||
private int _hoverLastLineAddress = -1;
|
||||
|
||||
private void ShowTooltip(string word, Dictionary<string, string> values, int address, int lineAddress)
|
||||
{
|
||||
if(_hoverLastWord != word || _hoverLastLineAddress != lineAddress || _codeTooltip == null) {
|
||||
if(!_preventCloseTooltip && _codeTooltip != null) {
|
||||
_codeTooltip.Close();
|
||||
_codeTooltip = null;
|
||||
}
|
||||
|
||||
if(ConfigManager.Config.DebugInfo.ShowOpCodeTooltips && frmOpCodeTooltip.IsOpCode(word)) {
|
||||
_codeTooltip = new frmOpCodeTooltip(word, lineAddress);
|
||||
} else {
|
||||
bool isPrgRom = false;
|
||||
if(address >= 0 && ConfigManager.Config.DebugInfo.ShowCodePreview) {
|
||||
AddressTypeInfo addressInfo = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)address, ref addressInfo);
|
||||
isPrgRom = addressInfo.Type == AddressType.PrgRom;
|
||||
}
|
||||
|
||||
_codeTooltip = new frmCodeTooltip(values, isPrgRom ? address : -1, isPrgRom ? _code : null);
|
||||
}
|
||||
_codeTooltip.Left = Cursor.Position.X + 10;
|
||||
_codeTooltip.Top = Cursor.Position.Y + 10;
|
||||
_codeTooltip.Show(this);
|
||||
}
|
||||
_codeTooltip.Left = Cursor.Position.X + 10;
|
||||
_codeTooltip.Top = Cursor.Position.Y + 10;
|
||||
|
||||
_preventCloseTooltip = true;
|
||||
_hoverLastWord = word;
|
||||
_hoverLastLineAddress = lineAddress;
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
if(_codeTooltip != null) {
|
||||
_codeTooltip.Close();
|
||||
_codeTooltip = null;
|
||||
}
|
||||
_tooltipManager.Close(true);
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
//Always enable to allow F2 shortcut
|
||||
mnuEditLabel.Enabled = true;
|
||||
|
||||
if(e.Location.X < this.ctrlCodeViewer.CodeMargin / 4) {
|
||||
this.ctrlCodeViewer.ContextMenuStrip = contextMenuMargin;
|
||||
} else {
|
||||
this.ctrlCodeViewer.ContextMenuStrip = contextMenuCode;
|
||||
this.ctrlCodeViewer.ContextMenuStrip = _codeViewerActions.contextMenu;
|
||||
}
|
||||
|
||||
if(_previousLocation != e.Location) {
|
||||
if(!_preventCloseTooltip && _codeTooltip != null) {
|
||||
_codeTooltip.Close();
|
||||
_codeTooltip = null;
|
||||
}
|
||||
_preventCloseTooltip = false;
|
||||
|
||||
string word = GetWordUnderLocation(e.Location);
|
||||
if(word.StartsWith("$")) {
|
||||
try {
|
||||
UInt32 address = UInt32.Parse(word.Substring(1), System.Globalization.NumberStyles.AllowHexSpecifier);
|
||||
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType(address, ref info);
|
||||
|
||||
if(info.Address >= 0) {
|
||||
CodeLabel label = LabelManager.GetLabel((UInt32)info.Address, info.Type);
|
||||
if(label == null) {
|
||||
DisplayAddressTooltip(word, address);
|
||||
} else {
|
||||
DisplayLabelTooltip(word, label);
|
||||
}
|
||||
} else {
|
||||
DisplayAddressTooltip(word, address);
|
||||
}
|
||||
} catch { }
|
||||
} else {
|
||||
CodeLabel label = LabelManager.GetLabel(word);
|
||||
|
||||
if(label != null) {
|
||||
DisplayLabelTooltip(word, label);
|
||||
} else if(ConfigManager.Config.DebugInfo.ShowOpCodeTooltips && frmOpCodeTooltip.IsOpCode(word)) {
|
||||
ShowTooltip(word, null, -1, ctrlCodeViewer.GetLineNumberAtPosition(e.Y));
|
||||
}
|
||||
}
|
||||
_previousLocation = e.Location;
|
||||
}
|
||||
}
|
||||
|
||||
private void DisplayAddressTooltip(string word, UInt32 address)
|
||||
{
|
||||
byte byteValue = InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, address);
|
||||
UInt16 wordValue = (UInt16)(byteValue | (InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, address+1) << 8));
|
||||
|
||||
var values = new Dictionary<string, string>() {
|
||||
{ "Address", "$" + address.ToString("X4") },
|
||||
{ "Value", $"${byteValue.ToString("X2")} (byte){Environment.NewLine}${wordValue.ToString("X4")} (word)" }
|
||||
};
|
||||
|
||||
ShowTooltip(word, values, (int)address, -1);
|
||||
}
|
||||
|
||||
private void DisplayLabelTooltip(string word, CodeLabel label)
|
||||
{
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress(label.Address, label.AddressType);
|
||||
byte byteValue = relativeAddress >= 0 ? InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, (UInt32)relativeAddress) : (byte)0;
|
||||
UInt16 wordValue = relativeAddress >= 0 ? (UInt16)(byteValue | (InteropEmu.DebugGetMemoryValue(DebugMemoryType.CpuMemory, (UInt32)relativeAddress+1) << 8)) : (UInt16)0;
|
||||
int address = InteropEmu.DebugGetRelativeAddress(label.Address, label.AddressType);
|
||||
var values = new Dictionary<string, string>() {
|
||||
{ "Label", label.Label },
|
||||
{ "Address", "$" + address.ToString("X4") },
|
||||
{ "Value", (relativeAddress >= 0 ? $"${byteValue.ToString("X2")} (byte){Environment.NewLine}${wordValue.ToString("X4")} (word)" : "n/a") },
|
||||
};
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(label.Comment)) {
|
||||
values["Comment"] = label.Comment;
|
||||
}
|
||||
|
||||
ShowTooltip(word, values, address, -1);
|
||||
}
|
||||
|
||||
private bool UpdateContextMenu(Point mouseLocation)
|
||||
{
|
||||
UpdateContextMenuItemVisibility(true);
|
||||
|
||||
string word = GetWordUnderLocation(mouseLocation);
|
||||
if(word.StartsWith("$") || LabelManager.GetLabel(word) != null) {
|
||||
//Cursor is on a numeric value or label
|
||||
_lastWord = word;
|
||||
|
||||
if(word.StartsWith("$")) {
|
||||
_lastClickedAddress = Int32.Parse(word.Substring(1), System.Globalization.NumberStyles.AllowHexSpecifier);
|
||||
_newWatchValue = "[$" + _lastClickedAddress.ToString("X") + "]";
|
||||
} else {
|
||||
_lastClickedAddress = (Int32)InteropEmu.DebugGetRelativeAddress(LabelManager.GetLabel(word).Address, LabelManager.GetLabel(word).AddressType);
|
||||
_newWatchValue = "[" + word + "]";
|
||||
}
|
||||
|
||||
mnuGoToLocation.Enabled = true;
|
||||
mnuGoToLocation.Text = $"Go to Location ({word})";
|
||||
|
||||
mnuShowInSplitView.Enabled = true;
|
||||
mnuShowInSplitView.Text = $"Show in Split View ({word})";
|
||||
|
||||
mnuAddToWatch.Enabled = true;
|
||||
mnuAddToWatch.Text = $"Add to Watch ({word})";
|
||||
|
||||
mnuFindOccurrences.Enabled = true;
|
||||
mnuFindOccurrences.Text = $"Find Occurrences ({word})";
|
||||
|
||||
mnuEditLabel.Enabled = true;
|
||||
mnuEditLabel.Text = $"Edit Label ({word})";
|
||||
|
||||
mnuEditInMemoryViewer.Enabled = true;
|
||||
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer ({word})";
|
||||
|
||||
return true;
|
||||
} else {
|
||||
mnuGoToLocation.Enabled = false;
|
||||
mnuGoToLocation.Text = "Go to Location";
|
||||
mnuShowInSplitView.Enabled = false;
|
||||
mnuShowInSplitView.Text = "Show in Split View";
|
||||
mnuAddToWatch.Enabled = false;
|
||||
mnuAddToWatch.Text = "Add to Watch";
|
||||
mnuFindOccurrences.Enabled = false;
|
||||
mnuFindOccurrences.Text = "Find Occurrences";
|
||||
mnuEditLabel.Enabled = false;
|
||||
mnuEditLabel.Text = "Edit Label";
|
||||
mnuEditInMemoryViewer.Enabled = false;
|
||||
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer";
|
||||
|
||||
|
||||
if(mouseLocation.X < this.ctrlCodeViewer.CodeMargin) {
|
||||
_lastClickedAddress = ctrlCodeViewer.GetLineNumberAtPosition(mouseLocation.Y);
|
||||
} else {
|
||||
_lastClickedAddress = ctrlCodeViewer.LastSelectedLine;
|
||||
}
|
||||
|
||||
if(_lastClickedAddress >= 0) {
|
||||
//Cursor is in the margin, over an address label
|
||||
string address = $"${_lastClickedAddress.ToString("X4")}";
|
||||
_newWatchValue = $"[{address}]";
|
||||
_lastWord = address;
|
||||
|
||||
mnuShowInSplitView.Enabled = true;
|
||||
mnuShowInSplitView.Text = $"Show in Split View ({address})";
|
||||
mnuAddToWatch.Enabled = true;
|
||||
mnuAddToWatch.Text = $"Add to Watch ({address})";
|
||||
mnuFindOccurrences.Enabled = true;
|
||||
mnuFindOccurrences.Text = $"Find Occurrences ({address})";
|
||||
mnuEditLabel.Enabled = true;
|
||||
mnuEditLabel.Text = $"Edit Label ({address})";
|
||||
mnuEditInMemoryViewer.Enabled = true;
|
||||
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer ({address})";
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
_previousLocation = e.Location;
|
||||
_tooltipManager.ProcessMouseMove(e.Location);
|
||||
}
|
||||
|
||||
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
|
||||
{
|
||||
this.UpdateContextMenuItemVisibility(mnuAddToWatch.Visible);
|
||||
_codeViewerActions.UpdateContextMenuItemVisibility();
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
public void UpdateContextMenuItemVisibility(bool visible)
|
||||
{
|
||||
mnuUndoPrgChrEdit.Enabled = InteropEmu.DebugHasUndoHistory();
|
||||
mnuShowNextStatement.Enabled = _currentActiveAddress.HasValue;
|
||||
mnuSetNextStatement.Enabled = _currentActiveAddress.HasValue;
|
||||
mnuEditSelectedCode.Enabled = mnuEditSubroutine.Enabled = InteropEmu.DebugIsExecutionStopped() && ctrlCodeViewer.CurrentLine >= 0;
|
||||
|
||||
mnuAddToWatch.Visible = visible;
|
||||
mnuFindOccurrences.Visible = visible;
|
||||
mnuEditLabel.Visible = visible;
|
||||
mnuGoToLocation.Visible = visible;
|
||||
mnuToggleBreakpoint.Visible = visible;
|
||||
sepAddToWatch.Visible = visible;
|
||||
sepEditLabel.Visible = visible;
|
||||
}
|
||||
|
||||
int _lastClickedAddress = Int32.MaxValue;
|
||||
string _newWatchValue = string.Empty;
|
||||
string _lastWord = string.Empty;
|
||||
|
||||
private void ctrlCodeViewer_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
if(UpdateContextMenu(e.Location)) {
|
||||
if(e.Button == MouseButtons.Left) {
|
||||
if(ModifierKeys.HasFlag(Keys.Control) && ModifierKeys.HasFlag(Keys.Alt)) {
|
||||
ShowInSplitView();
|
||||
} else if(ModifierKeys.HasFlag(Keys.Control)) {
|
||||
AddWatch();
|
||||
} else if(ModifierKeys.HasFlag(Keys.Alt)) {
|
||||
FindAllOccurrences(_lastWord, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
_codeViewerActions.ProcessMouseUp(e.Location, e.Button);
|
||||
}
|
||||
|
||||
Breakpoint _lineBreakpoint = null;
|
||||
private void ctrlCodeViewer_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if(_codeTooltip != null) {
|
||||
_codeTooltip.Close();
|
||||
_codeTooltip = null;
|
||||
}
|
||||
_tooltipManager.Close(true);
|
||||
|
||||
int relativeAddress = ctrlCodeViewer.GetLineNumberAtPosition(e.Y);
|
||||
AddressTypeInfo info = GetLineAddressTypeInfo(ctrlCodeViewer.GetLineIndexAtPosition(e.Y));
|
||||
AddressTypeInfo info = GetAddressInfo(ctrlCodeViewer.GetLineIndexAtPosition(e.Y));
|
||||
_lineBreakpoint = BreakpointManager.GetMatchingBreakpoint(relativeAddress, info);
|
||||
|
||||
if(e.Button == MouseButtons.Left && e.Location.X < this.ctrlCodeViewer.CodeMargin / 4) {
|
||||
@ -691,7 +380,7 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
private AddressTypeInfo GetLineAddressTypeInfo(int lineNumber)
|
||||
public AddressTypeInfo GetAddressInfo(int lineNumber)
|
||||
{
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
info.Address = this._absoluteLineNumbers[lineNumber];
|
||||
@ -706,26 +395,21 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
private void ctrlCodeViewer_ScrollPositionChanged(object sender, EventArgs e)
|
||||
{
|
||||
if(_codeTooltip != null) {
|
||||
_codeTooltip.Close();
|
||||
_codeTooltip = null;
|
||||
}
|
||||
_tooltipManager.Close(true);
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
if(e.Location.X > this.ctrlCodeViewer.CodeMargin / 2 && e.Location.X < this.ctrlCodeViewer.CodeMargin) {
|
||||
AddressTypeInfo info = GetLineAddressTypeInfo(ctrlCodeViewer.GetLineIndexAtPosition(e.Y));
|
||||
AddressTypeInfo info = GetAddressInfo(ctrlCodeViewer.GetLineIndexAtPosition(e.Y));
|
||||
if(info.Address >= 0) {
|
||||
ctrlLabelList.EditLabel((UInt32)info.Address, info.Type);
|
||||
}
|
||||
} else if(UpdateContextMenu(e.Location) && mnuGoToLocation.Enabled) {
|
||||
GoToLocation();
|
||||
} else{
|
||||
_codeViewerActions.ProcessMouseDoubleClick(e.Location);
|
||||
}
|
||||
}
|
||||
|
||||
#region Context Menu
|
||||
|
||||
private void contextMenuMargin_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
if(_lineBreakpoint == null) {
|
||||
@ -750,202 +434,13 @@ namespace Mesen.GUI.Debugger
|
||||
_lineBreakpoint.SetEnabled(!_lineBreakpoint.Enabled);
|
||||
}
|
||||
|
||||
private void contextMenuCode_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
UpdateContextMenuItemVisibility(true);
|
||||
|
||||
int startAddress, endAddress;
|
||||
string range;
|
||||
GetSelectedAddressRange(out startAddress, out endAddress, out range);
|
||||
mnuMarkSelectionAs.Enabled = startAddress >= 0 && endAddress >= 0 && startAddress <= endAddress;
|
||||
if(mnuMarkSelectionAs.Enabled) {
|
||||
mnuMarkSelectionAs.Text = "Mark selection as... (" + range + ")";
|
||||
} else {
|
||||
mnuMarkSelectionAs.Text = "Mark selection as...";
|
||||
}
|
||||
}
|
||||
|
||||
private void contextMenuCode_Closed(object sender, ToolStripDropDownClosedEventArgs e)
|
||||
{
|
||||
mnuEditSelectedCode.Enabled = true;
|
||||
mnuEditSubroutine.Enabled = true;
|
||||
}
|
||||
|
||||
private void mnuShowNextStatement_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.ScrollToActiveAddress();
|
||||
}
|
||||
|
||||
private void mnuShowLineNotes_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.ctrlCodeViewer.ShowLineNumberNotes = this.mnuShowLineNotes.Checked;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuGoToLocation_Click(object sender, EventArgs e)
|
||||
{
|
||||
GoToLocation();
|
||||
}
|
||||
|
||||
private void mnuFindOccurrences_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.FindAllOccurrences(_lastWord, true, true);
|
||||
}
|
||||
|
||||
public void FindAllOccurrences(string text, bool matchWholeWord, bool matchCase)
|
||||
{
|
||||
this.lstSearchResult.Items.Clear();
|
||||
foreach(Tuple<int, int, string> searchResult in this.ctrlCodeViewer.FindAllOccurrences(text, matchWholeWord, matchCase)) {
|
||||
var item = this.lstSearchResult.Items.Add(searchResult.Item1.ToString("X4"));
|
||||
item.Tag = searchResult.Item2;
|
||||
item.SubItems.Add(searchResult.Item3);
|
||||
item.SubItems.Add("");
|
||||
}
|
||||
this.lblSearchResult.Text = $"Search results for: {text} ({this.lstSearchResult.Items.Count} results)";
|
||||
this.lstSearchResult.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
|
||||
this.lstSearchResult.Columns[0].Width += 20;
|
||||
this.lstSearchResult.Columns[1].Width = Math.Max(this.lstSearchResult.Columns[1].Width, this.lstSearchResult.Width - this.lstSearchResult.Columns[0].Width - 24);
|
||||
this.splitContainer.Panel2Collapsed = false;
|
||||
}
|
||||
|
||||
private void lstSearchResult_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.lstSearchResult.SizeChanged -= lstSearchResult_SizeChanged;
|
||||
this.lstSearchResult.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
|
||||
this.lstSearchResult.Columns[1].Width = Math.Max(this.lstSearchResult.Columns[1].Width, this.lstSearchResult.Width - this.lstSearchResult.Columns[0].Width - 24);
|
||||
this.lstSearchResult.SizeChanged += lstSearchResult_SizeChanged;
|
||||
}
|
||||
|
||||
private void picCloseOccurrenceList_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.splitContainer.Panel2Collapsed = true;
|
||||
}
|
||||
|
||||
private void lstSearchResult_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if(lstSearchResult.SelectedItems.Count > 0) {
|
||||
int lineIndex = (int)lstSearchResult.SelectedItems[0].Tag;
|
||||
this.ctrlCodeViewer.ScrollToLineIndex(lineIndex);
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuAddToWatch_Click(object sender, EventArgs e)
|
||||
{
|
||||
AddWatch();
|
||||
}
|
||||
|
||||
private void GoToLocation()
|
||||
{
|
||||
this.ctrlCodeViewer.ScrollToLineNumber((int)_lastClickedAddress);
|
||||
}
|
||||
|
||||
private void mnuShowInSplitView_Click(object sender, EventArgs e)
|
||||
{
|
||||
ShowInSplitView();
|
||||
}
|
||||
|
||||
private void ShowInSplitView()
|
||||
{
|
||||
this.OnScrollToAddress?.Invoke(this, new AddressEventArgs() { Address = (UInt32)_lastClickedAddress });
|
||||
}
|
||||
|
||||
private void AddWatch()
|
||||
{
|
||||
WatchManager.AddWatch(_newWatchValue);
|
||||
}
|
||||
|
||||
private void mnuSetNextStatement_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.OnSetNextStatement?.Invoke(this, new AddressEventArgs() { Address = (UInt32)this.ctrlCodeViewer.CurrentLine });
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_TextZoomChanged(object sender, EventArgs e)
|
||||
{
|
||||
_config.TextZoom = this.TextZoom;
|
||||
_config.TextZoom = this.ctrlCodeViewer.TextZoom;
|
||||
UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuEditLabel_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(UpdateContextMenu(_previousLocation)) {
|
||||
AddressTypeInfo info = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)_lastClickedAddress, ref info);
|
||||
if(info.Address >= 0) {
|
||||
ctrlLabelList.EditLabel((UInt32)info.Address, info.Type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuNavigateForward_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.ctrlCodeViewer.NavigateForward();
|
||||
}
|
||||
|
||||
private void mnuNavigateBackward_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.ctrlCodeViewer.NavigateBackward();
|
||||
}
|
||||
|
||||
private void mnuToggleBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.ToggleBreakpoint(false);
|
||||
}
|
||||
|
||||
public void ToggleBreakpoint(bool toggleEnabledFlag)
|
||||
{
|
||||
int relativeAddress = ctrlCodeViewer.CurrentLine;
|
||||
AddressTypeInfo info = GetLineAddressTypeInfo(ctrlCodeViewer.SelectedLine);
|
||||
|
||||
BreakpointManager.ToggleBreakpoint(relativeAddress, info, toggleEnabledFlag);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
private void mnuShowByteCodeOnLeft_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.ByteCodePosition = ByteCodePosition.Left;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuShowByteCodeBelow_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.ByteCodePosition = ByteCodePosition.Below;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuHideByteCode_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.ByteCodePosition = ByteCodePosition.Hidden;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuShowInlineCompactDisplay_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.PrgAddressPosition = PrgAddressPosition.Inline;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuReplaceCpuAddress_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.PrgAddressPosition = PrgAddressPosition.Replace;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuBelowCpuAddress_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.PrgAddressPosition = PrgAddressPosition.Below;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuHidePrgAddresses_Click(object sender, EventArgs e)
|
||||
{
|
||||
_config.PrgAddressPosition = PrgAddressPosition.Hidden;
|
||||
this.UpdateConfig();
|
||||
}
|
||||
|
||||
private void mnuEditSubroutine_Click(object sender, EventArgs e)
|
||||
public void EditSubroutine()
|
||||
{
|
||||
int currentLine = this.GetCurrentLine();
|
||||
if(currentLine != -1 && InteropEmu.DebugIsExecutionStopped()) {
|
||||
@ -955,7 +450,7 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuEditSelectedCode_Click(object sender, EventArgs e)
|
||||
public void EditSelectedCode()
|
||||
{
|
||||
int startAddress = this.GetCurrentLine();
|
||||
int endAddress = this.ctrlCodeViewer.LastSelectedLine;
|
||||
@ -966,82 +461,18 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuCopySelection_Click(object sender, EventArgs e)
|
||||
public void FindAllOccurrences(string text, bool matchWholeWord, bool matchCase)
|
||||
{
|
||||
this.ctrlCodeViewer.CopySelection(ConfigManager.Config.DebugInfo.CopyAddresses, ConfigManager.Config.DebugInfo.CopyByteCode);
|
||||
ctrlFindOccurrences.FindAllOccurrences(text, matchWholeWord, matchCase);
|
||||
this.splitContainer.Panel2Collapsed = false;
|
||||
}
|
||||
|
||||
private void mnuEditInMemoryViewer_Click(object sender, EventArgs e)
|
||||
private void ctrlFindOccurrences_OnSearchResultsClosed(object sender, EventArgs e)
|
||||
{
|
||||
if(UpdateContextMenu(_previousLocation)) {
|
||||
DebugWindowManager.OpenMemoryViewer(_lastClickedAddress);
|
||||
}
|
||||
this.splitContainer.Panel2Collapsed = true;
|
||||
}
|
||||
|
||||
private void GetSelectedAddressRange(out int start, out int end, out string range)
|
||||
{
|
||||
int firstLineOfSelection = this.ctrlCodeViewer.SelectionStart;
|
||||
while(this.ctrlCodeViewer.GetLineNumber(firstLineOfSelection) < 0) {
|
||||
firstLineOfSelection++;
|
||||
}
|
||||
int firstLineAfterSelection = this.ctrlCodeViewer.SelectionStart + this.ctrlCodeViewer.SelectionLength + 1;
|
||||
while(this.ctrlCodeViewer.GetLineNumber(firstLineAfterSelection) < 0) {
|
||||
firstLineAfterSelection++;
|
||||
}
|
||||
start = this.ctrlCodeViewer.GetLineNumber(firstLineOfSelection);
|
||||
end = this.ctrlCodeViewer.GetLineNumber(firstLineAfterSelection) - 1;
|
||||
|
||||
range = "";
|
||||
if(start >= 0 && end >= 0) {
|
||||
range = $"${start.ToString("X4")} - ${end.ToString("X4")}";
|
||||
start = InteropEmu.DebugGetAbsoluteAddress((UInt32)start);
|
||||
end = InteropEmu.DebugGetAbsoluteAddress((UInt32)end);
|
||||
}
|
||||
}
|
||||
|
||||
private void MarkSelectionAs(CdlPrgFlags type)
|
||||
{
|
||||
int startAddress, endAddress;
|
||||
string range;
|
||||
GetSelectedAddressRange(out startAddress, out endAddress, out range);
|
||||
|
||||
if(startAddress >= 0 && endAddress >= 0 && startAddress <= endAddress) {
|
||||
InteropEmu.DebugMarkPrgBytesAs((UInt32)startAddress, (UInt32)endAddress, type);
|
||||
|
||||
frmDebugger debugger = DebugWindowManager.GetDebugger();
|
||||
if(debugger != null) {
|
||||
debugger.UpdateDebugger(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuMarkAsCode_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.MarkSelectionAs(CdlPrgFlags.Code);
|
||||
}
|
||||
|
||||
private void mnuMarkAsData_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.MarkSelectionAs(CdlPrgFlags.Data);
|
||||
}
|
||||
|
||||
private void mnuMarkAsUnidentifiedData_Click(object sender, EventArgs e)
|
||||
{
|
||||
this.MarkSelectionAs(CdlPrgFlags.None);
|
||||
}
|
||||
|
||||
private void mnuUndoPrgChrEdit_Click(object sender, EventArgs e)
|
||||
{
|
||||
if(InteropEmu.DebugHasUndoHistory()) {
|
||||
InteropEmu.DebugPerformUndo();
|
||||
frmDebugger debugger = DebugWindowManager.GetDebugger();
|
||||
if(debugger != null) {
|
||||
debugger.UpdateDebugger(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LineStyleProvider : ctrlTextbox.ILineStyleProvider
|
||||
public class LineStyleProvider : ctrlTextbox.ILineStyleProvider
|
||||
{
|
||||
private ctrlDebuggerCode _code;
|
||||
|
||||
@ -1050,14 +481,29 @@ namespace Mesen.GUI.Debugger
|
||||
_code = code;
|
||||
}
|
||||
|
||||
public string GetLineComment(int lineNumber)
|
||||
{
|
||||
if(_code.SymbolProvider != null && _code._config.ShowSourceAsComments) {
|
||||
AddressTypeInfo addressInfo = _code.GetAddressInfo(lineNumber);
|
||||
if(addressInfo.Type == AddressType.PrgRom) {
|
||||
return _code.SymbolProvider.GetSourceCodeLine(addressInfo.Address);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public LineProperties GetLineStyle(int cpuAddress, int lineNumber)
|
||||
{
|
||||
DebugInfo info = ConfigManager.Config.DebugInfo;
|
||||
LineProperties props = new LineProperties();
|
||||
AddressTypeInfo addressInfo = _code.GetAddressInfo(lineNumber);
|
||||
GetBreakpointLineProperties(props, cpuAddress, addressInfo);
|
||||
|
||||
bool isActiveStatement = _code._currentActiveAddress.HasValue && _code.ctrlCodeViewer.GetLineIndex((int)_code._currentActiveAddress.Value) == lineNumber;
|
||||
if(isActiveStatement) {
|
||||
props.FgColor = Color.Black;
|
||||
props.TextBgColor = info.CodeActiveStatementColor;
|
||||
props.Symbol = LineSymbol.Arrow;
|
||||
props.Symbol |= LineSymbol.Arrow;
|
||||
} else if(_code._unexecutedAddresses.Contains(lineNumber)) {
|
||||
props.LineBgColor = info.CodeUnexecutedCodeColor;
|
||||
} else if(_code._speculativeCodeAddreses.Contains(lineNumber)) {
|
||||
@ -1066,8 +512,19 @@ namespace Mesen.GUI.Debugger
|
||||
props.LineBgColor = info.CodeVerifiedDataColor;
|
||||
}
|
||||
|
||||
AddressTypeInfo addressInfo = _code.GetLineAddressTypeInfo(lineNumber);
|
||||
switch(_code._lineMemoryType[lineNumber]) {
|
||||
case 'P': props.AddressColor = Color.Gray; break;
|
||||
case 'W': props.AddressColor = Color.DarkBlue; break;
|
||||
case 'S': props.AddressColor = Color.DarkRed; break;
|
||||
case 'N': props.AddressColor = Color.DarkGreen; break;
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
public static void GetBreakpointLineProperties(LineProperties props, int cpuAddress, AddressTypeInfo addressInfo)
|
||||
{
|
||||
DebugInfo info = ConfigManager.Config.DebugInfo;
|
||||
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
||||
if(breakpoint.Matches(cpuAddress, ref addressInfo)) {
|
||||
Color fgColor = Color.White;
|
||||
@ -1091,31 +548,13 @@ namespace Mesen.GUI.Debugger
|
||||
symbol |= LineSymbol.Plus;
|
||||
}
|
||||
|
||||
if(isActiveStatement) {
|
||||
fgColor = Color.Black;
|
||||
bgColor = Color.Yellow;
|
||||
symbol |= LineSymbol.Arrow;
|
||||
}
|
||||
|
||||
if(props == null) {
|
||||
props = new LineProperties();
|
||||
}
|
||||
props.FgColor = fgColor;
|
||||
props.TextBgColor = bgColor;
|
||||
props.OutlineColor = outlineColor;
|
||||
props.Symbol = symbol;
|
||||
break;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(_code._lineMemoryType[lineNumber]) {
|
||||
case 'P': props.AddressColor = Color.Gray; break;
|
||||
case 'W': props.AddressColor = Color.DarkBlue; break;
|
||||
case 'S': props.AddressColor = Color.DarkRed; break;
|
||||
case 'N': props.AddressColor = Color.DarkGreen; break;
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1133,7 +572,7 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
AddressTypeInfo[] addressInfo = new AddressTypeInfo[len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
addressInfo[i] = _code.GetLineAddressTypeInfo(i);
|
||||
addressInfo[i] = _code.GetAddressInfo(i);
|
||||
}
|
||||
|
||||
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
||||
@ -1171,17 +610,13 @@ namespace Mesen.GUI.Debugger
|
||||
return Color.Transparent;
|
||||
}
|
||||
|
||||
public frmCodeTooltip GetPreview(int lineIndex)
|
||||
public frmCodePreviewTooltip GetPreview(int lineIndex)
|
||||
{
|
||||
if(lineIndex < _code._lineNumbers.Count) {
|
||||
int cpuAddress = -1;
|
||||
do {
|
||||
cpuAddress = _code._lineNumbers[lineIndex];
|
||||
while(lineIndex > 0 && _code._lineNumbers[lineIndex] < 0) {
|
||||
lineIndex--;
|
||||
} while(cpuAddress < 0 && lineIndex >= 0);
|
||||
|
||||
frmCodeTooltip frm = new frmCodeTooltip(new Dictionary<string, string>(), cpuAddress, _code._code);
|
||||
return frm;
|
||||
}
|
||||
return new frmCodePreviewTooltip(lineIndex, _code._code);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
@ -1216,16 +651,6 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
public class WatchEventArgs : EventArgs
|
||||
{
|
||||
public string WatchValue { get; set; }
|
||||
}
|
||||
|
||||
public class AddressEventArgs : EventArgs
|
||||
{
|
||||
public UInt32 Address { get; set; }
|
||||
}
|
||||
|
||||
public class AssemblerEventArgs : EventArgs
|
||||
{
|
||||
public string Code { get; set; }
|
||||
|
@ -117,9 +117,6 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="contextMenuCode.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>129, 19</value>
|
||||
</metadata>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
|
151
GUI.NET/Debugger/Controls/ctrlFindOccurrences.Designer.cs
generated
Normal file
151
GUI.NET/Debugger/Controls/ctrlFindOccurrences.Designer.cs
generated
Normal file
@ -0,0 +1,151 @@
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
partial class ctrlFindOccurrences
|
||||
{
|
||||
/// <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.tlpSearchResults = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lstSearchResult = new System.Windows.Forms.ListView();
|
||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.picCloseOccurrenceList = new System.Windows.Forms.PictureBox();
|
||||
this.lblSearchResult = new System.Windows.Forms.Label();
|
||||
this.tlpSearchResults.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picCloseOccurrenceList)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tlpSearchResults
|
||||
//
|
||||
this.tlpSearchResults.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single;
|
||||
this.tlpSearchResults.ColumnCount = 1;
|
||||
this.tlpSearchResults.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpSearchResults.Controls.Add(this.lstSearchResult, 0, 1);
|
||||
this.tlpSearchResults.Controls.Add(this.tableLayoutPanel2, 0, 0);
|
||||
this.tlpSearchResults.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tlpSearchResults.Location = new System.Drawing.Point(0, 0);
|
||||
this.tlpSearchResults.Name = "tlpSearchResults";
|
||||
this.tlpSearchResults.RowCount = 2;
|
||||
this.tlpSearchResults.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpSearchResults.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpSearchResults.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tlpSearchResults.Size = new System.Drawing.Size(394, 136);
|
||||
this.tlpSearchResults.TabIndex = 13;
|
||||
//
|
||||
// lstSearchResult
|
||||
//
|
||||
this.lstSearchResult.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.lstSearchResult.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.columnHeader1,
|
||||
this.columnHeader2});
|
||||
this.lstSearchResult.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.lstSearchResult.FullRowSelect = true;
|
||||
this.lstSearchResult.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
|
||||
this.lstSearchResult.Location = new System.Drawing.Point(1, 24);
|
||||
this.lstSearchResult.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.lstSearchResult.Name = "lstSearchResult";
|
||||
this.lstSearchResult.Size = new System.Drawing.Size(392, 111);
|
||||
this.lstSearchResult.TabIndex = 9;
|
||||
this.lstSearchResult.UseCompatibleStateImageBehavior = false;
|
||||
this.lstSearchResult.View = System.Windows.Forms.View.Details;
|
||||
this.lstSearchResult.SizeChanged += new System.EventHandler(this.lstSearchResult_DoubleClick);
|
||||
this.lstSearchResult.DoubleClick += new System.EventHandler(this.lstSearchResult_DoubleClick);
|
||||
//
|
||||
// columnHeader1
|
||||
//
|
||||
this.columnHeader1.Text = "";
|
||||
//
|
||||
// columnHeader2
|
||||
//
|
||||
this.columnHeader2.Text = "";
|
||||
this.columnHeader2.Width = 160;
|
||||
//
|
||||
// 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.picCloseOccurrenceList, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblSearchResult, 0, 0);
|
||||
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(1, 1);
|
||||
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(392, 22);
|
||||
this.tableLayoutPanel2.TabIndex = 11;
|
||||
//
|
||||
// picCloseOccurrenceList
|
||||
//
|
||||
this.picCloseOccurrenceList.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.picCloseOccurrenceList.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.picCloseOccurrenceList.Image = global::Mesen.GUI.Properties.Resources.Close;
|
||||
this.picCloseOccurrenceList.Location = new System.Drawing.Point(373, 3);
|
||||
this.picCloseOccurrenceList.Name = "picCloseOccurrenceList";
|
||||
this.picCloseOccurrenceList.Size = new System.Drawing.Size(16, 16);
|
||||
this.picCloseOccurrenceList.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
|
||||
this.picCloseOccurrenceList.TabIndex = 10;
|
||||
this.picCloseOccurrenceList.TabStop = false;
|
||||
this.picCloseOccurrenceList.Click += new System.EventHandler(this.picCloseOccurrenceList_Click);
|
||||
//
|
||||
// lblSearchResult
|
||||
//
|
||||
this.lblSearchResult.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblSearchResult.AutoSize = true;
|
||||
this.lblSearchResult.Location = new System.Drawing.Point(3, 4);
|
||||
this.lblSearchResult.Name = "lblSearchResult";
|
||||
this.lblSearchResult.Size = new System.Drawing.Size(95, 13);
|
||||
this.lblSearchResult.TabIndex = 11;
|
||||
this.lblSearchResult.Text = "Search results for: ";
|
||||
//
|
||||
// ctrlFindOccurrences
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.tlpSearchResults);
|
||||
this.Name = "ctrlFindOccurrences";
|
||||
this.Size = new System.Drawing.Size(394, 136);
|
||||
this.tlpSearchResults.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picCloseOccurrenceList)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tlpSearchResults;
|
||||
private System.Windows.Forms.ListView lstSearchResult;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader1;
|
||||
private System.Windows.Forms.ColumnHeader columnHeader2;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.PictureBox picCloseOccurrenceList;
|
||||
private System.Windows.Forms.Label lblSearchResult;
|
||||
}
|
||||
}
|
62
GUI.NET/Debugger/Controls/ctrlFindOccurrences.cs
Normal file
62
GUI.NET/Debugger/Controls/ctrlFindOccurrences.cs
Normal file
@ -0,0 +1,62 @@
|
||||
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;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
public partial class ctrlFindOccurrences : UserControl
|
||||
{
|
||||
public event EventHandler OnSearchResultsClosed;
|
||||
|
||||
public ctrlFindOccurrences()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.lstSearchResult.Font = new System.Drawing.Font(BaseControl.MonospaceFontFamily, 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
}
|
||||
|
||||
public ICodeViewer Viewer { get; set; }
|
||||
|
||||
public void FindAllOccurrences(string text, bool matchWholeWord, bool matchCase)
|
||||
{
|
||||
this.lstSearchResult.Items.Clear();
|
||||
foreach(Tuple<int, int, string> searchResult in Viewer.CodeViewer.FindAllOccurrences(text, matchWholeWord, matchCase)) {
|
||||
var item = this.lstSearchResult.Items.Add(searchResult.Item1.ToString("X4"));
|
||||
item.Tag = searchResult.Item2;
|
||||
item.SubItems.Add(searchResult.Item3);
|
||||
item.SubItems.Add("");
|
||||
}
|
||||
this.lblSearchResult.Text = $"Search results for: {text} ({this.lstSearchResult.Items.Count} results)";
|
||||
this.lstSearchResult.AutoResizeColumns(ColumnHeaderAutoResizeStyle.ColumnContent);
|
||||
this.lstSearchResult.Columns[0].Width += 20;
|
||||
this.lstSearchResult.Columns[1].Width = Math.Max(this.lstSearchResult.Columns[1].Width, this.lstSearchResult.Width - this.lstSearchResult.Columns[0].Width - 24);
|
||||
}
|
||||
|
||||
private void lstSearchResult_SizeChanged(object sender, EventArgs e)
|
||||
{
|
||||
this.lstSearchResult.SizeChanged -= lstSearchResult_SizeChanged;
|
||||
this.lstSearchResult.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
|
||||
this.lstSearchResult.Columns[1].Width = Math.Max(this.lstSearchResult.Columns[1].Width, this.lstSearchResult.Width - this.lstSearchResult.Columns[0].Width - 24);
|
||||
this.lstSearchResult.SizeChanged += lstSearchResult_SizeChanged;
|
||||
}
|
||||
|
||||
private void picCloseOccurrenceList_Click(object sender, EventArgs e)
|
||||
{
|
||||
OnSearchResultsClosed?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void lstSearchResult_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if(lstSearchResult.SelectedItems.Count > 0) {
|
||||
int lineIndex = (int)lstSearchResult.SelectedItems[0].Tag;
|
||||
Viewer.CodeViewer.ScrollToLineIndex(lineIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
120
GUI.NET/Debugger/Controls/ctrlFindOccurrences.resx
Normal file
120
GUI.NET/Debugger/Controls/ctrlFindOccurrences.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
@ -94,6 +94,11 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
_addresses = addresses;
|
||||
}
|
||||
|
||||
public string GetLineComment(int lineIndex)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public LineProperties GetLineStyle(int cpuAddress, int lineIndex)
|
||||
{
|
||||
if(_addresses.Contains(cpuAddress)) {
|
||||
|
@ -10,6 +10,7 @@ using System.Windows.Forms;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Debugger.Controls;
|
||||
using Mesen.GUI.Config;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
@ -55,20 +56,23 @@ namespace Mesen.GUI.Debugger
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
this.panelSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.panelSearch.Location = new System.Drawing.Point(this.Width - this.panelSearch.Width - 20, -1);
|
||||
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
|
||||
if(!designMode) {
|
||||
this.panelSearch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.panelSearch.Location = new System.Drawing.Point(this.Width - this.panelSearch.Width - 20, -1);
|
||||
|
||||
this.ctrlTextbox.ShowLineNumbers = true;
|
||||
this.ctrlTextbox.ShowLineInHex = true;
|
||||
|
||||
this.hScrollBar.ValueChanged += hScrollBar_ValueChanged;
|
||||
this.vScrollBar.ValueChanged += vScrollBar_ValueChanged;
|
||||
this.ctrlTextbox.ScrollPositionChanged += ctrlTextbox_ScrollPositionChanged;
|
||||
this.ctrlTextbox.SelectedLineChanged += ctrlTextbox_SelectedLineChanged;
|
||||
this.ctrlTextbox.ShowLineNumbers = true;
|
||||
this.ctrlTextbox.ShowLineInHex = true;
|
||||
|
||||
new ToolTip().SetToolTip(picCloseSearch, "Close");
|
||||
new ToolTip().SetToolTip(picSearchNext, "Find Next (F3)");
|
||||
new ToolTip().SetToolTip(picSearchPrevious, "Find Previous (Shift-F3)");
|
||||
this.hScrollBar.ValueChanged += hScrollBar_ValueChanged;
|
||||
this.vScrollBar.ValueChanged += vScrollBar_ValueChanged;
|
||||
this.ctrlTextbox.ScrollPositionChanged += ctrlTextbox_ScrollPositionChanged;
|
||||
this.ctrlTextbox.SelectedLineChanged += ctrlTextbox_SelectedLineChanged;
|
||||
|
||||
new ToolTip().SetToolTip(picCloseSearch, "Close");
|
||||
new ToolTip().SetToolTip(picSearchNext, "Find Next (F3)");
|
||||
new ToolTip().SetToolTip(picSearchPrevious, "Find Previous (Shift-F3)");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnResize(EventArgs e)
|
||||
@ -128,9 +132,9 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
public string GetWordUnderLocation(Point position, bool useCompareText = false)
|
||||
public string GetWordUnderLocation(Point position)
|
||||
{
|
||||
return this.ctrlTextbox.GetWordUnderLocation(position, useCompareText);
|
||||
return this.ctrlTextbox.GetWordUnderLocation(position);
|
||||
}
|
||||
|
||||
private void ctrlTextbox_ScrollPositionChanged(object sender, EventArgs e)
|
||||
@ -171,6 +175,15 @@ namespace Mesen.GUI.Debugger
|
||||
return this.ctrlTextbox.GetLineIndexAtPosition(yPos);
|
||||
}
|
||||
|
||||
public string GetLineNoteAtLineIndex(int lineIndex)
|
||||
{
|
||||
if(lineIndex >= 0 && lineIndex < this.ctrlTextbox.LineNumberNotes.Length) {
|
||||
return this.ctrlTextbox.LineNumberNotes[lineIndex];
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public int GetLineNumber(int lineIndex)
|
||||
{
|
||||
return this.ctrlTextbox.GetLineNumber(lineIndex);
|
||||
@ -181,9 +194,9 @@ namespace Mesen.GUI.Debugger
|
||||
return this.GetLineNumber(this.GetLineIndexAtPosition(yPos));
|
||||
}
|
||||
|
||||
public void ScrollToLineIndex(int lineIndex)
|
||||
public void ScrollToLineIndex(int lineIndex, bool scrollToTop = false)
|
||||
{
|
||||
this.ctrlTextbox.ScrollToLineIndex(lineIndex);
|
||||
this.ctrlTextbox.ScrollToLineIndex(lineIndex, eHistoryType.Always, scrollToTop);
|
||||
}
|
||||
|
||||
public void ScrollToLineNumber(int lineNumber, eHistoryType historyType = eHistoryType.Always, bool scrollToTop = false)
|
||||
@ -411,7 +424,13 @@ namespace Mesen.GUI.Debugger
|
||||
get { return this.ctrlTextbox.HideSelection; }
|
||||
set { this.ctrlTextbox.HideSelection = value; }
|
||||
}
|
||||
|
||||
|
||||
public bool CodeHighlightingEnabled
|
||||
{
|
||||
get { return this.ctrlTextbox.CodeHighlightingEnabled; }
|
||||
set { this.ctrlTextbox.CodeHighlightingEnabled = value; }
|
||||
}
|
||||
|
||||
public int LineCount { get { return this.ctrlTextbox.LineCount; } }
|
||||
public int SelectionStart { get { return this.ctrlTextbox.SelectionStart; } }
|
||||
public int SelectionLength { get { return this.ctrlTextbox.SelectionLength; } }
|
||||
@ -529,5 +548,22 @@ namespace Mesen.GUI.Debugger
|
||||
{
|
||||
this.ctrlTextbox.NavigateBackward();
|
||||
}
|
||||
|
||||
public bool GetNoteRangeAtLocation(int yPos, out int rangeStart, out int rangeEnd)
|
||||
{
|
||||
rangeStart = -1;
|
||||
rangeEnd = -1;
|
||||
int lineIndex = GetLineIndexAtPosition(yPos);
|
||||
if(Int32.TryParse(GetLineNoteAtLineIndex(lineIndex), NumberStyles.AllowHexSpecifier, null, out rangeStart)) {
|
||||
while(lineIndex < LineCount - 2 && string.IsNullOrWhiteSpace(GetLineNoteAtLineIndex(lineIndex + 1))) {
|
||||
lineIndex++;
|
||||
}
|
||||
if(Int32.TryParse(GetLineNoteAtLineIndex(lineIndex + 1), NumberStyles.AllowHexSpecifier, null, out rangeEnd)) {
|
||||
rangeEnd--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
168
GUI.NET/Debugger/Controls/ctrlSourceViewer.Designer.cs
generated
Normal file
168
GUI.NET/Debugger/Controls/ctrlSourceViewer.Designer.cs
generated
Normal file
@ -0,0 +1,168 @@
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
partial class ctrlSourceViewer
|
||||
{
|
||||
/// <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.components = new System.ComponentModel.Container();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.lblFile = new System.Windows.Forms.Label();
|
||||
this.cboFile = new System.Windows.Forms.ComboBox();
|
||||
this.ctrlCodeViewer = new Mesen.GUI.Debugger.ctrlScrollableTextbox();
|
||||
this.contextMenuMargin = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.mnuEditBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuDisableBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuRemoveBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.contextMenuMargin.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.lblFile, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.cboFile, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.ctrlCodeViewer, 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.Size = new System.Drawing.Size(463, 275);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// lblFile
|
||||
//
|
||||
this.lblFile.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblFile.AutoSize = true;
|
||||
this.lblFile.Location = new System.Drawing.Point(3, 7);
|
||||
this.lblFile.Name = "lblFile";
|
||||
this.lblFile.Size = new System.Drawing.Size(26, 13);
|
||||
this.lblFile.TabIndex = 0;
|
||||
this.lblFile.Text = "File:";
|
||||
//
|
||||
// cboFile
|
||||
//
|
||||
this.cboFile.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.cboFile.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cboFile.FormattingEnabled = true;
|
||||
this.cboFile.Location = new System.Drawing.Point(35, 3);
|
||||
this.cboFile.Margin = new System.Windows.Forms.Padding(3, 3, 0, 3);
|
||||
this.cboFile.Name = "cboFile";
|
||||
this.cboFile.Size = new System.Drawing.Size(428, 21);
|
||||
this.cboFile.TabIndex = 1;
|
||||
this.cboFile.SelectedIndexChanged += new System.EventHandler(this.cboFile_SelectedIndexChanged);
|
||||
//
|
||||
// ctrlCodeViewer
|
||||
//
|
||||
this.ctrlCodeViewer.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.ctrlCodeViewer.CodeHighlightingEnabled = false;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.ctrlCodeViewer, 2);
|
||||
this.ctrlCodeViewer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlCodeViewer.HideSelection = false;
|
||||
this.ctrlCodeViewer.Location = new System.Drawing.Point(0, 27);
|
||||
this.ctrlCodeViewer.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.ctrlCodeViewer.Name = "ctrlCodeViewer";
|
||||
this.ctrlCodeViewer.ShowCompactPrgAddresses = false;
|
||||
this.ctrlCodeViewer.ShowContentNotes = false;
|
||||
this.ctrlCodeViewer.ShowLineNumberNotes = false;
|
||||
this.ctrlCodeViewer.ShowMemoryValues = false;
|
||||
this.ctrlCodeViewer.ShowScrollbars = true;
|
||||
this.ctrlCodeViewer.ShowSingleContentLineNotes = true;
|
||||
this.ctrlCodeViewer.ShowSingleLineLineNumberNotes = false;
|
||||
this.ctrlCodeViewer.Size = new System.Drawing.Size(463, 248);
|
||||
this.ctrlCodeViewer.TabIndex = 2;
|
||||
this.ctrlCodeViewer.ScrollPositionChanged += new System.EventHandler(this.ctrlCodeViewer_ScrollPositionChanged);
|
||||
this.ctrlCodeViewer.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ctrlCodeViewer_MouseUp);
|
||||
this.ctrlCodeViewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ctrlCodeViewer_MouseMove);
|
||||
this.ctrlCodeViewer.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ctrlCodeViewer_MouseDown);
|
||||
this.ctrlCodeViewer.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.ctrlCodeViewer_MouseDoubleClick);
|
||||
this.ctrlCodeViewer.MouseLeave += new System.EventHandler(this.ctrlCodeViewer_MouseLeave);
|
||||
this.ctrlCodeViewer.TextZoomChanged += new System.EventHandler(this.ctrlCodeViewer_TextZoomChanged);
|
||||
//
|
||||
// contextMenuMargin
|
||||
//
|
||||
this.contextMenuMargin.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuEditBreakpoint,
|
||||
this.mnuDisableBreakpoint,
|
||||
this.mnuRemoveBreakpoint});
|
||||
this.contextMenuMargin.Name = "contextMenuMargin";
|
||||
this.contextMenuMargin.Size = new System.Drawing.Size(178, 70);
|
||||
this.contextMenuMargin.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuMargin_Opening);
|
||||
//
|
||||
// mnuEditBreakpoint
|
||||
//
|
||||
this.mnuEditBreakpoint.Image = global::Mesen.GUI.Properties.Resources.Edit;
|
||||
this.mnuEditBreakpoint.Name = "mnuEditBreakpoint";
|
||||
this.mnuEditBreakpoint.Size = new System.Drawing.Size(177, 22);
|
||||
this.mnuEditBreakpoint.Text = "Edit breakpoint";
|
||||
this.mnuEditBreakpoint.Click += new System.EventHandler(this.mnuEditBreakpoint_Click);
|
||||
//
|
||||
// mnuDisableBreakpoint
|
||||
//
|
||||
this.mnuDisableBreakpoint.Image = global::Mesen.GUI.Properties.Resources.BreakpointEnableDisable;
|
||||
this.mnuDisableBreakpoint.Name = "mnuDisableBreakpoint";
|
||||
this.mnuDisableBreakpoint.Size = new System.Drawing.Size(177, 22);
|
||||
this.mnuDisableBreakpoint.Text = "Disable breakpoint";
|
||||
this.mnuDisableBreakpoint.Click += new System.EventHandler(this.mnuDisableBreakpoint_Click);
|
||||
//
|
||||
// mnuRemoveBreakpoint
|
||||
//
|
||||
this.mnuRemoveBreakpoint.Image = global::Mesen.GUI.Properties.Resources.Close;
|
||||
this.mnuRemoveBreakpoint.Name = "mnuRemoveBreakpoint";
|
||||
this.mnuRemoveBreakpoint.Size = new System.Drawing.Size(177, 22);
|
||||
this.mnuRemoveBreakpoint.Text = "Remove breakpoint";
|
||||
this.mnuRemoveBreakpoint.Click += new System.EventHandler(this.mnuRemoveBreakpoint_Click);
|
||||
//
|
||||
// ctrlSourceViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Name = "ctrlSourceViewer";
|
||||
this.Size = new System.Drawing.Size(463, 275);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
this.contextMenuMargin.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.Label lblFile;
|
||||
private System.Windows.Forms.ComboBox cboFile;
|
||||
private ctrlScrollableTextbox ctrlCodeViewer;
|
||||
private System.Windows.Forms.ContextMenuStrip contextMenuMargin;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEditBreakpoint;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuDisableBreakpoint;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuRemoveBreakpoint;
|
||||
}
|
||||
}
|
497
GUI.NET/Debugger/Controls/ctrlSourceViewer.cs
Normal file
497
GUI.NET/Debugger/Controls/ctrlSourceViewer.cs
Normal file
@ -0,0 +1,497 @@
|
||||
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 static Mesen.GUI.Debugger.Ld65DbgImporter;
|
||||
using System.IO;
|
||||
using Mesen.GUI.Config;
|
||||
|
||||
namespace Mesen.GUI.Debugger.Controls
|
||||
{
|
||||
public partial class ctrlSourceViewer : UserControl, ICodeViewer
|
||||
{
|
||||
private UInt32? _currentActiveAddress { get; set; } = null;
|
||||
private CodeTooltipManager _tooltipManager = null;
|
||||
private CodeViewerActions _codeViewerActions;
|
||||
private DebugViewInfo _config;
|
||||
private Ld65DbgImporter.FileInfo _selectedFile = null;
|
||||
|
||||
public ctrlSourceViewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
|
||||
if(!designMode) {
|
||||
_codeViewerActions = new CodeViewerActions(this, true);
|
||||
_tooltipManager = new CodeTooltipManager(this, this.ctrlCodeViewer);
|
||||
}
|
||||
}
|
||||
|
||||
public new void Focus()
|
||||
{
|
||||
base.Focus();
|
||||
this.ctrlCodeViewer.Focus();
|
||||
}
|
||||
|
||||
public void SetConfig(DebugViewInfo config)
|
||||
{
|
||||
_config = config;
|
||||
_codeViewerActions.InitMenu(config);
|
||||
if(this.ctrlCodeViewer.TextZoom != config.TextZoom) {
|
||||
this.ctrlCodeViewer.TextZoom = config.TextZoom;
|
||||
}
|
||||
}
|
||||
|
||||
private List<string> _lineNumberNotes = new List<string>();
|
||||
private void UpdateCode()
|
||||
{
|
||||
List<int> indents = new List<int>();
|
||||
List<string> addressing = new List<string>();
|
||||
List<string> comments = new List<string>();
|
||||
List<int> lineNumbers = new List<int>();
|
||||
List<string> lineNotes = new List<string>();
|
||||
_lineNumberNotes = new List<string>();
|
||||
List<string> codeLines = new List<string>();
|
||||
|
||||
bool isC = CurrentFile.Name.EndsWith(".h") || CurrentFile.Name.EndsWith(".c");
|
||||
int index = 0;
|
||||
foreach(string line in CurrentFile.Data) {
|
||||
string l = line.Replace("\t", " ");
|
||||
|
||||
addressing.Add("");
|
||||
|
||||
int prgAddress = _symbolProvider.GetPrgAddress(CurrentFile.ID, index);
|
||||
int relativeAddress = InteropEmu.DebugGetRelativeAddress((uint)prgAddress, AddressType.PrgRom);
|
||||
lineNumbers.Add(relativeAddress);
|
||||
lineNotes.Add("");
|
||||
_lineNumberNotes.Add(prgAddress >= 0 ? prgAddress.ToString("X4") : "");
|
||||
|
||||
string trimmed = l.TrimStart();
|
||||
int margin = (l.Length - trimmed.Length) * 10;
|
||||
indents.Add(margin);
|
||||
|
||||
int commentIndex;
|
||||
if(isC) {
|
||||
commentIndex = trimmed.IndexOf("//");
|
||||
} else {
|
||||
commentIndex = trimmed.IndexOfAny(new char[] { ';', '.' });
|
||||
}
|
||||
|
||||
if(commentIndex >= 0) {
|
||||
comments.Add(trimmed.Substring(commentIndex));
|
||||
codeLines.Add(trimmed.Substring(0, commentIndex));
|
||||
} else {
|
||||
comments.Add("");
|
||||
codeLines.Add(trimmed);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
ctrlCodeViewer.CodeHighlightingEnabled = !isC;
|
||||
ctrlCodeViewer.LineIndentations = indents.ToArray();
|
||||
ctrlCodeViewer.Addressing = addressing.ToArray();
|
||||
ctrlCodeViewer.Comments = comments.ToArray();
|
||||
|
||||
ctrlCodeViewer.LineNumbers = lineNumbers.ToArray();
|
||||
ctrlCodeViewer.TextLineNotes = lineNotes.ToArray();
|
||||
ctrlCodeViewer.LineNumberNotes = _lineNumberNotes.ToArray();
|
||||
ctrlCodeViewer.TextLines = codeLines.ToArray();
|
||||
|
||||
this.RefreshViewer();
|
||||
}
|
||||
|
||||
public void RefreshViewer()
|
||||
{
|
||||
if(_symbolProvider != null) {
|
||||
ctrlCodeViewer.ScrollbarColorProvider = new ScrollbarColorProvider(this);
|
||||
ctrlCodeViewer.StyleProvider = new LineStyleProvider(this);
|
||||
} else {
|
||||
ctrlCodeViewer.ScrollbarColorProvider = null;
|
||||
ctrlCodeViewer.StyleProvider = null;
|
||||
}
|
||||
}
|
||||
|
||||
Ld65DbgImporter _symbolProvider;
|
||||
public Ld65DbgImporter SymbolProvider
|
||||
{
|
||||
get { return _symbolProvider; }
|
||||
set
|
||||
{
|
||||
if(_symbolProvider != value) {
|
||||
_symbolProvider = value;
|
||||
|
||||
cboFile.BeginUpdate();
|
||||
cboFile.Items.Clear();
|
||||
cboFile.Sorted = false;
|
||||
if(_symbolProvider != null) {
|
||||
foreach(Ld65DbgImporter.FileInfo file in _symbolProvider.Files.Values) {
|
||||
if(file.Data != null && file.Data.Length > 0 && !file.Name.ToLower().EndsWith(".chr")) {
|
||||
cboFile.Items.Add(file);
|
||||
}
|
||||
}
|
||||
}
|
||||
cboFile.Sorted = true;
|
||||
cboFile.EndUpdate();
|
||||
|
||||
if(cboFile.Items.Count > 0) {
|
||||
cboFile.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
_tooltipManager.SymbolProvider = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Ld65DbgImporter.FileInfo CurrentFile
|
||||
{
|
||||
get { return (Ld65DbgImporter.FileInfo)_selectedFile; }
|
||||
set
|
||||
{
|
||||
cboFile.SelectedItem = value;
|
||||
_selectedFile = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HideFileDropdown { set { cboFile.Visible = !value; lblFile.Visible = !value; } }
|
||||
|
||||
public ctrlScrollableTextbox CodeViewer { get { return this.ctrlCodeViewer; } }
|
||||
public CodeViewerActions CodeViewerActions { get { return _codeViewerActions; } }
|
||||
public UInt32? ActiveAddress { get { return _currentActiveAddress; } }
|
||||
|
||||
private void mnuToggleBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
ToggleBreakpoint();
|
||||
}
|
||||
|
||||
public AddressTypeInfo GetAddressInfo(int lineIndex)
|
||||
{
|
||||
return new AddressTypeInfo() {
|
||||
Address = _symbolProvider.GetPrgAddress(CurrentFile.ID, lineIndex),
|
||||
Type = AddressType.PrgRom
|
||||
};
|
||||
}
|
||||
|
||||
public void SetActiveAddress(UInt32 address)
|
||||
{
|
||||
_currentActiveAddress = address;
|
||||
this.RefreshViewer();
|
||||
}
|
||||
|
||||
public void SelectActiveAddress(UInt32 address)
|
||||
{
|
||||
if(_symbolProvider == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
_currentActiveAddress = address;
|
||||
|
||||
ScrollToLineNumber((int)address);
|
||||
this.RefreshViewer();
|
||||
}
|
||||
|
||||
public void ClearActiveAddress()
|
||||
{
|
||||
_currentActiveAddress = null;
|
||||
this.RefreshViewer();
|
||||
}
|
||||
|
||||
private void cboFile_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if(cboFile.SelectedIndex >= 0) {
|
||||
_selectedFile = cboFile.SelectedItem as Ld65DbgImporter.FileInfo;
|
||||
this.ctrlCodeViewer.ScrollToLineIndex(0, true);
|
||||
this.UpdateCode();
|
||||
} else {
|
||||
_selectedFile = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void ToggleBreakpoint()
|
||||
{
|
||||
AddressTypeInfo info = GetAddressInfo(ctrlCodeViewer.SelectedLine);
|
||||
if(info.Address >= 0) {
|
||||
BreakpointManager.ToggleBreakpoint(-1, info, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
if(e.Location.X < this.ctrlCodeViewer.CodeMargin / 4) {
|
||||
this.ctrlCodeViewer.ContextMenuStrip = contextMenuMargin;
|
||||
} else {
|
||||
this.ctrlCodeViewer.ContextMenuStrip = _codeViewerActions.contextMenu;
|
||||
}
|
||||
|
||||
_tooltipManager.ProcessMouseMove(e.Location);
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_MouseDown(object sender, MouseEventArgs e)
|
||||
{
|
||||
if(e.Button == MouseButtons.Left && e.Location.X < this.ctrlCodeViewer.CodeMargin / 4) {
|
||||
ToggleBreakpoint();
|
||||
}
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_MouseUp(object sender, MouseEventArgs e)
|
||||
{
|
||||
_codeViewerActions.ProcessMouseUp(e.Location, e.Button);
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_MouseDoubleClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
_codeViewerActions.ProcessMouseDoubleClick(e.Location);
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_TextZoomChanged(object sender, EventArgs e)
|
||||
{
|
||||
_config.TextZoom = this.ctrlCodeViewer.TextZoom;
|
||||
ConfigManager.ApplyChanges();
|
||||
}
|
||||
|
||||
private Breakpoint GetCurrentLineBreakpoint()
|
||||
{
|
||||
AddressTypeInfo addressInfo = GetAddressInfo(ctrlCodeViewer.SelectedLine);
|
||||
if(addressInfo.Address >= 0) {
|
||||
int relativeAddress = InteropEmu.DebugGetRelativeAddress((uint)addressInfo.Address, addressInfo.Type);
|
||||
return BreakpointManager.GetMatchingBreakpoint(relativeAddress, addressInfo);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void mnuEditBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
Breakpoint bp = GetCurrentLineBreakpoint();
|
||||
if(bp != null) {
|
||||
BreakpointManager.EditBreakpoint(bp);
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuDisableBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
Breakpoint bp = GetCurrentLineBreakpoint();
|
||||
bp.SetEnabled(!bp.Enabled);
|
||||
}
|
||||
|
||||
private void mnuRemoveBreakpoint_Click(object sender, EventArgs e)
|
||||
{
|
||||
Breakpoint bp = GetCurrentLineBreakpoint();
|
||||
if(bp != null) {
|
||||
BreakpointManager.RemoveBreakpoint(bp);
|
||||
}
|
||||
}
|
||||
|
||||
private void contextMenuMargin_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
Breakpoint bp = GetCurrentLineBreakpoint();
|
||||
if(bp != null) {
|
||||
mnuDisableBreakpoint.Text = bp.Enabled ? "Disable breakpoint" : "Enable breakpoint";
|
||||
} else {
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
_tooltipManager.Close(true);
|
||||
}
|
||||
|
||||
private void ctrlCodeViewer_ScrollPositionChanged(object sender, EventArgs e)
|
||||
{
|
||||
_tooltipManager.Close(true);
|
||||
}
|
||||
|
||||
public void ScrollToAddress(AddressTypeInfo addressInfo, bool scrollToTop = false)
|
||||
{
|
||||
if(addressInfo.Address >= 0 && addressInfo.Type == AddressType.PrgRom) {
|
||||
LineInfo line = _symbolProvider.GetSourceCodeLineInfo(addressInfo.Address);
|
||||
if(line != null) {
|
||||
foreach(Ld65DbgImporter.FileInfo fileInfo in cboFile.Items) {
|
||||
if(fileInfo.ID == line.FileID) {
|
||||
cboFile.SelectedItem = fileInfo;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ctrlCodeViewer.ScrollToLineIndex(line.LineNumber, scrollToTop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool CurrentFileContainsAddress(int cpuAddress)
|
||||
{
|
||||
if(CurrentFile == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AddressTypeInfo addressInfo = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((uint)cpuAddress, ref addressInfo);
|
||||
if(addressInfo.Address >= 0 && addressInfo.Type == AddressType.PrgRom) {
|
||||
LineInfo line = _symbolProvider.GetSourceCodeLineInfo(addressInfo.Address);
|
||||
return CurrentFile.ID == line?.FileID;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void ScrollToLineNumber(int lineNumber, bool scrollToTop = false)
|
||||
{
|
||||
AddressTypeInfo addressInfo = new AddressTypeInfo();
|
||||
InteropEmu.DebugGetAbsoluteAddressAndType((uint)lineNumber, ref addressInfo);
|
||||
ScrollToAddress(addressInfo, scrollToTop);
|
||||
}
|
||||
|
||||
public void EditSubroutine()
|
||||
{
|
||||
//Not supported
|
||||
}
|
||||
|
||||
public void EditSelectedCode()
|
||||
{
|
||||
//Not supported
|
||||
}
|
||||
|
||||
public void FindAllOccurrences(string text, bool matchWholeWord, bool matchCase)
|
||||
{
|
||||
//Not supported (yet?)
|
||||
}
|
||||
|
||||
#region Scrollbar / Code highlighting
|
||||
|
||||
class LineStyleProvider : ctrlTextbox.ILineStyleProvider
|
||||
{
|
||||
private ctrlSourceViewer _viewer;
|
||||
|
||||
public LineStyleProvider(ctrlSourceViewer viewer)
|
||||
{
|
||||
_viewer = viewer;
|
||||
}
|
||||
|
||||
public string GetLineComment(int lineNumber)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public LineProperties GetLineStyle(int cpuAddress, int lineIndex)
|
||||
{
|
||||
DebugInfo info = ConfigManager.Config.DebugInfo;
|
||||
LineProperties props = new LineProperties();
|
||||
|
||||
int nextLineIndex = lineIndex + 1;
|
||||
int nextCpuAddress;
|
||||
do {
|
||||
nextCpuAddress = _viewer.CodeViewer.GetLineNumber(nextLineIndex);
|
||||
nextLineIndex++;
|
||||
} while(nextCpuAddress < 0);
|
||||
|
||||
bool isActiveStatement = (
|
||||
cpuAddress >= 0 &&
|
||||
_viewer._currentActiveAddress.HasValue && (
|
||||
(_viewer._currentActiveAddress >= cpuAddress && _viewer._currentActiveAddress < nextCpuAddress && nextCpuAddress > cpuAddress) ||
|
||||
(_viewer._currentActiveAddress == cpuAddress && nextCpuAddress < cpuAddress)
|
||||
)
|
||||
);
|
||||
|
||||
int prgAddress = _viewer._symbolProvider.GetPrgAddress(_viewer.CurrentFile.ID, lineIndex);
|
||||
|
||||
if(prgAddress >= 0) {
|
||||
AddressTypeInfo addressInfo = new AddressTypeInfo();
|
||||
addressInfo.Address = prgAddress;
|
||||
addressInfo.Type = AddressType.PrgRom;
|
||||
|
||||
ctrlDebuggerCode.LineStyleProvider.GetBreakpointLineProperties(props, cpuAddress, addressInfo);
|
||||
}
|
||||
|
||||
if(isActiveStatement) {
|
||||
props.FgColor = Color.Black;
|
||||
props.TextBgColor = info.CodeActiveStatementColor;
|
||||
props.Symbol |= LineSymbol.Arrow;
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
}
|
||||
|
||||
class ScrollbarColorProvider : IScrollbarColorProvider
|
||||
{
|
||||
private Color _nesRamColor = Color.FromArgb(163, 222, 171);
|
||||
private Dictionary<int, Color> _breakpointColors = new Dictionary<int, Color>();
|
||||
|
||||
private ctrlSourceViewer _viewer;
|
||||
public ScrollbarColorProvider(ctrlSourceViewer viewer)
|
||||
{
|
||||
_viewer = viewer;
|
||||
|
||||
DebugInfo info = ConfigManager.Config.DebugInfo;
|
||||
int len = viewer.ctrlCodeViewer.LineCount;
|
||||
|
||||
int[] relativeAddresses = new int[len];
|
||||
AddressTypeInfo[] addressInfo = new AddressTypeInfo[len];
|
||||
for(int i = 0; i < len; i++) {
|
||||
addressInfo[i] = _viewer.GetAddressInfo(i);
|
||||
if(addressInfo[i].Address >= 0) {
|
||||
relativeAddresses[i] = InteropEmu.DebugGetRelativeAddress((uint)addressInfo[i].Address, AddressType.PrgRom);
|
||||
} else {
|
||||
relativeAddresses[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(Breakpoint breakpoint in BreakpointManager.Breakpoints) {
|
||||
for(int i = 0; i < len; i++) {
|
||||
if(breakpoint.Matches(relativeAddresses[i], ref addressInfo[i])) {
|
||||
Color bpColor = breakpoint.BreakOnExec ? info.CodeExecBreakpointColor : (breakpoint.BreakOnWrite ? info.CodeWriteBreakpointColor : info.CodeReadBreakpointColor);
|
||||
_breakpointColors[i] = bpColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Color GetBackgroundColor(float position)
|
||||
{
|
||||
return Color.Transparent;
|
||||
}
|
||||
|
||||
public frmCodePreviewTooltip GetPreview(int lineIndex)
|
||||
{
|
||||
if(lineIndex < _viewer.CodeViewer.LineCount) {
|
||||
while(lineIndex > 0 && _viewer.CodeViewer.GetLineNumber(lineIndex) < 0) {
|
||||
lineIndex--;
|
||||
}
|
||||
return new frmCodePreviewTooltip(lineIndex, null, _viewer.SymbolProvider, _viewer.CurrentFile);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetActiveLine()
|
||||
{
|
||||
if(_viewer._currentActiveAddress.HasValue && _viewer.CurrentFileContainsAddress((int)_viewer._currentActiveAddress.Value)) {
|
||||
return _viewer.ctrlCodeViewer.GetLineIndex((int)_viewer._currentActiveAddress.Value);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int GetSelectedLine()
|
||||
{
|
||||
return _viewer.ctrlCodeViewer.SelectedLine;
|
||||
}
|
||||
|
||||
public Color GetMarkerColor(float position, int linesPerPixel)
|
||||
{
|
||||
int lineIndex = (int)((_viewer.ctrlCodeViewer.LineCount - 1) * position);
|
||||
|
||||
Color bpColor;
|
||||
for(int i = 0; i < linesPerPixel; i++) {
|
||||
if(_breakpointColors.TryGetValue(lineIndex + i, out bpColor)) {
|
||||
return bpColor;
|
||||
}
|
||||
}
|
||||
return Color.Transparent;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
123
GUI.NET/Debugger/Controls/ctrlSourceViewer.resx
Normal file
123
GUI.NET/Debugger/Controls/ctrlSourceViewer.resx
Normal file
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="contextMenuMargin.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>178, 13</value>
|
||||
</metadata>
|
||||
</root>
|
@ -44,7 +44,7 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
public partial class ctrlTextbox : Control
|
||||
{
|
||||
private Regex _codeRegex = new Regex("([a-z]{3})([*]{0,1})[ ]{0,1}([(]{0,1})(([#]{0,1}[$][0-9a-f]*)|([@_a-z]([@_a-z0-9])*)){0,1}([)]{0,1})(,X|,Y){0,1}([)]{0,1})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
private Regex _codeRegex = new Regex("^([a-z]{3})([*]{0,1})($|[ ])+([(]{0,1})(([$][0-9a-f]*)|(#[@$:_0-9a-z]*)|([@_a-z]([@_a-z0-9])*)){0,1}([)]{0,1})(,X|,Y){0,1}([)]{0,1})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
public event EventHandler ScrollPositionChanged;
|
||||
public event EventHandler SelectedLineChanged;
|
||||
private bool _disableScrollPositionChangedEvent;
|
||||
@ -291,6 +291,10 @@ namespace Mesen.GUI.Debugger
|
||||
_lineNumberNotes = value;
|
||||
this.Invalidate();
|
||||
}
|
||||
get
|
||||
{
|
||||
return _lineNumberNotes;
|
||||
}
|
||||
}
|
||||
|
||||
public string Header
|
||||
@ -311,6 +315,8 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
public bool CodeHighlightingEnabled { get; set; } = true;
|
||||
|
||||
public List<Tuple<int, int, string>> FindAllOccurrences(string text, bool matchWholeWord, bool matchCase)
|
||||
{
|
||||
List<Tuple<int, int, string>> result = new List<Tuple<int, int, string>>();
|
||||
@ -398,6 +404,7 @@ namespace Mesen.GUI.Debugger
|
||||
public interface ILineStyleProvider
|
||||
{
|
||||
LineProperties GetLineStyle(int cpuAddress, int lineIndex);
|
||||
string GetLineComment(int lineIndex);
|
||||
}
|
||||
|
||||
private ILineStyleProvider _styleProvider;
|
||||
@ -451,10 +458,17 @@ namespace Mesen.GUI.Debugger
|
||||
//Line isn't currently visible, scroll it to the middle of the viewport
|
||||
if(scrollToTop) {
|
||||
int scrollPos = lineIndex;
|
||||
while(scrollPos > 0 && _lineNumbers[scrollPos - 1] < 0) {
|
||||
while(scrollPos > 0 && _lineNumbers[scrollPos - 1] < 0 && string.IsNullOrWhiteSpace(_lineNumberNotes[scrollPos - 1])) {
|
||||
//Make sure any comment for the line is in scroll view
|
||||
bool emptyLine = string.IsNullOrWhiteSpace(_contents[scrollPos]) && string.IsNullOrWhiteSpace(this.Comments[scrollPos]);
|
||||
if(emptyLine) {
|
||||
//If there's a blank line, stop scrolling up
|
||||
scrollPos++;
|
||||
break;
|
||||
}
|
||||
|
||||
scrollPos--;
|
||||
if(_contents[scrollPos].StartsWith("--") || _contents[scrollPos].StartsWith("__")) {
|
||||
if(emptyLine || _contents[scrollPos].StartsWith("--") || _contents[scrollPos].StartsWith("__")) {
|
||||
//Reached the start of a block, stop going back up
|
||||
break;
|
||||
}
|
||||
@ -533,7 +547,7 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
|
||||
if(positionX >= 0 && lineIndex < _contents.Length) {
|
||||
string text = this.GetFullWidthString(lineIndex);
|
||||
string text = this.GetFullWidthString(lineIndex).Trim();
|
||||
//Adjust background color highlights based on number of spaces in front of content
|
||||
positionX -= (LineIndentations != null ? LineIndentations[lineIndex] : 0);
|
||||
|
||||
@ -551,21 +565,22 @@ namespace Mesen.GUI.Debugger
|
||||
return false;
|
||||
}
|
||||
|
||||
public string GetWordUnderLocation(Point position, bool useCompareText = false)
|
||||
char[] _wordDelimiters = new char[] { ' ', ',', '|', ';', '(', ')', '.', '-', ':', '+', '<', '>', '#', '*', '/', '&', '[', ']', '~', '%' };
|
||||
public string GetWordUnderLocation(Point position)
|
||||
{
|
||||
int charIndex;
|
||||
int lineIndex;
|
||||
if(this.GetCharIndex(position, out charIndex, out lineIndex)) {
|
||||
string text = (useCompareText && _compareContents != null) ? _compareContents[lineIndex] : this.GetFullWidthString(lineIndex);
|
||||
List<char> wordDelimiters = new List<char>(new char[] { ' ', ',', '|', ';', '(', ')', '.', '-', ':' });
|
||||
if(wordDelimiters.Contains(text[charIndex])) {
|
||||
string text = this.GetFullWidthString(lineIndex).Trim();
|
||||
|
||||
if(_wordDelimiters.Contains(text[charIndex])) {
|
||||
return string.Empty;
|
||||
} else {
|
||||
int endIndex = text.IndexOfAny(wordDelimiters.ToArray(), charIndex);
|
||||
int endIndex = text.IndexOfAny(_wordDelimiters, charIndex);
|
||||
if(endIndex == -1) {
|
||||
endIndex = text.Length;
|
||||
}
|
||||
int startIndex = text.LastIndexOfAny(wordDelimiters.ToArray(), charIndex);
|
||||
int startIndex = text.LastIndexOfAny(_wordDelimiters, charIndex);
|
||||
return text.Substring(startIndex + 1, endIndex - startIndex - 1);
|
||||
}
|
||||
}
|
||||
@ -805,7 +820,6 @@ namespace Mesen.GUI.Debugger
|
||||
bool _mouseDragging;
|
||||
protected override void OnMouseDown(MouseEventArgs e)
|
||||
{
|
||||
base.OnMouseDown(e);
|
||||
this.Focus();
|
||||
|
||||
if(e.Button == MouseButtons.XButton1) {
|
||||
@ -835,6 +849,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.SelectionLength = 0;
|
||||
}
|
||||
}
|
||||
base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
protected override void OnMouseUp(MouseEventArgs e)
|
||||
@ -1028,20 +1043,34 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
g.TranslateTransform(-HorizontalScrollPosition * HorizontalScrollFactor, 0);
|
||||
} else {
|
||||
if(StyleProvider != null) {
|
||||
string symbolComment = StyleProvider.GetLineComment(currentLine);
|
||||
if(symbolComment != null) {
|
||||
symbolComment = symbolComment.Replace("\t", " ");
|
||||
}
|
||||
|
||||
if(symbolComment != _lastSymbolComment) {
|
||||
commentString = symbolComment ?? commentString;
|
||||
if(symbolComment != null) {
|
||||
_lastSymbolComment = symbolComment;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Draw line content
|
||||
int characterCount = 0;
|
||||
Color defaultColor = Color.FromArgb(60, 60, 60);
|
||||
if(codeString.Length > 0) {
|
||||
Match match = _codeRegex.Match(codeString);
|
||||
if(match.Success && !codeString.EndsWith(":")) {
|
||||
Match match = CodeHighlightingEnabled ? _codeRegex.Match(codeString) : null;
|
||||
if(match != null && match.Success && !codeString.EndsWith(":")) {
|
||||
string opcode = match.Groups[1].Value;
|
||||
string invalidStar = match.Groups[2].Value;
|
||||
string paren1 = match.Groups[3].Value;
|
||||
string operand = match.Groups[4].Value;
|
||||
string paren2 = match.Groups[8].Value;
|
||||
string indirect = match.Groups[9].Value;
|
||||
string paren3 = match.Groups[10].Value;
|
||||
string rest = match.Groups[11].Value;
|
||||
string paren1 = match.Groups[4].Value;
|
||||
string operand = match.Groups[5].Value;
|
||||
string paren2 = match.Groups[10].Value;
|
||||
string indirect = match.Groups[11].Value;
|
||||
string paren3 = match.Groups[12].Value;
|
||||
string rest = match.Groups[13].Value;
|
||||
Color operandColor = operand.Length > 0 ? (operand[0] == '#' ? (Color)info.AssemblerImmediateColor : (operand[0] == '$' ? (Color)info.AssemblerAddressColor : (Color)info.AssemblerLabelDefinitionColor)) : Color.Black;
|
||||
List<Color> colors = new List<Color>() { info.AssemblerOpcodeColor, defaultColor, defaultColor, defaultColor, operandColor, defaultColor, defaultColor, defaultColor };
|
||||
int codePartCount = colors.Count;
|
||||
@ -1080,7 +1109,7 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
float xOffset = 0;
|
||||
for(int i = 0; i < parts.Count; i++) {
|
||||
using(Brush b = new SolidBrush(textColor.HasValue && i < codePartCount ? textColor.Value : colors[i])) {
|
||||
using(Brush b = new SolidBrush(textColor.HasValue && (i < codePartCount || i == parts.Count - 1) ? textColor.Value : colors[i])) {
|
||||
g.DrawString(parts[i], this.Font, b, marginLeft + xOffset, positionY, StringFormat.GenericTypographic);
|
||||
xOffset += g.MeasureString("".PadLeft(parts[i].Length, 'w'), this.Font, Point.Empty, StringFormat.GenericTypographic).Width;
|
||||
characterCount += parts[i].Length;
|
||||
@ -1095,7 +1124,6 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!string.IsNullOrWhiteSpace(commentString)) {
|
||||
using(Brush commentBrush = new SolidBrush(info.AssemblerCommentColor)) {
|
||||
int padding = Math.Max(CommentSpacingCharCount, characterCount + 1);
|
||||
@ -1114,6 +1142,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.DrawHighlightedCompareString(g, codeString, currentLine, marginLeft, positionY);
|
||||
}
|
||||
}
|
||||
string _lastSymbolComment = null;
|
||||
|
||||
private void DrawLineSymbols(Graphics g, int positionY, LineProperties lineProperties, int lineHeight)
|
||||
{
|
||||
@ -1262,6 +1291,7 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
protected override void OnPaint(PaintEventArgs pe)
|
||||
{
|
||||
_lastSymbolComment = null;
|
||||
int lineHeight = this.LineHeight;
|
||||
pe.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
||||
Rectangle rect = this.ClientRectangle;
|
||||
|
@ -11,7 +11,7 @@ using Mesen.GUI.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
class Ld65DbgImporter
|
||||
public class Ld65DbgImporter
|
||||
{
|
||||
private const int iNesHeaderSize = 16;
|
||||
|
||||
@ -20,7 +20,9 @@ namespace Mesen.GUI.Debugger
|
||||
private Dictionary<int, LineInfo> _lines = new Dictionary<int, LineInfo>();
|
||||
private Dictionary<int, SpanInfo> _spans = new Dictionary<int, SpanInfo>();
|
||||
private Dictionary<int, SymbolInfo> _symbols = new Dictionary<int, SymbolInfo>();
|
||||
private Dictionary<int, CSymbolInfo> _cSymbols = new Dictionary<int, CSymbolInfo>();
|
||||
|
||||
private HashSet<int> _usedFileIds = new HashSet<int>();
|
||||
private HashSet<string> _usedLabels = new HashSet<string>();
|
||||
private Dictionary<int, CodeLabel> _ramLabels = new Dictionary<int, CodeLabel>();
|
||||
private Dictionary<int, CodeLabel> _romLabels = new Dictionary<int, CodeLabel>();
|
||||
@ -28,18 +30,126 @@ namespace Mesen.GUI.Debugger
|
||||
private HashSet<string> _filesNotFound = new HashSet<string>();
|
||||
private int _errorCount = 0;
|
||||
|
||||
private static Regex _segmentRegex = new Regex("seg\tid=([0-9]+),.*start=0x([0-9a-fA-F]+),.*size=0x([0-9A-Fa-f]+)", RegexOptions.Compiled);
|
||||
private static Regex _segmentPrgRomRegex = new Regex("seg\tid=([0-9]+),.*start=0x([0-9a-fA-F]+),.*size=0x([0-9A-Fa-f]+),.*ooffs=([0-9]+)", RegexOptions.Compiled);
|
||||
private static Regex _lineRegex = new Regex("line\tid=([0-9]+),.*file=([0-9]+),.*line=([0-9]+),.*span=([0-9]+)", RegexOptions.Compiled);
|
||||
private static Regex _fileRegex = new Regex("file\tid=([0-9]+),.*name=\"([^\"]+)\"", RegexOptions.Compiled);
|
||||
private static Regex _spanRegex = new Regex("span\tid=([0-9]+),.*seg=([0-9]+),.*start=([0-9]+),.*size=([0-9]+)(,.*type=([0-9]+)){0,1}", RegexOptions.Compiled);
|
||||
private static Regex _symbolRegex = new Regex("sym\tid=([0-9]+).*name=\"([0-9a-zA-Z@_]+)\",.*val=0x([0-9a-fA-F]+),.*seg=([0-9a-zA-Z]+)", RegexOptions.Compiled);
|
||||
private static Regex _segmentRegex = new Regex("^seg\tid=([0-9]+),.*start=0x([0-9a-fA-F]+),.*size=0x([0-9A-Fa-f]+)", RegexOptions.Compiled);
|
||||
private static Regex _segmentPrgRomRegex = new Regex("^seg\tid=([0-9]+),.*start=0x([0-9a-fA-F]+),.*size=0x([0-9A-Fa-f]+),.*ooffs=([0-9]+)", RegexOptions.Compiled);
|
||||
private static Regex _lineRegex = new Regex("^line\tid=([0-9]+),.*file=([0-9]+),.*line=([0-9]+)(,.*type=([0-9]+)){0,1}(,.*span=([0-9]+)){0,1}", RegexOptions.Compiled);
|
||||
private static Regex _fileRegex = new Regex("^file\tid=([0-9]+),.*name=\"([^\"]+)\"", RegexOptions.Compiled);
|
||||
private static Regex _spanRegex = new Regex("^span\tid=([0-9]+),.*seg=([0-9]+),.*start=([0-9]+),.*size=([0-9]+)(,.*type=([0-9]+)){0,1}", RegexOptions.Compiled);
|
||||
private static Regex _symbolRegex = new Regex("^sym\tid=([0-9]+).*name=\"([0-9a-zA-Z@_-]+)\"(,.*def=([0-9+]+)){0,1}(,.*ref=([0-9+]+)){0,1}(,.*val=0x([0-9a-fA-F]+)){0,1}(,.*seg=([0-9]+)){0,1}(,.*exp=([0-9]+)){0,1}", RegexOptions.Compiled);
|
||||
private static Regex _cSymbolRegex = new Regex("^csym\tid=([0-9]+).*name=\"([0-9a-zA-Z@_-]+)\"(,.*sym=([0-9+]+)){0,1}", RegexOptions.Compiled);
|
||||
|
||||
private static Regex _asmFirstLineRegex = new Regex(";(.*)", RegexOptions.Compiled);
|
||||
private static Regex _asmPreviousLinesRegex = new Regex("^\\s*;(.*)", RegexOptions.Compiled);
|
||||
private static Regex _cFirstLineRegex = new Regex("(.*)", RegexOptions.Compiled);
|
||||
private static Regex _cPreviousLinesRegex = new Regex("^\\s*//(.*)", RegexOptions.Compiled);
|
||||
|
||||
private Dictionary<int, LineInfo> _linesByPrgAddress = new Dictionary<int, LineInfo>();
|
||||
private Dictionary<string, int> _prgAddressByLine = new Dictionary<string, int>();
|
||||
|
||||
public Dictionary<int, FileInfo> Files { get { return _files; } }
|
||||
|
||||
public int GetPrgAddress(int fileID, int lineIndex)
|
||||
{
|
||||
int prgAddress;
|
||||
if(_prgAddressByLine.TryGetValue(fileID.ToString() + "_" + lineIndex.ToString(), out prgAddress)) {
|
||||
return prgAddress;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public LineInfo GetSourceCodeLineInfo(int prgRomAddress)
|
||||
{
|
||||
LineInfo line;
|
||||
if(_linesByPrgAddress.TryGetValue(prgRomAddress, out line)) {
|
||||
return line;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public string GetSourceCodeLine(int prgRomAddress)
|
||||
{
|
||||
if(prgRomAddress >= 0) {
|
||||
try {
|
||||
LineInfo line;
|
||||
if(_linesByPrgAddress.TryGetValue(prgRomAddress, out line)) {
|
||||
string output = "";
|
||||
FileInfo file = _files[line.FileID];
|
||||
if(file.Data == null) {
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
output += file.Data[line.LineNumber];
|
||||
return output;
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private SymbolInfo GetMatchingSymbol(SymbolInfo symbol, int rangeStart, int rangeEnd)
|
||||
{
|
||||
foreach(int reference in symbol.References) {
|
||||
LineInfo line = _lines[reference];
|
||||
if(line.SpanID == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SpanInfo span = _spans[line.SpanID.Value];
|
||||
SegmentInfo seg = _segments[span.SegmentID];
|
||||
|
||||
if(!seg.IsRam) {
|
||||
int spanPrgOffset = seg.FileOffset - iNesHeaderSize + span.Offset;
|
||||
if(rangeStart < spanPrgOffset + span.Size && rangeEnd >= spanPrgOffset) {
|
||||
if(symbol.ExportSymbolID != null && symbol.Address == null) {
|
||||
return _symbols[symbol.ExportSymbolID.Value];
|
||||
} else {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal SymbolInfo GetSymbol(string word, int prgStartAddress, int prgEndAddress)
|
||||
{
|
||||
try {
|
||||
foreach(CSymbolInfo symbol in _cSymbols.Values) {
|
||||
if(symbol.Name == word && symbol.SymbolID.HasValue) {
|
||||
SymbolInfo matchingSymbol = GetMatchingSymbol(_symbols[symbol.SymbolID.Value], prgStartAddress, prgEndAddress);
|
||||
if(matchingSymbol != null) {
|
||||
return matchingSymbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach(SymbolInfo symbol in _symbols.Values) {
|
||||
if(symbol.Name == word) {
|
||||
SymbolInfo matchingSymbol = GetMatchingSymbol(symbol, prgStartAddress, prgEndAddress);
|
||||
if(matchingSymbol != null) {
|
||||
return matchingSymbol;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public AddressTypeInfo? GetSymbolAddressInfo(SymbolInfo symbol)
|
||||
{
|
||||
if(symbol.SegmentID == null || symbol.Address == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SegmentInfo segment = _segments[symbol.SegmentID.Value];
|
||||
if(segment.IsRam) {
|
||||
return new AddressTypeInfo() { Address = symbol.Address.Value, Type = AddressType.Register };
|
||||
} else {
|
||||
return new AddressTypeInfo() { Address = symbol.Address.Value - segment.Start + segment.FileOffset - iNesHeaderSize, Type = AddressType.PrgRom };
|
||||
}
|
||||
}
|
||||
|
||||
private bool LoadSegments(string row)
|
||||
{
|
||||
Match match = _segmentRegex.Match(row);
|
||||
@ -52,13 +162,15 @@ namespace Mesen.GUI.Debugger
|
||||
};
|
||||
|
||||
match = _segmentPrgRomRegex.Match(row);
|
||||
if(match.Success) {
|
||||
if(match.Success && !row.Contains("type=rw")) {
|
||||
segment.FileOffset = Int32.Parse(match.Groups[4].Value);
|
||||
segment.IsRam = false;
|
||||
}
|
||||
|
||||
_segments.Add(segment.ID, segment);
|
||||
return true;
|
||||
} else if(row.StartsWith("seg")) {
|
||||
System.Diagnostics.Debug.Fail("Regex doesn't match seg");
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -73,27 +185,10 @@ namespace Mesen.GUI.Debugger
|
||||
Name = Path.GetFullPath(Path.Combine(basePath, match.Groups[2].Value.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar))).Replace(basePath + Path.DirectorySeparatorChar, "")
|
||||
};
|
||||
|
||||
try {
|
||||
string sourceFile = Path.Combine(basePath, file.Name);
|
||||
while(!File.Exists(sourceFile)) {
|
||||
//Go back up folder structure to attempt to find the file
|
||||
string oldPath = basePath;
|
||||
basePath = Path.GetDirectoryName(basePath);
|
||||
if(basePath == null || basePath == oldPath) {
|
||||
break;
|
||||
}
|
||||
sourceFile = Path.Combine(basePath, file.Name);
|
||||
}
|
||||
|
||||
if(File.Exists(sourceFile)) {
|
||||
file.Data = File.ReadAllLines(sourceFile);
|
||||
}
|
||||
} catch {
|
||||
_errorCount++;
|
||||
}
|
||||
|
||||
_files.Add(file.ID, file);
|
||||
return true;
|
||||
} else if(row.StartsWith("file")) {
|
||||
System.Diagnostics.Debug.Fail("Regex doesn't match file");
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -107,11 +202,15 @@ namespace Mesen.GUI.Debugger
|
||||
ID = Int32.Parse(match.Groups[1].Value),
|
||||
FileID = Int32.Parse(match.Groups[2].Value),
|
||||
LineNumber = Int32.Parse(match.Groups[3].Value) - 1,
|
||||
SpanID = Int32.Parse(match.Groups[4].Value)
|
||||
Type = match.Groups[5].Success ? (LineType)Int32.Parse(match.Groups[5].Value) : LineType.Assembly,
|
||||
SpanID = match.Groups[7].Success ? (int?)Int32.Parse(match.Groups[7].Value) : null
|
||||
};
|
||||
|
||||
_usedFileIds.Add(line.FileID);
|
||||
_lines.Add(line.ID, line);
|
||||
return true;
|
||||
} else if(row.StartsWith("line")) {
|
||||
System.Diagnostics.Debug.Fail("Regex doesn't match line");
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -131,6 +230,26 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
_spans.Add(span.ID, span);
|
||||
return true;
|
||||
} else if(row.StartsWith("span")) {
|
||||
System.Diagnostics.Debug.Fail("Regex doesn't match span");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool LoadCSymbols(string row)
|
||||
{
|
||||
Match match = _cSymbolRegex.Match(row);
|
||||
if(match.Success) {
|
||||
CSymbolInfo span = new CSymbolInfo() {
|
||||
ID = Int32.Parse(match.Groups[1].Value),
|
||||
Name = match.Groups[2].Value,
|
||||
SymbolID = match.Groups[4].Success ? (int?)Int32.Parse(match.Groups[4].Value) : null,
|
||||
};
|
||||
_cSymbols.Add(span.ID, span);
|
||||
return true;
|
||||
} else if(row.StartsWith("csym")) {
|
||||
System.Diagnostics.Debug.Fail("Regex doesn't match csym");
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -143,12 +262,27 @@ namespace Mesen.GUI.Debugger
|
||||
SymbolInfo symbol = new SymbolInfo() {
|
||||
ID = Int32.Parse(match.Groups[1].Value),
|
||||
Name = match.Groups[2].Value,
|
||||
Address = Int32.Parse(match.Groups[3].Value, NumberStyles.HexNumber),
|
||||
SegmentID = Int32.Parse(match.Groups[4].Value)
|
||||
Address = match.Groups[8].Success ? (int?)Int32.Parse(match.Groups[8].Value, NumberStyles.HexNumber) : null,
|
||||
SegmentID = match.Groups[10].Success ? (int?)Int32.Parse(match.Groups[10].Value) : null,
|
||||
ExportSymbolID = match.Groups[12].Success ? (int?)Int32.Parse(match.Groups[12].Value) : null
|
||||
};
|
||||
|
||||
if(match.Groups[4].Success) {
|
||||
symbol.Definitions = match.Groups[4].Value.Split('+').Select(o => Int32.Parse(o)).ToList();
|
||||
} else {
|
||||
symbol.Definitions = new List<int>();
|
||||
}
|
||||
|
||||
if(match.Groups[6].Success) {
|
||||
symbol.References = match.Groups[6].Value.Split('+').Select(o => Int32.Parse(o)).ToList();
|
||||
} else {
|
||||
symbol.References = new List<int>();
|
||||
}
|
||||
|
||||
_symbols.Add(symbol.ID, symbol);
|
||||
return true;
|
||||
} else if(row.StartsWith("sym")) {
|
||||
System.Diagnostics.Debug.Fail("Regex doesn't match sym");
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -159,23 +293,27 @@ namespace Mesen.GUI.Debugger
|
||||
foreach(KeyValuePair<int, SymbolInfo> kvp in _symbols) {
|
||||
try {
|
||||
SymbolInfo symbol = kvp.Value;
|
||||
if(_segments.ContainsKey(symbol.SegmentID)) {
|
||||
SegmentInfo segment = _segments[symbol.SegmentID];
|
||||
if(symbol.SegmentID == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if(_segments.ContainsKey(symbol.SegmentID.Value)) {
|
||||
SegmentInfo segment = _segments[symbol.SegmentID.Value];
|
||||
|
||||
int count = 2;
|
||||
string orgSymbolName = symbol.Name;
|
||||
while(!_usedLabels.Add(symbol.Name)) {
|
||||
string newName = symbol.Name;
|
||||
while(!_usedLabels.Add(newName)) {
|
||||
//Ensure labels are unique
|
||||
symbol.Name = orgSymbolName + "_" + count.ToString();
|
||||
newName = orgSymbolName + "_" + count.ToString();
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
int address = GetSymbolAddressInfo(symbol).Value.Address;
|
||||
if(segment.IsRam) {
|
||||
int address = symbol.Address;
|
||||
_ramLabels[address] = new CodeLabel() { Label = symbol.Name, Address = (UInt32)address, AddressType = AddressType.InternalRam, Comment = string.Empty };
|
||||
_ramLabels[address] = new CodeLabel() { Label = newName, Address = (UInt32)address, AddressType = AddressType.InternalRam, Comment = string.Empty };
|
||||
} else {
|
||||
int address = symbol.Address - segment.Start + segment.FileOffset - iNesHeaderSize;
|
||||
_romLabels[address] = new CodeLabel() { Label = symbol.Name, Address = (UInt32)address, AddressType = AddressType.PrgRom, Comment = string.Empty };
|
||||
_romLabels[address] = new CodeLabel() { Label = newName, Address = (UInt32)address, AddressType = AddressType.PrgRom, Comment = string.Empty };
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
@ -189,7 +327,11 @@ namespace Mesen.GUI.Debugger
|
||||
foreach(KeyValuePair<int, LineInfo> kvp in _lines) {
|
||||
try {
|
||||
LineInfo line = kvp.Value;
|
||||
SpanInfo span = _spans[line.SpanID];
|
||||
if(line.SpanID == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SpanInfo span = _spans[line.SpanID.Value];
|
||||
SegmentInfo segment = _segments[span.SegmentID];
|
||||
|
||||
if(_files[line.FileID].Data == null) {
|
||||
@ -254,6 +396,33 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadFileData(string path)
|
||||
{
|
||||
foreach(FileInfo file in _files.Values) {
|
||||
if(_usedFileIds.Contains(file.ID)) {
|
||||
try {
|
||||
string basePath = path;
|
||||
string sourceFile = Path.Combine(basePath, file.Name);
|
||||
while(!File.Exists(sourceFile)) {
|
||||
//Go back up folder structure to attempt to find the file
|
||||
string oldPath = basePath;
|
||||
basePath = Path.GetDirectoryName(basePath);
|
||||
if(basePath == null || basePath == oldPath) {
|
||||
break;
|
||||
}
|
||||
sourceFile = Path.Combine(basePath, file.Name);
|
||||
}
|
||||
|
||||
if(File.Exists(sourceFile)) {
|
||||
file.Data = File.ReadAllLines(sourceFile);
|
||||
}
|
||||
} catch {
|
||||
_errorCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Import(string path, bool silent = false)
|
||||
{
|
||||
string[] fileRows = File.ReadAllLines(path);
|
||||
@ -261,7 +430,7 @@ namespace Mesen.GUI.Debugger
|
||||
string basePath = Path.GetDirectoryName(path);
|
||||
foreach(string row in fileRows) {
|
||||
try {
|
||||
if(LoadSegments(row) || LoadLines(row) || LoadSpans(row) || LoadFiles(row, basePath) || LoadSymbols(row)) {
|
||||
if(LoadLines(row) || LoadSpans(row) || LoadSymbols(row) || LoadCSymbols(row) || LoadFiles(row, basePath) || LoadSegments(row)) {
|
||||
continue;
|
||||
}
|
||||
} catch {
|
||||
@ -269,6 +438,8 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
LoadFileData(basePath);
|
||||
|
||||
LoadLabels();
|
||||
LoadComments();
|
||||
|
||||
@ -296,6 +467,32 @@ namespace Mesen.GUI.Debugger
|
||||
InteropEmu.DebugSetCdlData(cdlFile);
|
||||
}
|
||||
|
||||
foreach(LineInfo line in _lines.Values) {
|
||||
if(line.SpanID == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
FileInfo file = _files[line.FileID];
|
||||
SpanInfo span = _spans[line.SpanID.Value];
|
||||
SegmentInfo segment = _segments[span.SegmentID];
|
||||
if(!segment.IsRam) {
|
||||
for(int i = 0; i < span.Size; i++) {
|
||||
int prgAddress = segment.FileOffset - iNesHeaderSize + span.Offset + i;
|
||||
|
||||
LineInfo existingLine;
|
||||
if(_linesByPrgAddress.TryGetValue(prgAddress, out existingLine) && existingLine.Type == LineType.External) {
|
||||
//Give priority to lines that come from C files
|
||||
continue;
|
||||
}
|
||||
|
||||
_linesByPrgAddress[prgAddress] = line;
|
||||
if(i == 0) {
|
||||
_prgAddressByLine[file.ID.ToString() + "_" + line.LineNumber.ToString()] = prgAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LabelManager.SetLabels(_romLabels.Values);
|
||||
LabelManager.SetLabels(_ramLabels.Values);
|
||||
|
||||
@ -329,22 +526,41 @@ namespace Mesen.GUI.Debugger
|
||||
public bool IsRam;
|
||||
}
|
||||
|
||||
private class FileInfo
|
||||
public class FileInfo
|
||||
{
|
||||
public int ID;
|
||||
public string Name;
|
||||
public string[] Data;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string folderName = Path.GetDirectoryName(Name);
|
||||
string fileName = Path.GetFileName(Name);
|
||||
if(string.IsNullOrWhiteSpace(folderName)) {
|
||||
return fileName;
|
||||
} else {
|
||||
return $"{fileName} ({folderName})";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class LineInfo
|
||||
public class LineInfo
|
||||
{
|
||||
public int ID;
|
||||
public int FileID;
|
||||
public int SpanID;
|
||||
public int? SpanID;
|
||||
public LineType Type;
|
||||
|
||||
public int LineNumber;
|
||||
}
|
||||
|
||||
public enum LineType
|
||||
{
|
||||
Assembly = 0,
|
||||
External = 1, //i.e C source file
|
||||
Macro = 2
|
||||
}
|
||||
|
||||
private class SpanInfo
|
||||
{
|
||||
public int ID;
|
||||
@ -354,12 +570,22 @@ namespace Mesen.GUI.Debugger
|
||||
public bool IsData;
|
||||
}
|
||||
|
||||
private class SymbolInfo
|
||||
public class SymbolInfo
|
||||
{
|
||||
public int ID;
|
||||
public string Name;
|
||||
public int Address;
|
||||
public int SegmentID;
|
||||
public int? Address;
|
||||
public int? SegmentID;
|
||||
public int? ExportSymbolID;
|
||||
public List<int> References;
|
||||
public List<int> Definitions;
|
||||
}
|
||||
|
||||
public class CSymbolInfo
|
||||
{
|
||||
public int ID;
|
||||
public string Name;
|
||||
public int? SymbolID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ namespace Mesen.GUI.Debugger
|
||||
frm.Show();
|
||||
}
|
||||
|
||||
public static void OpenMemoryViewer(int address)
|
||||
public static void OpenMemoryViewer(int address, bool usePrgRom)
|
||||
{
|
||||
frmMemoryViewer frm = GetMemoryViewer();
|
||||
if(frm == null) {
|
||||
@ -52,7 +52,7 @@ namespace Mesen.GUI.Debugger
|
||||
_openedWindows.Add(frm);
|
||||
}
|
||||
frm.Show();
|
||||
frm.ShowAddress(address);
|
||||
frm.ShowAddress(address, usePrgRom);
|
||||
}
|
||||
|
||||
public static void OpenScriptWindow(bool forceBlank)
|
||||
|
91
GUI.NET/Debugger/frmCodePreviewTooltip.Designer.cs
generated
Normal file
91
GUI.NET/Debugger/frmCodePreviewTooltip.Designer.cs
generated
Normal file
@ -0,0 +1,91 @@
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class frmCodePreviewTooltip
|
||||
{
|
||||
/// <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.panel1 = new System.Windows.Forms.Panel();
|
||||
this.tlpMain = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.panel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.AutoSize = true;
|
||||
this.panel1.BackColor = System.Drawing.SystemColors.Info;
|
||||
this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.panel1.Controls.Add(this.tlpMain);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(10, 10);
|
||||
this.panel1.TabIndex = 0;
|
||||
//
|
||||
// tlpMain
|
||||
//
|
||||
this.tlpMain.AutoSize = true;
|
||||
this.tlpMain.ColumnCount = 2;
|
||||
this.tlpMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tlpMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpMain.Location = new System.Drawing.Point(0, 0);
|
||||
this.tlpMain.Name = "tlpMain";
|
||||
this.tlpMain.RowCount = 2;
|
||||
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tlpMain.Size = new System.Drawing.Size(8, 8);
|
||||
this.tlpMain.TabIndex = 0;
|
||||
//
|
||||
// frmCodeTooltip
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoSize = true;
|
||||
this.ClientSize = new System.Drawing.Size(10, 10);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.panel1);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "frmCodeTooltip";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.Text = "frmCodeTooltip";
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel1.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.TableLayoutPanel tlpMain;
|
||||
}
|
||||
}
|
83
GUI.NET/Debugger/frmCodePreviewTooltip.cs
Normal file
83
GUI.NET/Debugger/frmCodePreviewTooltip.cs
Normal file
@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Config;
|
||||
using Mesen.GUI.Debugger.Controls;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class frmCodePreviewTooltip : Form
|
||||
{
|
||||
private ICodeViewer _codeViewer;
|
||||
|
||||
private int _lineIndex;
|
||||
private string _code;
|
||||
private Ld65DbgImporter _symbolProvider;
|
||||
private Ld65DbgImporter.FileInfo _selectedFile;
|
||||
|
||||
protected override bool ShowWithoutActivation
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public frmCodePreviewTooltip(int lineIndex, string code = null, Ld65DbgImporter symbolProvider = null, Ld65DbgImporter.FileInfo selectedFile = null)
|
||||
{
|
||||
_code = code;
|
||||
_symbolProvider = symbolProvider;
|
||||
_lineIndex = lineIndex;
|
||||
_selectedFile = selectedFile;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnShown(EventArgs e)
|
||||
{
|
||||
base.OnShown(e);
|
||||
|
||||
tlpMain.SuspendLayout();
|
||||
tlpMain.RowStyles.Insert(1, new RowStyle());
|
||||
|
||||
if(_code != null) {
|
||||
_codeViewer = new ctrlDebuggerCode();
|
||||
_codeViewer.SymbolProvider = _symbolProvider;
|
||||
(_codeViewer as ctrlDebuggerCode).Code = _code;
|
||||
} else {
|
||||
_codeViewer = new ctrlSourceViewer();
|
||||
|
||||
//Must set symbol provider before setting CurrentFile
|
||||
_codeViewer.SymbolProvider = _symbolProvider;
|
||||
|
||||
(_codeViewer as ctrlSourceViewer).HideFileDropdown = true;
|
||||
(_codeViewer as ctrlSourceViewer).CurrentFile = _selectedFile;
|
||||
}
|
||||
|
||||
_codeViewer.CodeViewer.HideSelection = true;
|
||||
_codeViewer.CodeViewer.ShowScrollbars = false;
|
||||
_codeViewer.CodeViewer.ScrollToLineIndex(_lineIndex, true);
|
||||
_codeViewer.SetConfig(ConfigManager.Config.DebugInfo.LeftView);
|
||||
|
||||
Control control = _codeViewer as Control;
|
||||
control.Dock = DockStyle.Fill;
|
||||
tlpMain.SetRow(control, 0);
|
||||
tlpMain.SetColumn(control, 0);
|
||||
tlpMain.SetColumnSpan(control, 2);
|
||||
tlpMain.Controls.Add(control);
|
||||
|
||||
tlpMain.ResumeLayout();
|
||||
this.Width = this.tlpMain.Width;
|
||||
this.Height = this.tlpMain.Height;
|
||||
}
|
||||
|
||||
public void ScrollToLineIndex(int lineIndex)
|
||||
{
|
||||
_codeViewer?.CodeViewer.ScrollToLineIndex(0);
|
||||
_codeViewer?.CodeViewer.ScrollToLineIndex(lineIndex);
|
||||
}
|
||||
}
|
||||
}
|
120
GUI.NET/Debugger/frmCodePreviewTooltip.resx
Normal file
120
GUI.NET/Debugger/frmCodePreviewTooltip.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
@ -9,26 +9,29 @@ using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Config;
|
||||
using Mesen.GUI.Debugger.Controls;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class frmCodeTooltip : Form
|
||||
{
|
||||
private ctrlDebuggerCode _codeWindow;
|
||||
private ICodeViewer _codeViewer;
|
||||
private Dictionary<string, string> _values;
|
||||
private int _previewAddress;
|
||||
private AddressTypeInfo? _previewAddress;
|
||||
private string _code;
|
||||
private Ld65DbgImporter _symbolProvider;
|
||||
|
||||
protected override bool ShowWithoutActivation
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public frmCodeTooltip(Dictionary<string, string> values, int previewAddress = -1, string code = null)
|
||||
public frmCodeTooltip(Dictionary<string, string> values, AddressTypeInfo? previewAddress = null, string code = null, Ld65DbgImporter symbolProvider = null)
|
||||
{
|
||||
_values = values;
|
||||
_previewAddress = previewAddress;
|
||||
_code = code;
|
||||
_symbolProvider = symbolProvider;
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@ -61,31 +64,33 @@ namespace Mesen.GUI.Debugger
|
||||
i++;
|
||||
}
|
||||
|
||||
if(_previewAddress >= 0) {
|
||||
if(_previewAddress.HasValue) {
|
||||
tlpMain.RowStyles.Insert(1, new RowStyle());
|
||||
|
||||
_codeWindow = new ctrlDebuggerCode();
|
||||
_codeWindow.HideSelection = true;
|
||||
_codeWindow.SetConfig(ConfigManager.Config.DebugInfo.LeftView);
|
||||
_codeWindow.Code = _code;
|
||||
_codeWindow.Dock = DockStyle.Fill;
|
||||
_codeWindow.ShowScrollbars = false;
|
||||
_codeWindow.ScrollToLineNumber(_previewAddress, true);
|
||||
if(_code != null) {
|
||||
_codeViewer = new ctrlDebuggerCode();
|
||||
(_codeViewer as ctrlDebuggerCode).Code = _code;
|
||||
} else {
|
||||
_codeViewer = new ctrlSourceViewer();
|
||||
(_codeViewer as ctrlSourceViewer).HideFileDropdown = true;
|
||||
}
|
||||
|
||||
tlpMain.SetRow(_codeWindow, i);
|
||||
tlpMain.SetColumn(_codeWindow, 0);
|
||||
tlpMain.SetColumnSpan(_codeWindow, 2);
|
||||
tlpMain.Controls.Add(_codeWindow);
|
||||
_codeViewer.SymbolProvider = _symbolProvider;
|
||||
_codeViewer.CodeViewer.HideSelection = true;
|
||||
_codeViewer.CodeViewer.ShowScrollbars = false;
|
||||
_codeViewer.ScrollToAddress(_previewAddress.Value, true);
|
||||
_codeViewer.SetConfig(ConfigManager.Config.DebugInfo.LeftView);
|
||||
|
||||
Control control = _codeViewer as Control;
|
||||
control.Dock = DockStyle.Fill;
|
||||
tlpMain.SetRow(control, i);
|
||||
tlpMain.SetColumn(control, 0);
|
||||
tlpMain.SetColumnSpan(control, 2);
|
||||
tlpMain.Controls.Add(control);
|
||||
}
|
||||
tlpMain.ResumeLayout();
|
||||
this.Width = this.tlpMain.Width;
|
||||
this.Height = this.tlpMain.Height;
|
||||
}
|
||||
|
||||
public void ScrollToLineIndex(int lineIndex)
|
||||
{
|
||||
_codeWindow?.ScrollToLineIndex(0);
|
||||
_codeWindow?.ScrollToLineIndex(lineIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ namespace Mesen.GUI.Debugger
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
ctrlDbgShortcutsShared.Shortcuts = new FieldInfo[24] {
|
||||
ctrlDbgShortcutsShared.Shortcuts = new FieldInfo[] {
|
||||
GetMember(nameof(DebuggerShortcutsConfig.IncreaseFontSize)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.DecreaseFontSize)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.ResetFontSize)),
|
||||
@ -47,7 +47,7 @@ namespace Mesen.GUI.Debugger
|
||||
GetMember(nameof(DebuggerShortcutsConfig.OpenTraceLogger))
|
||||
};
|
||||
|
||||
ctrlDbgShortcutsMemoryViewer.Shortcuts = new FieldInfo[7] {
|
||||
ctrlDbgShortcutsMemoryViewer.Shortcuts = new FieldInfo[] {
|
||||
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Freeze)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Unfreeze)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_AddToWatch)),
|
||||
@ -57,14 +57,14 @@ namespace Mesen.GUI.Debugger
|
||||
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Export))
|
||||
};
|
||||
|
||||
ctrlDbgShortcutsScriptWindow.Shortcuts = new FieldInfo[4] {
|
||||
ctrlDbgShortcutsScriptWindow.Shortcuts = new FieldInfo[] {
|
||||
GetMember(nameof(DebuggerShortcutsConfig.ScriptWindow_OpenScript)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.ScriptWindow_SaveScript)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.ScriptWindow_RunScript)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.ScriptWindow_StopScript))
|
||||
};
|
||||
|
||||
ctrlDbgShortcutsDebugger.Shortcuts = new FieldInfo[43] {
|
||||
ctrlDbgShortcutsDebugger.Shortcuts = new FieldInfo[] {
|
||||
GetMember(nameof(DebuggerShortcutsConfig.Continue)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.Break)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.ToggleBreakContinue)),
|
||||
@ -88,6 +88,7 @@ namespace Mesen.GUI.Debugger
|
||||
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_NavigateForward)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_ToggleBreakpoint)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_DisableEnableBreakpoint)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_SwitchView)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.FunctionList_EditLabel)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.FunctionList_AddBreakpoint)),
|
||||
GetMember(nameof(DebuggerShortcutsConfig.FunctionList_FindOccurrences)),
|
||||
|
180
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
180
GUI.NET/Debugger/frmDebugger.Designer.cs
generated
@ -34,8 +34,12 @@ namespace Mesen.GUI.Debugger
|
||||
this.splitContainer = new Mesen.GUI.Controls.ctrlSplitContainer();
|
||||
this.ctrlSplitContainerTop = new Mesen.GUI.Controls.ctrlSplitContainer();
|
||||
this.tlpTop = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.ctrlDebuggerCode = new Mesen.GUI.Debugger.ctrlDebuggerCode();
|
||||
this.ctrlConsoleStatus = new Mesen.GUI.Debugger.ctrlConsoleStatus();
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.ctrlSourceViewer = new Mesen.GUI.Debugger.Controls.ctrlSourceViewer();
|
||||
this.ctrlDebuggerCode = new Mesen.GUI.Debugger.ctrlDebuggerCode();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.ctrlSourceViewerSplit = new Mesen.GUI.Debugger.Controls.ctrlSourceViewer();
|
||||
this.ctrlDebuggerCodeSplit = new Mesen.GUI.Debugger.ctrlDebuggerCode();
|
||||
this.tlpFunctionLabelLists = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.grpLabels = new System.Windows.Forms.GroupBox();
|
||||
@ -86,6 +90,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.mnuRunOneFrame = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuBreakIn = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuBreakOn = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuFind = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem();
|
||||
@ -186,7 +191,6 @@ namespace Mesen.GUI.Debugger
|
||||
this.ctrlPpuMemoryMapping = new Mesen.GUI.Debugger.Controls.ctrlMemoryMapping();
|
||||
this.ctrlCpuMemoryMapping = new Mesen.GUI.Debugger.Controls.ctrlMemoryMapping();
|
||||
this.tsToolbar = new Mesen.GUI.Controls.ctrlMesenToolStrip();
|
||||
this.mnuBreakOn = new System.Windows.Forms.ToolStripMenuItem();
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
|
||||
this.splitContainer.Panel1.SuspendLayout();
|
||||
this.splitContainer.Panel2.SuspendLayout();
|
||||
@ -196,6 +200,8 @@ namespace Mesen.GUI.Debugger
|
||||
this.ctrlSplitContainerTop.Panel2.SuspendLayout();
|
||||
this.ctrlSplitContainerTop.SuspendLayout();
|
||||
this.tlpTop.SuspendLayout();
|
||||
this.panel1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
this.tlpFunctionLabelLists.SuspendLayout();
|
||||
this.grpLabels.SuspendLayout();
|
||||
this.grpFunctions.SuspendLayout();
|
||||
@ -231,8 +237,8 @@ namespace Mesen.GUI.Debugger
|
||||
this.splitContainer.Panel2.Controls.Add(this.picWatchHelp);
|
||||
this.splitContainer.Panel2.Controls.Add(this.tableLayoutPanel10);
|
||||
this.splitContainer.Panel2MinSize = 100;
|
||||
this.splitContainer.Size = new System.Drawing.Size(1172, 573);
|
||||
this.splitContainer.SplitterDistance = 400;
|
||||
this.splitContainer.Size = new System.Drawing.Size(1075, 576);
|
||||
this.splitContainer.SplitterDistance = 413;
|
||||
this.splitContainer.SplitterWidth = 7;
|
||||
this.splitContainer.TabIndex = 1;
|
||||
this.splitContainer.TabStop = false;
|
||||
@ -255,7 +261,7 @@ namespace Mesen.GUI.Debugger
|
||||
//
|
||||
this.ctrlSplitContainerTop.Panel2.Controls.Add(this.tlpFunctionLabelLists);
|
||||
this.ctrlSplitContainerTop.Panel2MinSize = 150;
|
||||
this.ctrlSplitContainerTop.Size = new System.Drawing.Size(1172, 400);
|
||||
this.ctrlSplitContainerTop.Size = new System.Drawing.Size(1075, 413);
|
||||
this.ctrlSplitContainerTop.SplitterDistance = 750;
|
||||
this.ctrlSplitContainerTop.SplitterWidth = 7;
|
||||
this.ctrlSplitContainerTop.TabIndex = 3;
|
||||
@ -269,61 +275,99 @@ namespace Mesen.GUI.Debugger
|
||||
this.tlpTop.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 0F));
|
||||
this.tlpTop.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tlpTop.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tlpTop.Controls.Add(this.ctrlDebuggerCode, 0, 0);
|
||||
this.tlpTop.Controls.Add(this.ctrlConsoleStatus, 2, 0);
|
||||
this.tlpTop.Controls.Add(this.ctrlDebuggerCodeSplit, 1, 0);
|
||||
this.tlpTop.Controls.Add(this.panel1, 0, 0);
|
||||
this.tlpTop.Controls.Add(this.panel2, 1, 0);
|
||||
this.tlpTop.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tlpTop.Location = new System.Drawing.Point(0, 0);
|
||||
this.tlpTop.Name = "tlpTop";
|
||||
this.tlpTop.RowCount = 1;
|
||||
this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tlpTop.Size = new System.Drawing.Size(750, 400);
|
||||
this.tlpTop.Size = new System.Drawing.Size(750, 413);
|
||||
this.tlpTop.TabIndex = 2;
|
||||
//
|
||||
// ctrlDebuggerCode
|
||||
//
|
||||
this.ctrlDebuggerCode.Code = null;
|
||||
this.ctrlDebuggerCode.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlDebuggerCode.HideSelection = false;
|
||||
this.ctrlDebuggerCode.Location = new System.Drawing.Point(3, 3);
|
||||
this.ctrlDebuggerCode.Name = "ctrlDebuggerCode";
|
||||
this.ctrlDebuggerCode.ShowMemoryValues = false;
|
||||
this.ctrlDebuggerCode.ShowScrollbars = true;
|
||||
this.ctrlDebuggerCode.Size = new System.Drawing.Size(286, 394);
|
||||
this.ctrlDebuggerCode.TabIndex = 2;
|
||||
this.ctrlDebuggerCode.TextZoom = 100;
|
||||
this.ctrlDebuggerCode.OnEditCode += new Mesen.GUI.Debugger.ctrlDebuggerCode.AssemblerEventHandler(this.ctrlDebuggerCode_OnEditCode);
|
||||
this.ctrlDebuggerCode.OnSetNextStatement += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnSetNextStatement);
|
||||
this.ctrlDebuggerCode.OnScrollToAddress += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnScrollToAddress);
|
||||
this.ctrlDebuggerCode.Enter += new System.EventHandler(this.ctrlDebuggerCode_Enter);
|
||||
//
|
||||
// ctrlConsoleStatus
|
||||
//
|
||||
this.ctrlConsoleStatus.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlConsoleStatus.Location = new System.Drawing.Point(292, 0);
|
||||
this.ctrlConsoleStatus.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.ctrlConsoleStatus.Name = "ctrlConsoleStatus";
|
||||
this.ctrlConsoleStatus.Size = new System.Drawing.Size(458, 400);
|
||||
this.ctrlConsoleStatus.Size = new System.Drawing.Size(458, 413);
|
||||
this.ctrlConsoleStatus.TabIndex = 3;
|
||||
this.ctrlConsoleStatus.OnGotoLocation += new System.EventHandler(this.ctrlConsoleStatus_OnGotoLocation);
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.Controls.Add(this.ctrlSourceViewer);
|
||||
this.panel1.Controls.Add(this.ctrlDebuggerCode);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel1.Location = new System.Drawing.Point(3, 0);
|
||||
this.panel1.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(286, 413);
|
||||
this.panel1.TabIndex = 5;
|
||||
//
|
||||
// ctrlSourceViewer
|
||||
//
|
||||
this.ctrlSourceViewer.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlSourceViewer.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlSourceViewer.Name = "ctrlSourceViewer";
|
||||
this.ctrlSourceViewer.Size = new System.Drawing.Size(286, 413);
|
||||
this.ctrlSourceViewer.SymbolProvider = null;
|
||||
this.ctrlSourceViewer.TabIndex = 7;
|
||||
this.ctrlSourceViewer.Visible = false;
|
||||
this.ctrlSourceViewer.Enter += new System.EventHandler(this.ctrlDebuggerCode_Enter);
|
||||
//
|
||||
// ctrlDebuggerCode
|
||||
//
|
||||
this.ctrlDebuggerCode.Code = null;
|
||||
this.ctrlDebuggerCode.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlDebuggerCode.HideSelection = false;
|
||||
this.ctrlDebuggerCode.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlDebuggerCode.Name = "ctrlDebuggerCode";
|
||||
this.ctrlDebuggerCode.ShowMemoryValues = false;
|
||||
this.ctrlDebuggerCode.Size = new System.Drawing.Size(286, 413);
|
||||
this.ctrlDebuggerCode.SymbolProvider = null;
|
||||
this.ctrlDebuggerCode.TabIndex = 2;
|
||||
this.ctrlDebuggerCode.OnEditCode += new Mesen.GUI.Debugger.ctrlDebuggerCode.AssemblerEventHandler(this.ctrlDebuggerCode_OnEditCode);
|
||||
this.ctrlDebuggerCode.Enter += new System.EventHandler(this.ctrlDebuggerCode_Enter);
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.Controls.Add(this.ctrlSourceViewerSplit);
|
||||
this.panel2.Controls.Add(this.ctrlDebuggerCodeSplit);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel2.Location = new System.Drawing.Point(292, 0);
|
||||
this.panel2.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(1, 413);
|
||||
this.panel2.TabIndex = 6;
|
||||
//
|
||||
// ctrlSourceViewerSplit
|
||||
//
|
||||
this.ctrlSourceViewerSplit.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlSourceViewerSplit.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlSourceViewerSplit.Name = "ctrlSourceViewerSplit";
|
||||
this.ctrlSourceViewerSplit.Size = new System.Drawing.Size(1, 413);
|
||||
this.ctrlSourceViewerSplit.SymbolProvider = null;
|
||||
this.ctrlSourceViewerSplit.TabIndex = 8;
|
||||
this.ctrlSourceViewerSplit.Visible = false;
|
||||
this.ctrlSourceViewerSplit.Enter += new System.EventHandler(this.ctrlDebuggerCode_Enter);
|
||||
//
|
||||
// ctrlDebuggerCodeSplit
|
||||
//
|
||||
this.ctrlDebuggerCodeSplit.Code = null;
|
||||
this.ctrlDebuggerCodeSplit.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlDebuggerCodeSplit.HideSelection = false;
|
||||
this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(295, 3);
|
||||
this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlDebuggerCodeSplit.Name = "ctrlDebuggerCodeSplit";
|
||||
this.ctrlDebuggerCodeSplit.ShowMemoryValues = false;
|
||||
this.ctrlDebuggerCodeSplit.ShowScrollbars = true;
|
||||
this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 394);
|
||||
this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 413);
|
||||
this.ctrlDebuggerCodeSplit.SymbolProvider = null;
|
||||
this.ctrlDebuggerCodeSplit.TabIndex = 4;
|
||||
this.ctrlDebuggerCodeSplit.TextZoom = 100;
|
||||
this.ctrlDebuggerCodeSplit.Visible = false;
|
||||
this.ctrlDebuggerCodeSplit.OnEditCode += new Mesen.GUI.Debugger.ctrlDebuggerCode.AssemblerEventHandler(this.ctrlDebuggerCode_OnEditCode);
|
||||
this.ctrlDebuggerCodeSplit.OnSetNextStatement += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnSetNextStatement);
|
||||
this.ctrlDebuggerCodeSplit.OnScrollToAddress += new Mesen.GUI.Debugger.ctrlDebuggerCode.AddressEventHandler(this.ctrlDebuggerCode_OnScrollToAddress);
|
||||
this.ctrlDebuggerCodeSplit.Enter += new System.EventHandler(this.ctrlDebuggerCodeSplit_Enter);
|
||||
this.ctrlDebuggerCodeSplit.Enter += new System.EventHandler(this.ctrlDebuggerCode_Enter);
|
||||
//
|
||||
// tlpFunctionLabelLists
|
||||
//
|
||||
@ -338,16 +382,16 @@ namespace Mesen.GUI.Debugger
|
||||
this.tlpFunctionLabelLists.RowCount = 2;
|
||||
this.tlpFunctionLabelLists.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tlpFunctionLabelLists.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
|
||||
this.tlpFunctionLabelLists.Size = new System.Drawing.Size(418, 400);
|
||||
this.tlpFunctionLabelLists.Size = new System.Drawing.Size(318, 413);
|
||||
this.tlpFunctionLabelLists.TabIndex = 5;
|
||||
//
|
||||
// grpLabels
|
||||
//
|
||||
this.grpLabels.Controls.Add(this.ctrlLabelList);
|
||||
this.grpLabels.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpLabels.Location = new System.Drawing.Point(3, 203);
|
||||
this.grpLabels.Location = new System.Drawing.Point(3, 209);
|
||||
this.grpLabels.Name = "grpLabels";
|
||||
this.grpLabels.Size = new System.Drawing.Size(412, 194);
|
||||
this.grpLabels.Size = new System.Drawing.Size(312, 201);
|
||||
this.grpLabels.TabIndex = 6;
|
||||
this.grpLabels.TabStop = false;
|
||||
this.grpLabels.Text = "Labels";
|
||||
@ -357,7 +401,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.ctrlLabelList.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlLabelList.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlLabelList.Name = "ctrlLabelList";
|
||||
this.ctrlLabelList.Size = new System.Drawing.Size(406, 175);
|
||||
this.ctrlLabelList.Size = new System.Drawing.Size(306, 182);
|
||||
this.ctrlLabelList.TabIndex = 0;
|
||||
this.ctrlLabelList.OnFindOccurrence += new System.EventHandler(this.ctrlLabelList_OnFindOccurrence);
|
||||
this.ctrlLabelList.OnLabelSelected += new System.EventHandler(this.ctrlLabelList_OnLabelSelected);
|
||||
@ -368,7 +412,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.grpFunctions.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpFunctions.Location = new System.Drawing.Point(3, 3);
|
||||
this.grpFunctions.Name = "grpFunctions";
|
||||
this.grpFunctions.Size = new System.Drawing.Size(412, 194);
|
||||
this.grpFunctions.Size = new System.Drawing.Size(312, 200);
|
||||
this.grpFunctions.TabIndex = 5;
|
||||
this.grpFunctions.TabStop = false;
|
||||
this.grpFunctions.Text = "Functions";
|
||||
@ -378,7 +422,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.ctrlFunctionList.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlFunctionList.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlFunctionList.Name = "ctrlFunctionList";
|
||||
this.ctrlFunctionList.Size = new System.Drawing.Size(406, 175);
|
||||
this.ctrlFunctionList.Size = new System.Drawing.Size(306, 181);
|
||||
this.ctrlFunctionList.TabIndex = 0;
|
||||
this.ctrlFunctionList.OnFindOccurrence += new System.EventHandler(this.ctrlFunctionList_OnFindOccurrence);
|
||||
this.ctrlFunctionList.OnFunctionSelected += new System.EventHandler(this.ctrlFunctionList_OnFunctionSelected);
|
||||
@ -409,7 +453,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel10.Size = new System.Drawing.Size(1172, 166);
|
||||
this.tableLayoutPanel10.Size = new System.Drawing.Size(1075, 156);
|
||||
this.tableLayoutPanel10.TabIndex = 0;
|
||||
//
|
||||
// grpWatch
|
||||
@ -418,7 +462,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.grpWatch.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpWatch.Location = new System.Drawing.Point(3, 3);
|
||||
this.grpWatch.Name = "grpWatch";
|
||||
this.grpWatch.Size = new System.Drawing.Size(384, 160);
|
||||
this.grpWatch.Size = new System.Drawing.Size(352, 150);
|
||||
this.grpWatch.TabIndex = 2;
|
||||
this.grpWatch.TabStop = false;
|
||||
this.grpWatch.Text = "Watch";
|
||||
@ -428,16 +472,16 @@ namespace Mesen.GUI.Debugger
|
||||
this.ctrlWatch.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlWatch.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlWatch.Name = "ctrlWatch";
|
||||
this.ctrlWatch.Size = new System.Drawing.Size(378, 141);
|
||||
this.ctrlWatch.Size = new System.Drawing.Size(346, 131);
|
||||
this.ctrlWatch.TabIndex = 0;
|
||||
//
|
||||
// grpBreakpoints
|
||||
//
|
||||
this.grpBreakpoints.Controls.Add(this.ctrlBreakpoints);
|
||||
this.grpBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpBreakpoints.Location = new System.Drawing.Point(393, 3);
|
||||
this.grpBreakpoints.Location = new System.Drawing.Point(361, 3);
|
||||
this.grpBreakpoints.Name = "grpBreakpoints";
|
||||
this.grpBreakpoints.Size = new System.Drawing.Size(384, 160);
|
||||
this.grpBreakpoints.Size = new System.Drawing.Size(352, 150);
|
||||
this.grpBreakpoints.TabIndex = 3;
|
||||
this.grpBreakpoints.TabStop = false;
|
||||
this.grpBreakpoints.Text = "Breakpoints";
|
||||
@ -447,7 +491,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.ctrlBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlBreakpoints.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlBreakpoints.Name = "ctrlBreakpoints";
|
||||
this.ctrlBreakpoints.Size = new System.Drawing.Size(378, 141);
|
||||
this.ctrlBreakpoints.Size = new System.Drawing.Size(346, 131);
|
||||
this.ctrlBreakpoints.TabIndex = 0;
|
||||
this.ctrlBreakpoints.BreakpointNavigation += new System.EventHandler(this.ctrlBreakpoints_BreakpointNavigation);
|
||||
//
|
||||
@ -455,9 +499,9 @@ namespace Mesen.GUI.Debugger
|
||||
//
|
||||
this.grpCallstack.Controls.Add(this.ctrlCallstack);
|
||||
this.grpCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.grpCallstack.Location = new System.Drawing.Point(783, 3);
|
||||
this.grpCallstack.Location = new System.Drawing.Point(719, 3);
|
||||
this.grpCallstack.Name = "grpCallstack";
|
||||
this.grpCallstack.Size = new System.Drawing.Size(386, 160);
|
||||
this.grpCallstack.Size = new System.Drawing.Size(353, 150);
|
||||
this.grpCallstack.TabIndex = 4;
|
||||
this.grpCallstack.TabStop = false;
|
||||
this.grpCallstack.Text = "Call Stack";
|
||||
@ -467,7 +511,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.ctrlCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlCallstack.Location = new System.Drawing.Point(3, 16);
|
||||
this.ctrlCallstack.Name = "ctrlCallstack";
|
||||
this.ctrlCallstack.Size = new System.Drawing.Size(380, 141);
|
||||
this.ctrlCallstack.Size = new System.Drawing.Size(347, 131);
|
||||
this.ctrlCallstack.TabIndex = 0;
|
||||
this.ctrlCallstack.FunctionSelected += new System.EventHandler(this.ctrlCallstack_FunctionSelected);
|
||||
//
|
||||
@ -482,7 +526,7 @@ namespace Mesen.GUI.Debugger
|
||||
this.toolsToolStripMenuItem});
|
||||
this.menuStrip.Location = new System.Drawing.Point(0, 0);
|
||||
this.menuStrip.Name = "menuStrip";
|
||||
this.menuStrip.Size = new System.Drawing.Size(1172, 24);
|
||||
this.menuStrip.Size = new System.Drawing.Size(1075, 24);
|
||||
this.menuStrip.TabIndex = 2;
|
||||
this.menuStrip.Text = "menuStrip1";
|
||||
//
|
||||
@ -775,6 +819,13 @@ namespace Mesen.GUI.Debugger
|
||||
this.mnuBreakIn.Text = "Break in...";
|
||||
this.mnuBreakIn.Click += new System.EventHandler(this.mnuBreakIn_Click);
|
||||
//
|
||||
// mnuBreakOn
|
||||
//
|
||||
this.mnuBreakOn.Name = "mnuBreakOn";
|
||||
this.mnuBreakOn.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuBreakOn.Text = "Break on...";
|
||||
this.mnuBreakOn.Click += new System.EventHandler(this.mnuBreakOn_Click);
|
||||
//
|
||||
// searchToolStripMenuItem
|
||||
//
|
||||
this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
@ -1524,9 +1575,9 @@ namespace Mesen.GUI.Debugger
|
||||
this.toolStripStatusLabel1,
|
||||
this.lblCyclesElapsedCount,
|
||||
this.lblCyclesElapsed});
|
||||
this.statusStrip.Location = new System.Drawing.Point(0, 663);
|
||||
this.statusStrip.Location = new System.Drawing.Point(0, 666);
|
||||
this.statusStrip.Name = "statusStrip";
|
||||
this.statusStrip.Size = new System.Drawing.Size(1172, 24);
|
||||
this.statusStrip.Size = new System.Drawing.Size(1075, 24);
|
||||
this.statusStrip.TabIndex = 3;
|
||||
this.statusStrip.Text = "statusStrip1";
|
||||
//
|
||||
@ -1560,7 +1611,7 @@ namespace Mesen.GUI.Debugger
|
||||
// toolStripStatusLabel1
|
||||
//
|
||||
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
|
||||
this.toolStripStatusLabel1.Size = new System.Drawing.Size(437, 19);
|
||||
this.toolStripStatusLabel1.Size = new System.Drawing.Size(340, 19);
|
||||
this.toolStripStatusLabel1.Spring = true;
|
||||
//
|
||||
// lblCyclesElapsedCount
|
||||
@ -1579,9 +1630,9 @@ namespace Mesen.GUI.Debugger
|
||||
// ctrlPpuMemoryMapping
|
||||
//
|
||||
this.ctrlPpuMemoryMapping.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.ctrlPpuMemoryMapping.Location = new System.Drawing.Point(0, 630);
|
||||
this.ctrlPpuMemoryMapping.Location = new System.Drawing.Point(0, 633);
|
||||
this.ctrlPpuMemoryMapping.Name = "ctrlPpuMemoryMapping";
|
||||
this.ctrlPpuMemoryMapping.Size = new System.Drawing.Size(1172, 33);
|
||||
this.ctrlPpuMemoryMapping.Size = new System.Drawing.Size(1075, 33);
|
||||
this.ctrlPpuMemoryMapping.TabIndex = 5;
|
||||
this.ctrlPpuMemoryMapping.Text = "ctrlMemoryMapping1";
|
||||
this.ctrlPpuMemoryMapping.Visible = false;
|
||||
@ -1589,9 +1640,9 @@ namespace Mesen.GUI.Debugger
|
||||
// ctrlCpuMemoryMapping
|
||||
//
|
||||
this.ctrlCpuMemoryMapping.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.ctrlCpuMemoryMapping.Location = new System.Drawing.Point(0, 597);
|
||||
this.ctrlCpuMemoryMapping.Location = new System.Drawing.Point(0, 600);
|
||||
this.ctrlCpuMemoryMapping.Name = "ctrlCpuMemoryMapping";
|
||||
this.ctrlCpuMemoryMapping.Size = new System.Drawing.Size(1172, 33);
|
||||
this.ctrlCpuMemoryMapping.Size = new System.Drawing.Size(1075, 33);
|
||||
this.ctrlCpuMemoryMapping.TabIndex = 4;
|
||||
this.ctrlCpuMemoryMapping.Text = "ctrlMemoryMapping1";
|
||||
this.ctrlCpuMemoryMapping.Visible = false;
|
||||
@ -1600,23 +1651,16 @@ namespace Mesen.GUI.Debugger
|
||||
//
|
||||
this.tsToolbar.Location = new System.Drawing.Point(0, 24);
|
||||
this.tsToolbar.Name = "tsToolbar";
|
||||
this.tsToolbar.Size = new System.Drawing.Size(1172, 25);
|
||||
this.tsToolbar.Size = new System.Drawing.Size(1075, 25);
|
||||
this.tsToolbar.TabIndex = 6;
|
||||
this.tsToolbar.Text = "toolStrip1";
|
||||
this.tsToolbar.Visible = false;
|
||||
//
|
||||
// mnuBreakOn
|
||||
//
|
||||
this.mnuBreakOn.Name = "mnuBreakOn";
|
||||
this.mnuBreakOn.Size = new System.Drawing.Size(212, 22);
|
||||
this.mnuBreakOn.Text = "Break on...";
|
||||
this.mnuBreakOn.Click += new System.EventHandler(this.mnuBreakOn_Click);
|
||||
//
|
||||
// frmDebugger
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(1172, 687);
|
||||
this.ClientSize = new System.Drawing.Size(1075, 690);
|
||||
this.Controls.Add(this.splitContainer);
|
||||
this.Controls.Add(this.ctrlCpuMemoryMapping);
|
||||
this.Controls.Add(this.ctrlPpuMemoryMapping);
|
||||
@ -1636,6 +1680,8 @@ namespace Mesen.GUI.Debugger
|
||||
((System.ComponentModel.ISupportInitialize)(this.ctrlSplitContainerTop)).EndInit();
|
||||
this.ctrlSplitContainerTop.ResumeLayout(false);
|
||||
this.tlpTop.ResumeLayout(false);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel2.ResumeLayout(false);
|
||||
this.tlpFunctionLabelLists.ResumeLayout(false);
|
||||
this.grpLabels.ResumeLayout(false);
|
||||
this.grpFunctions.ResumeLayout(false);
|
||||
@ -1798,6 +1844,10 @@ namespace Mesen.GUI.Debugger
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem20;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuBringToFrontOnPause;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuBringToFrontOnBreak;
|
||||
private ctrlSourceViewer ctrlSourceViewer;
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
private ctrlSourceViewer ctrlSourceViewerSplit;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem21;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuSelectFont;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem22;
|
||||
|
@ -24,7 +24,7 @@ namespace Mesen.GUI.Debugger
|
||||
private int _previousCycle = 0;
|
||||
|
||||
private InteropEmu.NotificationListener _notifListener;
|
||||
private ctrlDebuggerCode _lastCodeWindow;
|
||||
private ICodeViewer _lastCodeWindow;
|
||||
private Size _minimumSize;
|
||||
|
||||
public frmDebugger()
|
||||
@ -51,9 +51,27 @@ namespace Mesen.GUI.Debugger
|
||||
BreakpointManager.BreakpointsChanged += BreakpointManager_BreakpointsChanged;
|
||||
ctrlProfiler.OnFunctionSelected += ctrlProfiler_OnFunctionSelected;
|
||||
|
||||
ctrlDebuggerCode.CodeViewerActions.OnSetNextStatement += ctrlDebuggerCode_OnSetNextStatement;
|
||||
ctrlDebuggerCode.CodeViewerActions.OnShowInSplitView += ctrlDebuggerCode_OnShowInSplitView;
|
||||
ctrlDebuggerCode.CodeViewerActions.OnSwitchView += ctrlDebuggerCode_OnSwitchView;
|
||||
|
||||
ctrlDebuggerCodeSplit.CodeViewerActions.OnSetNextStatement += ctrlDebuggerCode_OnSetNextStatement;
|
||||
ctrlDebuggerCodeSplit.CodeViewerActions.OnShowInSplitView += ctrlDebuggerCode_OnShowInSplitView;
|
||||
ctrlDebuggerCodeSplit.CodeViewerActions.OnSwitchView += ctrlDebuggerCode_OnSwitchView;
|
||||
|
||||
ctrlSourceViewer.CodeViewerActions.OnSetNextStatement += ctrlDebuggerCode_OnSetNextStatement;
|
||||
ctrlSourceViewer.CodeViewerActions.OnShowInSplitView += ctrlDebuggerCode_OnShowInSplitView;
|
||||
ctrlSourceViewer.CodeViewerActions.OnSwitchView += ctrlDebuggerCode_OnSwitchView;
|
||||
|
||||
ctrlSourceViewerSplit.CodeViewerActions.OnSetNextStatement += ctrlDebuggerCode_OnSetNextStatement;
|
||||
ctrlSourceViewerSplit.CodeViewerActions.OnShowInSplitView += ctrlDebuggerCode_OnShowInSplitView;
|
||||
ctrlSourceViewerSplit.CodeViewerActions.OnSwitchView += ctrlDebuggerCode_OnSwitchView;
|
||||
|
||||
Font font = new Font(ConfigManager.Config.DebugInfo.FontFamily, ConfigManager.Config.DebugInfo.FontSize, ConfigManager.Config.DebugInfo.FontStyle);
|
||||
ctrlDebuggerCode.BaseFont = font;
|
||||
ctrlDebuggerCodeSplit.BaseFont = font;
|
||||
ctrlDebuggerCode.CodeViewer.BaseFont = font;
|
||||
ctrlDebuggerCodeSplit.CodeViewer.BaseFont = font;
|
||||
ctrlSourceViewer.CodeViewer.BaseFont = font;
|
||||
ctrlSourceViewerSplit.CodeViewer.BaseFont = font;
|
||||
|
||||
this.InitShortcuts();
|
||||
this.InitToolbar();
|
||||
@ -127,7 +145,9 @@ namespace Mesen.GUI.Debugger
|
||||
_lastCodeWindow = ctrlDebuggerCode;
|
||||
|
||||
this.ctrlDebuggerCode.SetConfig(ConfigManager.Config.DebugInfo.LeftView);
|
||||
this.ctrlSourceViewer.SetConfig(ConfigManager.Config.DebugInfo.LeftView);
|
||||
this.ctrlDebuggerCodeSplit.SetConfig(ConfigManager.Config.DebugInfo.RightView);
|
||||
this.ctrlSourceViewerSplit.SetConfig(ConfigManager.Config.DebugInfo.RightView);
|
||||
|
||||
this.toolTip.SetToolTip(this.picWatchHelp, frmBreakpoint.GetConditionTooltip(true));
|
||||
|
||||
@ -214,7 +234,8 @@ namespace Mesen.GUI.Debugger
|
||||
mnuToggleBreakpoint, mnuDisableEnableBreakpoint, null,
|
||||
mnuFind, mnuFindPrev, mnuFindNext, null,
|
||||
mnuApuViewer, mnuAssembler, mnuMemoryViewer, mnuEventViewer, mnuPpuViewer, mnuScriptWindow, mnuTraceLogger, null,
|
||||
mnuEditHeader, null
|
||||
mnuEditHeader, null,
|
||||
mnuSplitView, null
|
||||
);
|
||||
AddItemToToolbar(mnuShowVerifiedData, "Show Verified Data");
|
||||
AddItemToToolbar(mnuShowUnidentifiedData, "Show Unidentified Code/Data");
|
||||
@ -316,12 +337,16 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
private void AutoLoadDbgFiles(bool silent)
|
||||
{
|
||||
ctrlSourceViewer.SymbolProvider = null;
|
||||
ctrlSourceViewerSplit.SymbolProvider = null;
|
||||
ctrlDebuggerCode.SymbolProvider = null;
|
||||
ctrlDebuggerCodeSplit.SymbolProvider = null;
|
||||
|
||||
if(ConfigManager.Config.DebugInfo.AutoLoadDbgFiles) {
|
||||
RomInfo info = InteropEmu.GetRomInfo();
|
||||
string dbgPath = Path.Combine(info.RomFile.Folder, info.GetRomName() + ".dbg");
|
||||
if(File.Exists(dbgPath)) {
|
||||
Ld65DbgImporter dbgImporter = new Ld65DbgImporter();
|
||||
dbgImporter.Import(dbgPath, silent);
|
||||
ImportDbgFile(dbgPath, silent);
|
||||
} else {
|
||||
string mlbPath = Path.Combine(info.RomFile.Folder, info.GetRomName() + ".mlb");
|
||||
if(File.Exists(mlbPath)) {
|
||||
@ -329,6 +354,24 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ctrlSourceViewer.SymbolProvider == null) {
|
||||
ctrlSourceViewer.Visible = false;
|
||||
ctrlSourceViewerSplit.Visible = false;
|
||||
ctrlDebuggerCode.Visible = true;
|
||||
ctrlDebuggerCodeSplit.Visible = true;
|
||||
ctrlDebuggerCode.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
private void ImportDbgFile(string dbgPath, bool silent)
|
||||
{
|
||||
Ld65DbgImporter dbgImporter = new Ld65DbgImporter();
|
||||
dbgImporter.Import(dbgPath, silent);
|
||||
ctrlDebuggerCode.SymbolProvider = dbgImporter;
|
||||
ctrlDebuggerCodeSplit.SymbolProvider = dbgImporter;
|
||||
ctrlSourceViewer.SymbolProvider = dbgImporter;
|
||||
ctrlSourceViewerSplit.SymbolProvider = dbgImporter;
|
||||
}
|
||||
|
||||
private void UpdateWorkspace()
|
||||
@ -479,7 +522,7 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
ctrlDebuggerCodeSplit.UpdateCode(true);
|
||||
} else {
|
||||
_lastCodeWindow = ctrlDebuggerCode;
|
||||
_lastCodeWindow = ctrlSourceViewer.Visible ? (ICodeViewer)ctrlSourceViewer : (ICodeViewer)ctrlDebuggerCode;
|
||||
}
|
||||
|
||||
if(updateActiveAddress) {
|
||||
@ -487,10 +530,12 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
|
||||
ctrlDebuggerCode.SetActiveAddress(state.CPU.DebugPC);
|
||||
ctrlSourceViewer.SetActiveAddress(state.CPU.DebugPC);
|
||||
ctrlDebuggerCode.UpdateLineColors();
|
||||
|
||||
if(UpdateSplitView()) {
|
||||
ctrlDebuggerCodeSplit.SetActiveAddress(state.CPU.DebugPC);
|
||||
ctrlSourceViewerSplit.SetActiveAddress(state.CPU.DebugPC);
|
||||
ctrlDebuggerCodeSplit.UpdateLineColors();
|
||||
}
|
||||
|
||||
@ -520,6 +565,9 @@ namespace Mesen.GUI.Debugger
|
||||
ctrlDebuggerCode.UpdateLineColors();
|
||||
ctrlDebuggerCodeSplit.ClearActiveAddress();
|
||||
ctrlDebuggerCodeSplit.UpdateLineColors();
|
||||
|
||||
ctrlSourceViewer.ClearActiveAddress();
|
||||
ctrlSourceViewerSplit.ClearActiveAddress();
|
||||
}
|
||||
|
||||
public void TogglePause()
|
||||
@ -534,7 +582,7 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
private void ToggleBreakpoint(bool toggleEnabled)
|
||||
{
|
||||
_lastCodeWindow.ToggleBreakpoint(toggleEnabled);
|
||||
_lastCodeWindow.CodeViewerActions.ToggleBreakpoint(toggleEnabled);
|
||||
}
|
||||
|
||||
private void ResumeExecution()
|
||||
@ -611,42 +659,88 @@ namespace Mesen.GUI.Debugger
|
||||
InteropEmu.DebugPpuStep(89341);
|
||||
}
|
||||
|
||||
private void ctrlDebuggerCode_OnScrollToAddress(ctrlDebuggerCode sender, AddressEventArgs args)
|
||||
private void ctrlDebuggerCode_OnShowInSplitView(ICodeViewer sender, AddressEventArgs args)
|
||||
{
|
||||
if(!ConfigManager.Config.DebugInfo.SplitView) {
|
||||
mnuSplitView.Checked = true;
|
||||
ConfigManager.Config.DebugInfo.SplitView = true;
|
||||
ConfigManager.ApplyChanges();
|
||||
UpdateDebugger(false);
|
||||
}
|
||||
|
||||
UInt16 addr = (UInt16)args.Address;
|
||||
if(sender == ctrlDebuggerCode) {
|
||||
if(!ConfigManager.Config.DebugInfo.SplitView) {
|
||||
mnuSplitView.Checked = true;
|
||||
ConfigManager.Config.DebugInfo.SplitView = true;
|
||||
ConfigManager.ApplyChanges();
|
||||
UpdateDebugger(false);
|
||||
if(sender == ctrlDebuggerCode || sender == ctrlSourceViewer) {
|
||||
if(ctrlSourceViewerSplit.Visible) {
|
||||
ctrlSourceViewerSplit.ScrollToLineNumber(addr);
|
||||
} else {
|
||||
ctrlDebuggerCodeSplit.ScrollToLineNumber(addr);
|
||||
}
|
||||
ctrlDebuggerCodeSplit.ScrollToLineNumber(addr);
|
||||
} else {
|
||||
ctrlDebuggerCode.ScrollToLineNumber(addr);
|
||||
if(ctrlSourceViewer.Visible) {
|
||||
ctrlSourceViewer.ScrollToLineNumber(addr);
|
||||
} else {
|
||||
ctrlDebuggerCode.ScrollToLineNumber(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ctrlDebuggerCode_OnSetNextStatement(ctrlDebuggerCode sender, AddressEventArgs args)
|
||||
private void ctrlDebuggerCode_OnSetNextStatement(AddressEventArgs args)
|
||||
{
|
||||
UInt16 addr = (UInt16)args.Address;
|
||||
InteropEmu.DebugSetNextStatement(addr);
|
||||
this.UpdateDebugger();
|
||||
}
|
||||
|
||||
private void ctrlDebuggerCode_OnSwitchView(ICodeViewer sender)
|
||||
{
|
||||
if(ctrlDebuggerCode == sender) {
|
||||
ctrlDebuggerCode.Visible = false;
|
||||
ctrlSourceViewer.Visible = true;
|
||||
if(ctrlDebuggerCode.CodeViewer.CurrentLine >= 0) {
|
||||
ctrlSourceViewer.ScrollToLineNumber(ctrlDebuggerCode.CodeViewer.CurrentLine);
|
||||
}
|
||||
ctrlSourceViewer.Focus();
|
||||
ctrlSourceViewer.SetConfig(ConfigManager.Config.DebugInfo.LeftView);
|
||||
} else if(ctrlSourceViewer == sender) {
|
||||
ctrlSourceViewer.Visible = false;
|
||||
ctrlDebuggerCode.Visible = true;
|
||||
if(ctrlDebuggerCode.CodeViewer.CurrentLine >= 0) {
|
||||
ctrlDebuggerCode.ScrollToLineNumber(ctrlDebuggerCode.CodeViewer.CurrentLine);
|
||||
}
|
||||
ctrlDebuggerCode.Focus();
|
||||
ctrlDebuggerCode.SetConfig(ConfigManager.Config.DebugInfo.LeftView);
|
||||
} else if(ctrlSourceViewerSplit == sender) {
|
||||
ctrlSourceViewerSplit.Visible = false;
|
||||
ctrlDebuggerCodeSplit.Visible = true;
|
||||
if(ctrlSourceViewerSplit.CodeViewer.CurrentLine >= 0) {
|
||||
ctrlDebuggerCodeSplit.ScrollToLineNumber(ctrlSourceViewerSplit.CodeViewer.CurrentLine);
|
||||
}
|
||||
ctrlDebuggerCodeSplit.Focus();
|
||||
ctrlDebuggerCodeSplit.SetConfig(ConfigManager.Config.DebugInfo.RightView);
|
||||
} else {
|
||||
ctrlDebuggerCodeSplit.Visible = false;
|
||||
ctrlSourceViewerSplit.Visible = true;
|
||||
if(ctrlDebuggerCodeSplit.CodeViewer.CurrentLine >= 0) {
|
||||
ctrlSourceViewerSplit.ScrollToLineNumber(ctrlDebuggerCodeSplit.CodeViewer.CurrentLine);
|
||||
}
|
||||
ctrlSourceViewerSplit.Focus();
|
||||
ctrlSourceViewerSplit.SetConfig(ConfigManager.Config.DebugInfo.RightView);
|
||||
}
|
||||
}
|
||||
|
||||
private void mnuFind_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow.OpenSearchBox();
|
||||
_lastCodeWindow.CodeViewer.OpenSearchBox();
|
||||
}
|
||||
|
||||
private void mnuFindNext_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow.FindNext();
|
||||
_lastCodeWindow.CodeViewer.FindNext();
|
||||
}
|
||||
|
||||
private void mnuFindPrev_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow.FindPrevious();
|
||||
_lastCodeWindow.CodeViewer.FindPrevious();
|
||||
}
|
||||
|
||||
private void mnuSplitView_Click(object sender, EventArgs e)
|
||||
@ -671,21 +765,19 @@ namespace Mesen.GUI.Debugger
|
||||
{
|
||||
ctrlDebuggerCodeSplit.UpdateLineColors();
|
||||
ctrlDebuggerCode.UpdateLineColors();
|
||||
|
||||
ctrlSourceViewer.RefreshViewer();
|
||||
ctrlSourceViewerSplit.RefreshViewer();
|
||||
}
|
||||
|
||||
private void ctrlDebuggerCode_Enter(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow = ctrlDebuggerCode;
|
||||
}
|
||||
|
||||
private void ctrlDebuggerCodeSplit_Enter(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow = ctrlDebuggerCodeSplit;
|
||||
_lastCodeWindow = (ICodeViewer)sender;
|
||||
}
|
||||
|
||||
private void mnuGoToAddress_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow.GoToAddress();
|
||||
_lastCodeWindow.CodeViewer.GoToAddress();
|
||||
}
|
||||
|
||||
private void mnuGoToIrqHandler_Click(object sender, EventArgs e)
|
||||
@ -708,24 +800,22 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
private void mnuGoToProgramCount_Click(object sender, EventArgs e)
|
||||
{
|
||||
DebugState state = new DebugState();
|
||||
InteropEmu.DebugGetState(ref state);
|
||||
_lastCodeWindow.ScrollToActiveAddress();
|
||||
_lastCodeWindow.CodeViewerActions.ScrollToActiveAddress();
|
||||
}
|
||||
|
||||
private void mnuIncreaseFontSize_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow.TextZoom += 10;
|
||||
_lastCodeWindow.CodeViewer.TextZoom += 10;
|
||||
}
|
||||
|
||||
private void mnuDecreaseFontSize_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow.TextZoom -= 10;
|
||||
_lastCodeWindow.CodeViewer.TextZoom -= 10;
|
||||
}
|
||||
|
||||
private void mnuResetFontSize_Click(object sender, EventArgs e)
|
||||
{
|
||||
_lastCodeWindow.TextZoom = 100;
|
||||
_lastCodeWindow.CodeViewer.TextZoom = 100;
|
||||
}
|
||||
|
||||
private void mnuClose_Click(object sender, EventArgs e)
|
||||
@ -755,9 +845,9 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
InteropEmu.DebugRun();
|
||||
|
||||
ConfigManager.Config.DebugInfo.FontFamily = ctrlDebuggerCode.BaseFont.FontFamily.Name;
|
||||
ConfigManager.Config.DebugInfo.FontStyle = ctrlDebuggerCode.BaseFont.Style;
|
||||
ConfigManager.Config.DebugInfo.FontSize = ctrlDebuggerCode.BaseFont.Size;
|
||||
ConfigManager.Config.DebugInfo.FontFamily = ctrlDebuggerCode.CodeViewer.BaseFont.FontFamily.Name;
|
||||
ConfigManager.Config.DebugInfo.FontStyle = ctrlDebuggerCode.CodeViewer.BaseFont.Style;
|
||||
ConfigManager.Config.DebugInfo.FontSize = ctrlDebuggerCode.CodeViewer.BaseFont.Size;
|
||||
ConfigManager.Config.DebugInfo.WindowWidth = this.WindowState == FormWindowState.Maximized ? this.RestoreBounds.Width : this.Width;
|
||||
ConfigManager.Config.DebugInfo.WindowHeight = this.WindowState == FormWindowState.Maximized ? this.RestoreBounds.Height : this.Height;
|
||||
ConfigManager.Config.DebugInfo.TopPanelHeight = this.splitContainer.GetSplitterDistance();
|
||||
@ -1034,8 +1124,7 @@ namespace Mesen.GUI.Debugger
|
||||
if(ext == ".mlb") {
|
||||
MesenLabelFile.Import(ofd.FileName);
|
||||
} else {
|
||||
Ld65DbgImporter dbgImporter = new Ld65DbgImporter();
|
||||
dbgImporter.Import(ofd.FileName);
|
||||
ImportDbgFile(ofd.FileName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1253,8 +1342,13 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
private void mnuCode_DropDownOpening(object sender, EventArgs e)
|
||||
{
|
||||
this._lastCodeWindow.UpdateContextMenuItemVisibility(false);
|
||||
mnuCode.DropDownItems.AddRange(this._lastCodeWindow.ContextMenuItems.ToArray());
|
||||
this._lastCodeWindow.CodeViewerActions.UpdateContextMenuItemVisibility(false);
|
||||
|
||||
List<ToolStripItem> items = new List<ToolStripItem>();
|
||||
foreach(ToolStripItem item in this._lastCodeWindow.CodeViewerActions.contextMenu.Items) {
|
||||
items.Add(item);
|
||||
}
|
||||
mnuCode.DropDownItems.AddRange(items.ToArray());
|
||||
}
|
||||
|
||||
private void mnuCode_DropDownClosed(object sender, EventArgs e)
|
||||
@ -1263,7 +1357,7 @@ namespace Mesen.GUI.Debugger
|
||||
foreach(ToolStripItem item in mnuCode.DropDownItems) {
|
||||
items.Add(item);
|
||||
}
|
||||
this._lastCodeWindow.ContextMenuItems = items;
|
||||
this._lastCodeWindow.CodeViewerActions.contextMenu.Items.AddRange(items.ToArray());
|
||||
}
|
||||
|
||||
private void mnuCdlStripUsedData_Click(object sender, EventArgs e)
|
||||
@ -1287,8 +1381,10 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
private void mnuSelectFont_Click(object sender, EventArgs e)
|
||||
{
|
||||
ctrlDebuggerCode.BaseFont = FontDialogHelper.SelectFont(ctrlDebuggerCode.Font);
|
||||
ctrlDebuggerCodeSplit.BaseFont = ctrlDebuggerCode.BaseFont;
|
||||
ctrlDebuggerCode.CodeViewer.BaseFont = FontDialogHelper.SelectFont(ctrlDebuggerCode.CodeViewer.BaseFont);
|
||||
ctrlDebuggerCodeSplit.CodeViewer.BaseFont = ctrlDebuggerCode.CodeViewer.BaseFont;
|
||||
ctrlSourceViewer.CodeViewer.BaseFont = ctrlDebuggerCode.CodeViewer.BaseFont;
|
||||
ctrlSourceViewerSplit.CodeViewer.BaseFont = ctrlDebuggerCode.CodeViewer.BaseFont;
|
||||
}
|
||||
|
||||
private void mnuPreferences_Click(object sender, EventArgs e)
|
||||
|
@ -165,13 +165,18 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowAddress(int address)
|
||||
public void ShowAddress(int address, bool usePrgRom)
|
||||
{
|
||||
tabMain.SelectedTab = tpgMemoryViewer;
|
||||
cboMemoryType.SelectedIndex = 0; //Select CPU Memory
|
||||
ctrlHexViewer.GoToAddress(address);
|
||||
if(usePrgRom) {
|
||||
cboMemoryType.SetEnumValue(DebugMemoryType.PrgRom);
|
||||
ctrlHexViewer.GoToAddress(address);
|
||||
} else {
|
||||
cboMemoryType.SetEnumValue(DebugMemoryType.CpuMemory);
|
||||
ctrlHexViewer.GoToAddress(address);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void InitTblMappings()
|
||||
{
|
||||
DebugWorkspace workspace = DebugWorkspaceManager.GetWorkspace();
|
||||
|
@ -323,6 +323,7 @@
|
||||
<Compile Include="Debugger\BreakpointManager.cs" />
|
||||
<Compile Include="Debugger\ChrByteColorProvider.cs" />
|
||||
<Compile Include="Debugger\ByteColorProvider.cs" />
|
||||
<Compile Include="Debugger\CodeTooltipManager.cs" />
|
||||
<Compile Include="Debugger\Controls\ApuViewer\ctrlEnvelopeInfo.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
@ -362,6 +363,12 @@
|
||||
<Compile Include="Debugger\Controls\BaseScrollableTextboxUserControl.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\CodeViewerActions.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\CodeViewerActions.Designer.cs">
|
||||
<DependentUpon>CodeViewerActions.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ComboBoxWithSeparator.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
@ -392,6 +399,12 @@
|
||||
<Compile Include="Debugger\Controls\ctrlDbgShortcuts.Designer.cs">
|
||||
<DependentUpon>ctrlDbgShortcuts.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlFindOccurrences.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlFindOccurrences.Designer.cs">
|
||||
<DependentUpon>ctrlFindOccurrences.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlFlagStatus.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
@ -438,6 +451,12 @@
|
||||
<Compile Include="Debugger\Controls\ctrlPaletteViewer.Designer.cs">
|
||||
<DependentUpon>ctrlPaletteViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlSourceViewer.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlSourceViewer.Designer.cs">
|
||||
<DependentUpon>ctrlSourceViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlSpriteViewer.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
@ -502,6 +521,7 @@
|
||||
<Compile Include="Debugger\Controls\ctrlWatch.Designer.cs">
|
||||
<DependentUpon>ctrlWatch.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ICodeViewer.cs" />
|
||||
<Compile Include="Debugger\ctrlPaletteDisplay.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
@ -599,6 +619,12 @@
|
||||
<Compile Include="Debugger\frmBreakOn.Designer.cs">
|
||||
<DependentUpon>frmBreakOn.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\frmCodePreviewTooltip.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\frmCodePreviewTooltip.Designer.cs">
|
||||
<DependentUpon>frmCodePreviewTooltip.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\frmDbgPreferences.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@ -1134,6 +1160,7 @@
|
||||
<Compile Include="ResourceManager.cs" />
|
||||
<Compile Include="RuntimeChecker.cs" />
|
||||
<Compile Include="SingleInstance.cs" />
|
||||
<None Include="Resources\SwitchView.png" />
|
||||
<None Include="Resources\SelectAll.png" />
|
||||
<None Include="Resources\Paste.png" />
|
||||
<None Include="Resources\EditLabel.png" />
|
||||
@ -1174,15 +1201,24 @@
|
||||
<EmbeddedResource Include="Debugger\Controls\ApuViewer\ctrlSquareInfo.resx">
|
||||
<DependentUpon>ctrlSquareInfo.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\CodeViewerActions.resx">
|
||||
<DependentUpon>CodeViewerActions.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlDbgShortcuts.resx">
|
||||
<DependentUpon>ctrlDbgShortcuts.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlFindOccurrences.resx">
|
||||
<DependentUpon>ctrlFindOccurrences.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlFlagStatus.resx">
|
||||
<DependentUpon>ctrlFlagStatus.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlEventViewerPpuView.resx">
|
||||
<DependentUpon>ctrlEventViewerPpuView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Controls\ctrlSourceViewer.resx">
|
||||
<DependentUpon>ctrlSourceViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Example.lua" />
|
||||
<None Include="Resources\PipetteSmall.png" />
|
||||
<None Include="Resources\Enum.png" />
|
||||
@ -1302,6 +1338,9 @@
|
||||
<EmbeddedResource Include="Debugger\frmBreakOn.resx">
|
||||
<DependentUpon>frmBreakOn.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\frmCodePreviewTooltip.resx">
|
||||
<DependentUpon>frmCodePreviewTooltip.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\frmDbgPreferences.resx">
|
||||
<DependentUpon>frmDbgPreferences.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
10
GUI.NET/Properties/Resources.Designer.cs
generated
10
GUI.NET/Properties/Resources.Designer.cs
generated
@ -890,6 +890,16 @@ namespace Mesen.GUI.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
internal static System.Drawing.Bitmap SwitchView {
|
||||
get {
|
||||
object obj = ResourceManager.GetObject("SwitchView", resourceCulture);
|
||||
return ((System.Drawing.Bitmap)(obj));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
|
@ -397,4 +397,7 @@
|
||||
<data name="SelectAll" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\SelectAll.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
<data name="SwitchView" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\SwitchView.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||
</data>
|
||||
</root>
|
BIN
GUI.NET/Resources/SwitchView.png
Normal file
BIN
GUI.NET/Resources/SwitchView.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 521 B |
Loading…
Reference in New Issue
Block a user