diff --git a/GUI.NET/Debugger/Controls/BaseScrollableTextboxUserControl.cs b/GUI.NET/Debugger/Controls/BaseScrollableTextboxUserControl.cs
index 79e8fd31..f1d53e76 100644
--- a/GUI.NET/Debugger/Controls/BaseScrollableTextboxUserControl.cs
+++ b/GUI.NET/Debugger/Controls/BaseScrollableTextboxUserControl.cs
@@ -9,14 +9,19 @@ using System.Windows.Forms;
namespace Mesen.GUI.Debugger.Controls
{
- public abstract class BaseScrollableTextboxUserControl : UserControl
+ public class BaseScrollableTextboxUserControl : UserControl
{
- protected abstract ctrlScrollableTextbox ScrollableTextbox
+ virtual protected ctrlScrollableTextbox ScrollableTextbox
{
- get;
+ get
+ {
+ return null;
+ }
}
[DefaultValue(13F)]
+ [Browsable(false)]
+ [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public float FontSize
{
get { return this.ScrollableTextbox.FontSize; }
@@ -57,10 +62,10 @@ namespace Mesen.GUI.Debugger.Controls
{
this.ScrollableTextbox.ScrollToLineNumber(0);
}
-
- public string GetWordUnderLocation(Point position)
+
+ public string GetWordUnderLocation(Point position, bool useCompareText = false)
{
- return this.ScrollableTextbox.GetWordUnderLocation(position);
+ return this.ScrollableTextbox.GetWordUnderLocation(position, useCompareText);
}
}
}
diff --git a/GUI.NET/Debugger/Controls/ctrlDebuggerCode.cs b/GUI.NET/Debugger/Controls/ctrlDebuggerCode.cs
index 35230af0..31237edc 100644
--- a/GUI.NET/Debugger/Controls/ctrlDebuggerCode.cs
+++ b/GUI.NET/Debugger/Controls/ctrlDebuggerCode.cs
@@ -151,7 +151,9 @@ namespace Mesen.GUI.Debugger
UInt32 address = UInt32.Parse(word.Substring(1), System.Globalization.NumberStyles.AllowHexSpecifier);
Byte memoryValue = InteropEmu.DebugGetMemoryValue(address);
string valueText = "$" + memoryValue.ToString("X");
- toolTip.Show(valueText, ctrlCodeViewer, e.Location.X + 5, e.Location.Y + 5, 3000);
+ toolTip.Show(valueText, ctrlCodeViewer, e.Location.X + 5, e.Location.Y - 20, 3000);
+ } else {
+ toolTip.Hide(ctrlCodeViewer);
}
_previousLocation = e.Location;
}
diff --git a/GUI.NET/Debugger/Controls/ctrlHexViewer.Designer.cs b/GUI.NET/Debugger/Controls/ctrlHexViewer.Designer.cs
index 0dd204c3..b582cda4 100644
--- a/GUI.NET/Debugger/Controls/ctrlHexViewer.Designer.cs
+++ b/GUI.NET/Debugger/Controls/ctrlHexViewer.Designer.cs
@@ -27,11 +27,13 @@
///
private void InitializeComponent()
{
+ this.components = new System.ComponentModel.Container();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+ this.ctrlDataViewer = new Mesen.GUI.Debugger.ctrlScrollableTextbox();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.lblNumberOfColumns = new System.Windows.Forms.Label();
this.cboNumberColumns = new System.Windows.Forms.ComboBox();
- this.ctrlDataViewer = new Mesen.GUI.Debugger.ctrlScrollableTextbox();
+ this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.tableLayoutPanel1.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout();
this.SuspendLayout();
@@ -51,6 +53,17 @@
this.tableLayoutPanel1.Size = new System.Drawing.Size(191, 109);
this.tableLayoutPanel1.TabIndex = 0;
//
+ // ctrlDataViewer
+ //
+ this.ctrlDataViewer.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.ctrlDataViewer.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.ctrlDataViewer.FontSize = 13F;
+ this.ctrlDataViewer.Location = new System.Drawing.Point(3, 30);
+ this.ctrlDataViewer.Name = "ctrlDataViewer";
+ this.ctrlDataViewer.Size = new System.Drawing.Size(185, 76);
+ this.ctrlDataViewer.TabIndex = 0;
+ this.ctrlDataViewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ctrlDataViewer_MouseMove);
+ //
// flowLayoutPanel1
//
this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
@@ -58,7 +71,7 @@
this.flowLayoutPanel1.Controls.Add(this.lblNumberOfColumns);
this.flowLayoutPanel1.Controls.Add(this.cboNumberColumns);
this.flowLayoutPanel1.Location = new System.Drawing.Point(27, 0);
- this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
+ this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(164, 27);
this.flowLayoutPanel1.TabIndex = 1;
@@ -89,16 +102,6 @@
this.cboNumberColumns.TabIndex = 1;
this.cboNumberColumns.SelectedIndexChanged += new System.EventHandler(this.cboNumberColumns_SelectedIndexChanged);
//
- // ctrlDataViewer
- //
- this.ctrlDataViewer.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
- this.ctrlDataViewer.Dock = System.Windows.Forms.DockStyle.Fill;
- this.ctrlDataViewer.FontSize = 13F;
- this.ctrlDataViewer.Location = new System.Drawing.Point(3, 30);
- this.ctrlDataViewer.Name = "ctrlDataViewer";
- this.ctrlDataViewer.Size = new System.Drawing.Size(185, 76);
- this.ctrlDataViewer.TabIndex = 0;
- //
// ctrlHexViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@@ -121,5 +124,6 @@
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Label lblNumberOfColumns;
private System.Windows.Forms.ComboBox cboNumberColumns;
+ private System.Windows.Forms.ToolTip toolTip;
}
}
diff --git a/GUI.NET/Debugger/Controls/ctrlHexViewer.cs b/GUI.NET/Debugger/Controls/ctrlHexViewer.cs
index 42e9a608..7ffa5df2 100644
--- a/GUI.NET/Debugger/Controls/ctrlHexViewer.cs
+++ b/GUI.NET/Debugger/Controls/ctrlHexViewer.cs
@@ -14,6 +14,8 @@ namespace Mesen.GUI.Debugger.Controls
{
public event EventHandler ColumnCountChanged;
+ private string[] _previousHexContent = null;
+ private int _currentColumnCount;
private byte[] _data;
public ctrlHexViewer()
@@ -36,11 +38,19 @@ namespace Mesen.GUI.Debugger.Controls
set
{
if(value != null) {
+ if(_currentColumnCount != this.ColumnCount) {
+ this._previousHexContent = null;
+ _currentColumnCount = this.ColumnCount;
+ }
+
this._data = value;
string[] hexContent;
int[] lineNumbers;
this.ArrayToHex(value, out hexContent, out lineNumbers);
+ this.ctrlDataViewer.CompareLines = _previousHexContent;
this.ctrlDataViewer.TextLines = hexContent;
+ _previousHexContent = hexContent;
+
this.ctrlDataViewer.LineNumbers = lineNumbers;
if(this.ColumnCount == 16) {
this.ctrlDataViewer.Header = "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F";
@@ -131,5 +141,21 @@ namespace Mesen.GUI.Debugger.Controls
this.Data = _data;
this.ctrlDataViewer.Focus();
}
+
+ Point _previousLocation;
+ private void ctrlDataViewer_MouseMove(object sender, MouseEventArgs e)
+ {
+ if(_previousLocation != e.Location) {
+ string currentWord = this.GetWordUnderLocation(e.Location, false);
+ string originalWord = this.GetWordUnderLocation(e.Location, true);
+
+ if(currentWord != originalWord) {
+ this.toolTip.Show("Previous Value: $" + originalWord + Environment.NewLine + "Current Value: $" + currentWord, this.ctrlDataViewer, e.Location.X + 5, e.Location.Y - 40, 3000);
+ } else {
+ this.toolTip.Hide(this.ctrlDataViewer);
+ }
+ _previousLocation = e.Location;
+ }
+ }
}
}
diff --git a/GUI.NET/Debugger/Controls/ctrlHexViewer.resx b/GUI.NET/Debugger/Controls/ctrlHexViewer.resx
index 1af7de15..8766f298 100644
--- a/GUI.NET/Debugger/Controls/ctrlHexViewer.resx
+++ b/GUI.NET/Debugger/Controls/ctrlHexViewer.resx
@@ -117,4 +117,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ 17, 17
+
\ No newline at end of file
diff --git a/GUI.NET/Debugger/Controls/ctrlScrollableTextbox.cs b/GUI.NET/Debugger/Controls/ctrlScrollableTextbox.cs
index 909e9ef4..d106c0b1 100644
--- a/GUI.NET/Debugger/Controls/ctrlScrollableTextbox.cs
+++ b/GUI.NET/Debugger/Controls/ctrlScrollableTextbox.cs
@@ -50,9 +50,9 @@ namespace Mesen.GUI.Debugger
}
}
- public string GetWordUnderLocation(Point position)
+ public string GetWordUnderLocation(Point position, bool useCompareText = false)
{
- return this.ctrlTextbox.GetWordUnderLocation(position);
+ return this.ctrlTextbox.GetWordUnderLocation(position, useCompareText);
}
private void ctrlTextbox_ScrollPositionChanged(object sender, EventArgs e)
@@ -170,6 +170,14 @@ namespace Mesen.GUI.Debugger
this.vScrollBar.Maximum = this.ctrlTextbox.LineCount + this.vScrollBar.LargeChange;
}
}
+
+ public string[] CompareLines
+ {
+ set
+ {
+ this.ctrlTextbox.CompareLines = value;
+ }
+ }
public int[] LineNumbers
{
diff --git a/GUI.NET/Debugger/Controls/ctrlTextbox.cs b/GUI.NET/Debugger/Controls/ctrlTextbox.cs
index 8b322652..0e0d4d33 100644
--- a/GUI.NET/Debugger/Controls/ctrlTextbox.cs
+++ b/GUI.NET/Debugger/Controls/ctrlTextbox.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
+using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -32,6 +33,7 @@ namespace Mesen.GUI.Debugger
public event EventHandler ScrollPositionChanged;
private string[] _contents = new string[0];
+ private string[] _compareContents = null;
private int[] _lineNumbers = new int[0];
private Dictionary _lineNumberIndex = new Dictionary();
private Dictionary _lineProperties = new Dictionary();
@@ -64,6 +66,14 @@ namespace Mesen.GUI.Debugger
}
}
+ public string[] CompareLines
+ {
+ set
+ {
+ _compareContents = value;
+ }
+ }
+
public int LineCount
{
get
@@ -209,39 +219,46 @@ namespace Mesen.GUI.Debugger
{
return this.ShowLineNumbers ? (int)(g.MeasureString("W", this.Font).Width * 6) : 0;
}
-
- public string GetWordUnderLocation(Point position)
+
+ private bool GetCharIndex(Point position, out int charIndex, out int lineIndex)
{
+ charIndex = -1;
using(Graphics g = Graphics.FromHwnd(this.Handle)) {
int marginLeft = this.GetMargin(g);
int positionX = position.X - marginLeft;
- int lineOffset = this.GetLineAtPosition(position.Y);
- if(positionX >= 0 && this.ScrollPosition + lineOffset < _contents.Length) {
- string text = _contents[this.ScrollPosition + lineOffset];
- int charIndex = -1;
+ lineIndex = this.ScrollPosition + this.GetLineAtPosition(position.Y);
+ if(positionX >= 0 && lineIndex < _contents.Length) {
+ string text = _contents[lineIndex];
int previousWidth = 0;
for(int i = 0, len = text.Length; i < len; i++) {
int width = (int)g.MeasureString(text.Substring(0, i+1), this.Font).Width;
if(width >= positionX && previousWidth <= positionX) {
charIndex = i;
- break;
+ return true;
}
previousWidth = width;
}
+ }
+ }
+ return false;
+ }
- if(charIndex >= 0) {
- List wordDelimiters = new List(new char[] { ' ', ',' });
- if(wordDelimiters.Contains(text[charIndex])) {
- return string.Empty;
- } else {
- int endIndex = text.IndexOfAny(wordDelimiters.ToArray(), charIndex);
- if(endIndex == -1) {
- endIndex = text.Length;
- }
- int startIndex = text.LastIndexOfAny(wordDelimiters.ToArray(), charIndex);
- return text.Substring(startIndex + 1, endIndex - startIndex - 1);
- }
+ public string GetWordUnderLocation(Point position, bool useCompareText = false)
+ {
+ int charIndex;
+ int lineIndex;
+ if(this.GetCharIndex(position, out charIndex, out lineIndex)) {
+ string text = (useCompareText && _compareContents != null) ? _compareContents[lineIndex] : _contents[lineIndex];
+ List wordDelimiters = new List(new char[] { ' ', ',' });
+ if(wordDelimiters.Contains(text[charIndex])) {
+ return string.Empty;
+ } else {
+ int endIndex = text.IndexOfAny(wordDelimiters.ToArray(), charIndex);
+ if(endIndex == -1) {
+ endIndex = text.Length;
}
+ int startIndex = text.LastIndexOfAny(wordDelimiters.ToArray(), charIndex);
+ return text.Substring(startIndex + 1, endIndex - startIndex - 1);
}
}
return string.Empty;
@@ -401,29 +418,58 @@ namespace Mesen.GUI.Debugger
string lineText = _contents[currentLine];
using(Brush fgBrush = new SolidBrush(textColor)) {
g.DrawString(lineText, this.Font, fgBrush, marginLeft, positionY);
+ this.DrawHighlightedSearchString(g, lineText, marginLeft, positionY);
+ this.DrawHighlightedCompareString(g, lineText, currentLine, marginLeft, positionY);
+ }
+ }
- int searchIndex;
- if(!string.IsNullOrWhiteSpace(this._searchString) && (searchIndex = lineText.ToLowerInvariant().IndexOf(this._searchString)) >= 0) {
- //Draw colored search string
- int previousSearchIndex = -this._searchString.Length;
+ private void DrawHighlightedCompareString(Graphics g, string lineText, int currentLine, int marginLeft, int positionY)
+ {
+ if(_compareContents != null && _compareContents.Length > currentLine) {
+ string compareText = _compareContents[currentLine];
+
+ if(compareText != lineText) {
StringBuilder sb = new StringBuilder();
- do {
- sb.Append(string.Empty.PadLeft(searchIndex - previousSearchIndex - this._searchString.Length));
- sb.Append(lineText.Substring(searchIndex, this._searchString.Length));
-
- previousSearchIndex = searchIndex;
- searchIndex = lineText.ToLowerInvariant().IndexOf(this._searchString, searchIndex + this._searchString.Length);
- } while(searchIndex >= 0);
-
- string drawSearchString = sb.ToString();
- using(Brush selBrush = new SolidBrush(Color.White), selBgBrush = new SolidBrush(Color.CornflowerBlue)) {
- for(int i = -2; i <= 2; i++) {
- for(int j = -2; j <= 2; j++) {
- g.DrawString(drawSearchString, this.Font, selBgBrush, marginLeft + i, positionY + j);
- }
+ for(int i = 0, len = lineText.Length; i < len; i++) {
+ if(lineText[i] == compareText[i]) {
+ sb.Append(" ");
+ } else {
+ sb.Append(lineText[i]);
}
- g.DrawString(drawSearchString, this.Font, selBrush, marginLeft, positionY);
}
+
+ g.DrawString(sb.ToString(), new Font(this.Font, FontStyle.Bold), Brushes.Red, marginLeft, positionY);
+ }
+ }
+ }
+
+ private void DrawHighlightedSearchString(Graphics g, string lineText, int marginLeft, int positionY)
+ {
+ int searchIndex;
+ if(!string.IsNullOrWhiteSpace(this._searchString) && (searchIndex = lineText.ToLowerInvariant().IndexOf(this._searchString)) >= 0) {
+ //Draw colored search string
+ int previousSearchIndex = -this._searchString.Length;
+ string lowerCaseText = lineText.ToLowerInvariant();
+ StringBuilder sb = new StringBuilder();
+ StringBuilder sbBackground = new StringBuilder();
+ do {
+ sb.Append(string.Empty.PadLeft(searchIndex - previousSearchIndex - this._searchString.Length));
+ sbBackground.Append(string.Empty.PadLeft(searchIndex - previousSearchIndex - this._searchString.Length));
+
+ sb.Append(lineText.Substring(searchIndex, this._searchString.Length));
+ sbBackground.Append(string.Empty.PadLeft(this._searchString.Length, '█'));
+
+ previousSearchIndex = searchIndex;
+ searchIndex = lowerCaseText.IndexOf(this._searchString, searchIndex + this._searchString.Length);
+ } while(searchIndex >= 0);
+
+ string drawSearchString = sb.ToString();
+ string drawSearchStringBg = sbBackground.ToString();
+
+ using(Brush selBrush = new SolidBrush(Color.White), selBgBrush = new SolidBrush(Color.CornflowerBlue)) {
+ g.DrawString(drawSearchStringBg, this.Font, selBgBrush, marginLeft-1, positionY);
+ g.DrawString(drawSearchStringBg, this.Font, selBgBrush, marginLeft+1, positionY);
+ g.DrawString(drawSearchString, this.Font, selBrush, marginLeft, positionY);
}
}
}
diff --git a/GUI.NET/Debugger/frmMemoryViewer.Designer.cs b/GUI.NET/Debugger/frmMemoryViewer.Designer.cs
index bf8cab7d..a74cb662 100644
--- a/GUI.NET/Debugger/frmMemoryViewer.Designer.cs
+++ b/GUI.NET/Debugger/frmMemoryViewer.Designer.cs
@@ -44,6 +44,8 @@
this.mnuIncreaseFontSize = new System.Windows.Forms.ToolStripMenuItem();
this.mnuDecreaseFontSize = new System.Windows.Forms.ToolStripMenuItem();
this.mnuResetFontSize = new System.Windows.Forms.ToolStripMenuItem();
+ this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
+ this.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFind = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem();
@@ -130,14 +132,15 @@
//
this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuRefresh,
- this.fontSizeToolStripMenuItem});
+ this.fontSizeToolStripMenuItem,
+ this.toolStripMenuItem2,
+ this.mnuAutoRefresh});
this.mnuView.Name = "mnuView";
this.mnuView.Size = new System.Drawing.Size(44, 20);
this.mnuView.Text = "View";
//
// mnuRefresh
//
- this.mnuRefresh.CheckOnClick = true;
this.mnuRefresh.Name = "mnuRefresh";
this.mnuRefresh.ShortcutKeys = System.Windows.Forms.Keys.F5;
this.mnuRefresh.Size = new System.Drawing.Size(152, 22);
@@ -181,6 +184,20 @@
this.mnuResetFontSize.Text = "Reset to Default";
this.mnuResetFontSize.Click += new System.EventHandler(this.mnuResetFontSize_Click);
//
+ // toolStripMenuItem2
+ //
+ this.toolStripMenuItem2.Name = "toolStripMenuItem2";
+ this.toolStripMenuItem2.Size = new System.Drawing.Size(149, 6);
+ //
+ // mnuAutoRefresh
+ //
+ this.mnuAutoRefresh.Checked = true;
+ this.mnuAutoRefresh.CheckOnClick = true;
+ this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.mnuAutoRefresh.Name = "mnuAutoRefresh";
+ this.mnuAutoRefresh.Size = new System.Drawing.Size(152, 22);
+ this.mnuAutoRefresh.Text = "Auto-refresh";
+ //
// toolStripMenuItem1
//
this.toolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -265,5 +282,7 @@
private System.Windows.Forms.ToolStripMenuItem mnuResetFontSize;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuClose;
+ private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
+ private System.Windows.Forms.ToolStripMenuItem mnuAutoRefresh;
}
}
\ No newline at end of file
diff --git a/GUI.NET/Debugger/frmMemoryViewer.cs b/GUI.NET/Debugger/frmMemoryViewer.cs
index 6017550c..8042c6e6 100644
--- a/GUI.NET/Debugger/frmMemoryViewer.cs
+++ b/GUI.NET/Debugger/frmMemoryViewer.cs
@@ -14,10 +14,16 @@ namespace Mesen.GUI.Debugger
public partial class frmMemoryViewer : BaseForm
{
private InteropEmu.NotificationListener _notifListener;
+ private int _autoRefreshCounter = 0;
public frmMemoryViewer()
{
InitializeComponent();
+ }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
this.cboMemoryType.SelectedIndex = 0;
this.Size = new Size(this.ctrlHexViewer.IdealWidth, this.Height);
@@ -30,6 +36,13 @@ namespace Mesen.GUI.Debugger
{
if(e.NotificationType == InteropEmu.ConsoleNotificationType.CodeBreak) {
this.BeginInvoke((MethodInvoker)(() => this.RefreshData()));
+ } else if(e.NotificationType == InteropEmu.ConsoleNotificationType.PpuFrameDone) {
+ this.BeginInvoke((MethodInvoker)(() => {
+ if(_autoRefreshCounter % 4 == 0 && this.mnuAutoRefresh.Checked) {
+ this.RefreshData();
+ }
+ _autoRefreshCounter++;
+ }));
}
}
diff --git a/GUI.NET/Debugger/frmPpuViewer.cs b/GUI.NET/Debugger/frmPpuViewer.cs
index 416d022a..43e6751d 100644
--- a/GUI.NET/Debugger/frmPpuViewer.cs
+++ b/GUI.NET/Debugger/frmPpuViewer.cs
@@ -16,6 +16,7 @@ namespace Mesen.GUI.Debugger
public partial class frmPpuViewer : BaseForm
{
private InteropEmu.NotificationListener _notifListener;
+ private int _autoRefreshCounter = 0;
public frmPpuViewer()
{
@@ -61,9 +62,10 @@ namespace Mesen.GUI.Debugger
private void AutoRefresh()
{
- if(mnuAutoRefresh.Checked) {
+ if(_autoRefreshCounter % 4 == 0 && this.mnuAutoRefresh.Checked) {
this.RefreshViewers();
}
+ _autoRefreshCounter++;
}
private void mnuRefresh_Click(object sender, EventArgs e)