Debugger - Wrote custom textbox for the display + Basic breakpoints (exec/read/write)

This commit is contained in:
Souryo 2015-08-02 19:27:02 -04:00
parent dffc03ad68
commit e7275cb3f7
31 changed files with 1818 additions and 572 deletions

View file

@ -45,6 +45,9 @@ struct State
uint8_t PS = 0;
uint32_t IRQFlag = 0;
bool NMIFlag = false;
//Used by debugger
uint16_t DebugPC = 0;
};
class CPU : public Snapshotable
@ -79,6 +82,7 @@ private:
uint8_t GetOPCode()
{
_state.DebugPC = _state.PC;
uint8_t opCode = MemoryRead(_state.PC, true);
_state.PC++;
return opCode;

View file

@ -36,7 +36,7 @@ Debugger::~Debugger()
Console::Resume();
}
void Debugger::AddBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr)
void Debugger::AddBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr, bool enabled)
{
_bpLock.Acquire();
@ -45,6 +45,7 @@ void Debugger::AddBreakpoint(BreakpointType type, uint32_t address, bool isAbsol
}
shared_ptr<Breakpoint> breakpoint(new Breakpoint(type, address, isAbsoluteAddr));
breakpoint->SetEnabled(enabled);
switch(type) {
case BreakpointType::Execute: _execBreakpoints.push_back(breakpoint); break;
case BreakpointType::Read: _readBreakpoints.push_back(breakpoint); break;
@ -54,55 +55,26 @@ void Debugger::AddBreakpoint(BreakpointType type, uint32_t address, bool isAbsol
_bpLock.Release();
}
vector<shared_ptr<Breakpoint>> Debugger::GetBreakpoints()
{
vector<shared_ptr<Breakpoint>> breakpoints;
breakpoints.insert(breakpoints.end(), _execBreakpoints.begin(), _execBreakpoints.end());
breakpoints.insert(breakpoints.end(), _readBreakpoints.begin(), _readBreakpoints.end());
breakpoints.insert(breakpoints.end(), _writeBreakpoints.begin(), _writeBreakpoints.end());
return breakpoints;
}
vector<uint32_t> Debugger::GetExecBreakpointAddresses()
void Debugger::RemoveBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr)
{
_bpLock.Acquire();
vector<uint32_t> result;
for(size_t i = 0, len = _execBreakpoints.size(); i < len; i++) {
shared_ptr<Breakpoint> breakpoint = _execBreakpoints[i];
int32_t addr = breakpoint->GetAddr();
if(breakpoint->IsAbsoluteAddr()) {
addr = _mapper->FromAbsoluteAddress(addr);
}
if(addr >= 0) {
result.push_back(addr);
}
vector<shared_ptr<Breakpoint>> *breakpoints = nullptr;
switch(type) {
case BreakpointType::Execute: breakpoints = &_execBreakpoints; break;
case BreakpointType::Read: breakpoints = &_readBreakpoints; break;
case BreakpointType::Write: breakpoints = &_writeBreakpoints; break;
}
_bpLock.Release();
return result;
}
void Debugger::RemoveBreakpoint(shared_ptr<Breakpoint> breakpoint)
{
_bpLock.Acquire();
for(size_t i = 0, len = _execBreakpoints.size(); i < len; i++) {
if(_execBreakpoints[i] == breakpoint) {
_execBreakpoints.erase(_execBreakpoints.begin()+i);
shared_ptr<Breakpoint> breakpoint = GetMatchingBreakpoint(type, address);
for(size_t i = 0, len = breakpoints->size(); i < len; i++) {
shared_ptr<Breakpoint> breakpoint = (*breakpoints)[i];
if(breakpoint->GetAddr() == address && breakpoint->IsAbsoluteAddr() == isAbsoluteAddr) {
breakpoints->erase(breakpoints->begin() + i);
break;
}
}
_bpLock.Release();
//_readBreakpoints.remove(breakpoint);
//_writeBreakpoints.remove(breakpoint);
}
shared_ptr<Breakpoint> Debugger::GetMatchingBreakpoint(BreakpointType type, uint32_t addr)

View file

@ -46,15 +46,15 @@ private:
private:
void PrivateCheckBreakpoint(BreakpointType type, uint32_t addr);
shared_ptr<Breakpoint> GetMatchingBreakpoint(BreakpointType type, uint32_t addr);
bool SleepUntilResume();
public:
Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<PPU> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseMapper> mapper);
~Debugger();
void AddBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr);
void RemoveBreakpoint(shared_ptr<Breakpoint> breakpoint);
shared_ptr<Breakpoint> GetMatchingBreakpoint(BreakpointType type, uint32_t addr);
void AddBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr, bool enabled);
void RemoveBreakpoint(BreakpointType type, uint32_t address, bool isAbsoluteAddr);
vector<shared_ptr<Breakpoint>> GetBreakpoints();
vector<uint32_t> GetExecBreakpointAddresses();

View file

@ -9,91 +9,33 @@ using System.Windows.Forms;
namespace Mesen.GUI.Controls
{
//Code adapted from:
//http://blogs.msdn.com/b/hippietim/archive/2006/03/27/562256.aspx
class MyListView : ListView
{
private bool m_doubleClickDoesCheck = true; // maintain the default behavior
private bool m_inDoubleClickCheckHack = false;
private bool preventCheck = false;
//****************************************************************************************
// This function helps us overcome the problem with the managed listview wrapper wanting
// to turn double-clicks on checklist items into checkbox clicks. We count on the fact
// that the base handler for NM_DBLCLK will send a hit test request back at us right away.
// So we set a special flag to return a bogus hit test result in that case.
//****************************************************************************************
private void OnWmReflectNotify(ref Message m)
protected override void OnItemCheck(ItemCheckEventArgs e)
{
if(!DoubleClickDoesCheck && CheckBoxes) {
NativeMethods.NMHDR nmhdr = (NativeMethods.NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NativeMethods.NMHDR));
if(nmhdr.code == NativeMethods.NM_DBLCLK) {
m_inDoubleClickCheckHack = true;
}
}
if(this.preventCheck) {
e.NewValue = e.CurrentValue;
this.preventCheck = false;
} else
base.OnItemCheck(e);
}
protected override void WndProc(ref Message m)
protected override void OnMouseDown(MouseEventArgs e)
{
switch(m.Msg) {
// This code is to hack around the fact that the managed listview
// wrapper translates double clicks into checks without giving the
// host to participate.
// See OnWmReflectNotify() for more details.
case NativeMethods.WM_REFLECT + NativeMethods.WM_NOTIFY:
OnWmReflectNotify(ref m);
break;
// This code checks to see if we have entered our hack check for
// double clicking items in check lists. During the NM_DBLCLK
// processing, the managed handler will send a hit test message
// to see which item to check. Returning -1 will convince that
// code not to proceed.
case NativeMethods.LVM_HITTEST:
if(m_inDoubleClickCheckHack) {
m_inDoubleClickCheckHack = false;
m.Result = (System.IntPtr)(-1);
return;
}
break;
if(e.Button == MouseButtons.Left && e.Clicks > 1) {
this.preventCheck = true;
} else {
this.preventCheck = false;
}
base.WndProc(ref m);
base.OnMouseDown(e);
}
[Browsable(true),
Description("When CheckBoxes is true, this controls whether or not double clicking will toggle the check."),
Category("My Controls"),
DefaultValue(true)]
public bool DoubleClickDoesCheck
protected override void OnKeyDown(KeyEventArgs e)
{
get
{
return m_doubleClickDoesCheck;
}
set
{
m_doubleClickDoesCheck = value;
}
this.preventCheck = false;
base.OnKeyDown(e);
}
}
public class NativeMethods
{
public const int WM_USER = 0x0400;
public const int WM_REFLECT = WM_USER + 0x1C00;
public const int WM_NOTIFY = 0x004E;
public const int LVM_HITTEST = (0x1000 + 18);
public const int NM_DBLCLK = (-3);
[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr hwndFrom;
public UIntPtr idFrom;
public int code;
}
}
}

View file

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mesen.GUI.Debugger
{
public class Breakpoint
{
private bool _added = false;
public BreakpointType Type;
public bool Enabled = true;
public UInt32 Address;
public bool IsAbsoluteAddress;
public void Remove()
{
if(_added) {
InteropEmu.DebugRemoveBreakpoint(Type, Address, false);
}
}
public void Add()
{
InteropEmu.DebugAddBreakpoint(Type, Address, false, Enabled);
_added = true;
}
public void SetEnabled(bool enabled)
{
Enabled = enabled;
Remove();
Add();
}
}
}

View file

@ -0,0 +1,130 @@
namespace Mesen.GUI.Debugger.Controls
{
partial class ctrlBreakpoints
{
/// <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.contextMenuBreakpoints = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuAddBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRemoveBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
this.lstBreakpoints = new Mesen.GUI.Controls.MyListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.colLastColumn = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.contextMenuBreakpoints.SuspendLayout();
this.SuspendLayout();
//
// contextMenuBreakpoints
//
this.contextMenuBreakpoints.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAddBreakpoint,
this.mnuRemoveBreakpoint});
this.contextMenuBreakpoints.Name = "contextMenuWatch";
this.contextMenuBreakpoints.Size = new System.Drawing.Size(142, 48);
this.contextMenuBreakpoints.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuBreakpoints_Opening);
//
// mnuAddBreakpoint
//
this.mnuAddBreakpoint.Name = "mnuAddBreakpoint";
this.mnuAddBreakpoint.Size = new System.Drawing.Size(141, 22);
this.mnuAddBreakpoint.Text = "Add...";
this.mnuAddBreakpoint.Click += new System.EventHandler(this.mnuAddBreakpoint_Click);
//
// mnuRemoveBreakpoint
//
this.mnuRemoveBreakpoint.Name = "mnuRemoveBreakpoint";
this.mnuRemoveBreakpoint.ShortcutKeys = System.Windows.Forms.Keys.Delete;
this.mnuRemoveBreakpoint.Size = new System.Drawing.Size(141, 22);
this.mnuRemoveBreakpoint.Text = "Remove";
this.mnuRemoveBreakpoint.Click += new System.EventHandler(this.mnuRemoveBreakpoint_Click);
//
// lstBreakpoints
//
this.lstBreakpoints.CheckBoxes = true;
this.lstBreakpoints.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader3,
this.columnHeader1,
this.columnHeader2,
this.colLastColumn});
this.lstBreakpoints.ContextMenuStrip = this.contextMenuBreakpoints;
this.lstBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstBreakpoints.FullRowSelect = true;
this.lstBreakpoints.GridLines = true;
this.lstBreakpoints.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
this.lstBreakpoints.Location = new System.Drawing.Point(0, 0);
this.lstBreakpoints.Name = "lstBreakpoints";
this.lstBreakpoints.Size = new System.Drawing.Size(393, 101);
this.lstBreakpoints.TabIndex = 7;
this.lstBreakpoints.UseCompatibleStateImageBehavior = false;
this.lstBreakpoints.View = System.Windows.Forms.View.Details;
this.lstBreakpoints.ColumnWidthChanged += new System.Windows.Forms.ColumnWidthChangedEventHandler(this.lstBreakpoints_ColumnWidthChanged);
this.lstBreakpoints.ColumnWidthChanging += new System.Windows.Forms.ColumnWidthChangingEventHandler(this.lstBreakpoints_ColumnWidthChanging);
this.lstBreakpoints.DoubleClick += new System.EventHandler(this.lstBreakpoints_DoubleClick);
//
// columnHeader1
//
this.columnHeader1.Text = "Type";
this.columnHeader1.Width = 70;
//
// columnHeader2
//
this.columnHeader2.Text = "Address";
this.columnHeader2.Width = 100;
//
// colLastColumn
//
this.colLastColumn.Text = "";
//
// columnHeader3
//
this.columnHeader3.Text = "Enabled";
//
// ctrlBreakpoints
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.lstBreakpoints);
this.Name = "ctrlBreakpoints";
this.Size = new System.Drawing.Size(393, 101);
this.contextMenuBreakpoints.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private Mesen.GUI.Controls.MyListView lstBreakpoints;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ColumnHeader colLastColumn;
private System.Windows.Forms.ContextMenuStrip contextMenuBreakpoints;
private System.Windows.Forms.ToolStripMenuItem mnuAddBreakpoint;
private System.Windows.Forms.ToolStripMenuItem mnuRemoveBreakpoint;
private System.Windows.Forms.ColumnHeader columnHeader3;
}
}

View file

@ -0,0 +1,156 @@
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;
namespace Mesen.GUI.Debugger.Controls
{
public partial class ctrlBreakpoints : UserControl
{
public event EventHandler BreakpointChanged;
private List<Breakpoint> _breakpoints = new List<Breakpoint>();
public ctrlBreakpoints()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
AdjustColumnWidth();
}
public void ToggleBreakpoint(int address)
{
if(address >= 0) {
Breakpoint breakpoint = GetMatchingBreakpoint(address);
if(breakpoint != null) {
_breakpoints.Remove(breakpoint);
breakpoint.Remove();
} else {
breakpoint = new Breakpoint() {
Type = BreakpointType.Execute,
Address = (UInt32)address,
IsAbsoluteAddress = false,
Enabled = true
};
_breakpoints.Add(breakpoint);
breakpoint.Add();
}
RefreshList();
OnBreakpointChanged();
}
}
private Breakpoint GetMatchingBreakpoint(int address)
{
foreach(Breakpoint breakpoint in _breakpoints) {
if(breakpoint.Address == address) {
return breakpoint;
}
}
return null;
}
public List<Breakpoint> GetBreakpoints()
{
return _breakpoints;
}
private void RefreshList()
{
lstBreakpoints.ItemChecked -= new System.Windows.Forms.ItemCheckedEventHandler(lstBreakpoints_ItemChecked);
lstBreakpoints.Items.Clear();
foreach(Breakpoint breakpoint in _breakpoints) {
ListViewItem item = new ListViewItem();
item.Tag = breakpoint;
item.Checked = breakpoint.Enabled;
item.SubItems.Add(breakpoint.Type.ToString());
item.SubItems.Add("$" + breakpoint.Address.ToString("X"));
lstBreakpoints.Items.Add(item);
}
lstBreakpoints.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(lstBreakpoints_ItemChecked);
}
private void lstBreakpoints_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e)
{
if(e.ColumnIndex == 2) {
e.Cancel = true;
}
AdjustColumnWidth();
}
private void lstBreakpoints_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
{
AdjustColumnWidth();
}
private void AdjustColumnWidth()
{
lstBreakpoints.ColumnWidthChanging -= lstBreakpoints_ColumnWidthChanging;
lstBreakpoints.ColumnWidthChanged -= lstBreakpoints_ColumnWidthChanged;
//Force watch values to take the full width of the list
int totalWidth = lstBreakpoints.Columns[0].Width + lstBreakpoints.Columns[1].Width + lstBreakpoints.Columns[2].Width;
colLastColumn.Width = lstBreakpoints.ClientSize.Width - totalWidth;
lstBreakpoints.ColumnWidthChanging += lstBreakpoints_ColumnWidthChanging;
lstBreakpoints.ColumnWidthChanged += lstBreakpoints_ColumnWidthChanged;
}
private void OnBreakpointChanged()
{
if(BreakpointChanged != null) {
BreakpointChanged(this, null);
}
}
private void lstBreakpoints_ItemChecked(object sender, ItemCheckedEventArgs e)
{
if(((Breakpoint)e.Item.Tag).Enabled != e.Item.Checked) {
((Breakpoint)e.Item.Tag).SetEnabled(e.Item.Checked);
OnBreakpointChanged();
}
}
private void lstBreakpoints_DoubleClick(object sender, EventArgs e)
{
if(lstBreakpoints.SelectedItems.Count > 0) {
new frmBreakpoint(((Breakpoint)lstBreakpoints.SelectedItems[0].Tag)).ShowDialog();
RefreshList();
OnBreakpointChanged();
}
}
private void mnuRemoveBreakpoint_Click(object sender, EventArgs e)
{
foreach(ListViewItem item in lstBreakpoints.SelectedItems) {
((Breakpoint)item.Tag).Remove();
_breakpoints.Remove((Breakpoint)item.Tag);
}
RefreshList();
OnBreakpointChanged();
}
private void mnuAddBreakpoint_Click(object sender, EventArgs e)
{
Breakpoint breakpoint = new Breakpoint();
if(new frmBreakpoint(breakpoint).ShowDialog() == DialogResult.OK) {
_breakpoints.Add(breakpoint);
RefreshList();
OnBreakpointChanged();
}
}
private void contextMenuBreakpoints_Opening(object sender, CancelEventArgs e)
{
mnuRemoveBreakpoint.Enabled = (lstBreakpoints.SelectedItems.Count > 0);
}
}
}

View 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="contextMenuBreakpoints.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -28,8 +28,6 @@
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tableLayoutPanel11 = new System.Windows.Forms.TableLayoutPanel();
this.txtCode = new Mesen.GUI.Debugger.ctrlSyncTextBox();
this.contextMenuCode = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuShowNextStatement = new System.Windows.Forms.ToolStripMenuItem();
this.mnuSetNextStatement = new System.Windows.Forms.ToolStripMenuItem();
@ -37,50 +35,12 @@
this.mnuShowOnlyDisassembledCode = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
this.mnuGoToLocation = new System.Windows.Forms.ToolStripMenuItem();
this.panel1 = new System.Windows.Forms.Panel();
this.txtCodeMargin = new Mesen.GUI.Debugger.ctrlSyncTextBox();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.mnuAddToWatch = new System.Windows.Forms.ToolStripMenuItem();
this.tableLayoutPanel11.SuspendLayout();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.ctrlCodeViewer = new Mesen.GUI.Debugger.ctrlScrollableTextbox();
this.contextMenuCode.SuspendLayout();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel11
//
this.tableLayoutPanel11.CellBorderStyle = System.Windows.Forms.TableLayoutPanelCellBorderStyle.Single;
this.tableLayoutPanel11.ColumnCount = 2;
this.tableLayoutPanel11.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 74F));
this.tableLayoutPanel11.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel11.Controls.Add(this.txtCode, 1, 0);
this.tableLayoutPanel11.Controls.Add(this.panel1, 0, 0);
this.tableLayoutPanel11.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel11.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel11.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel11.Name = "tableLayoutPanel11";
this.tableLayoutPanel11.RowCount = 1;
this.tableLayoutPanel11.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel11.Size = new System.Drawing.Size(379, 218);
this.tableLayoutPanel11.TabIndex = 3;
//
// txtCode
//
this.txtCode.BackColor = System.Drawing.Color.White;
this.txtCode.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.txtCode.ContextMenuStrip = this.contextMenuCode;
this.txtCode.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtCode.Font = new System.Drawing.Font("Consolas", 11F);
this.txtCode.Location = new System.Drawing.Point(76, 1);
this.txtCode.Margin = new System.Windows.Forms.Padding(0);
this.txtCode.Name = "txtCode";
this.txtCode.ReadOnly = true;
this.txtCode.Size = new System.Drawing.Size(302, 216);
this.txtCode.SyncedTextbox = null;
this.txtCode.TabIndex = 0;
this.txtCode.Text = "";
this.txtCode.MouseMove += new System.Windows.Forms.MouseEventHandler(this.txtCode_MouseMove);
this.txtCode.MouseUp += new System.Windows.Forms.MouseEventHandler(this.txtCode_MouseUp);
//
// contextMenuCode
//
this.contextMenuCode.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -92,7 +52,7 @@
this.mnuGoToLocation,
this.mnuAddToWatch});
this.contextMenuCode.Name = "contextMenuWatch";
this.contextMenuCode.Size = new System.Drawing.Size(259, 148);
this.contextMenuCode.Size = new System.Drawing.Size(259, 126);
this.contextMenuCode.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuCode_Opening);
//
// mnuShowNextStatement
@ -139,33 +99,6 @@
this.mnuGoToLocation.Text = "Go To Location";
this.mnuGoToLocation.Click += new System.EventHandler(this.mnuGoToLocation_Click);
//
// panel1
//
this.panel1.Controls.Add(this.txtCodeMargin);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(1, 1);
this.panel1.Margin = new System.Windows.Forms.Padding(0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(74, 216);
this.panel1.TabIndex = 1;
//
// txtCodeMargin
//
this.txtCodeMargin.BackColor = System.Drawing.Color.WhiteSmoke;
this.txtCodeMargin.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.txtCodeMargin.Dock = System.Windows.Forms.DockStyle.Left;
this.txtCodeMargin.Font = new System.Drawing.Font("Consolas", 11F);
this.txtCodeMargin.Location = new System.Drawing.Point(0, 0);
this.txtCodeMargin.Margin = new System.Windows.Forms.Padding(0);
this.txtCodeMargin.Name = "txtCodeMargin";
this.txtCodeMargin.ReadOnly = true;
this.txtCodeMargin.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.ForcedVertical;
this.txtCodeMargin.Size = new System.Drawing.Size(90, 216);
this.txtCodeMargin.SyncedTextbox = null;
this.txtCodeMargin.TabIndex = 1;
this.txtCodeMargin.Text = "";
this.txtCodeMargin.Enter += new System.EventHandler(this.txtCodeMargin_Enter);
//
// mnuAddToWatch
//
this.mnuAddToWatch.Name = "mnuAddToWatch";
@ -173,26 +106,31 @@
this.mnuAddToWatch.Text = "Add to Watch";
this.mnuAddToWatch.Click += new System.EventHandler(this.mnuAddToWatch_Click);
//
// ctrlCodeViewer
//
this.ctrlCodeViewer.ContextMenuStrip = this.contextMenuCode;
this.ctrlCodeViewer.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlCodeViewer.Location = new System.Drawing.Point(0, 0);
this.ctrlCodeViewer.Name = "ctrlCodeViewer";
this.ctrlCodeViewer.Size = new System.Drawing.Size(379, 218);
this.ctrlCodeViewer.TabIndex = 1;
this.ctrlCodeViewer.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ctrlCodeViewer_MouseUp);
this.ctrlCodeViewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ctrlCodeViewer_MouseMove);
//
// ctrlDebuggerCode
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel11);
this.Controls.Add(this.ctrlCodeViewer);
this.Name = "ctrlDebuggerCode";
this.Size = new System.Drawing.Size(379, 218);
this.tableLayoutPanel11.ResumeLayout(false);
this.contextMenuCode.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel11;
private ctrlSyncTextBox txtCode;
private System.Windows.Forms.Panel panel1;
private ctrlSyncTextBox txtCodeMargin;
private System.Windows.Forms.ToolTip toolTip;
private System.Windows.Forms.ContextMenuStrip contextMenuCode;
private System.Windows.Forms.ToolStripMenuItem mnuShowNextStatement;
@ -202,5 +140,6 @@
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem mnuGoToLocation;
private System.Windows.Forms.ToolStripMenuItem mnuAddToWatch;
private Mesen.GUI.Debugger.ctrlScrollableTextbox ctrlCodeViewer;
}
}

View file

@ -18,8 +18,6 @@ namespace Mesen.GUI.Debugger
public ctrlDebuggerCode()
{
InitializeComponent();
txtCode.SyncedTextbox = txtCodeMargin;
}
private string _code;
@ -32,6 +30,7 @@ namespace Mesen.GUI.Debugger
if(value != _code) {
_codeChanged = true;
_code = value;
UpdateCode();
}
}
}
@ -39,107 +38,46 @@ namespace Mesen.GUI.Debugger
private UInt32? _currentActiveAddress = null;
public void SelectActiveAddress(UInt32 address)
{
txtCode.BeginUpdate();
txtCodeMargin.BeginUpdate();
if(!UpdateCode()) {
RemoveActiveHighlight();
}
int lineIndex = GetAddressLine(address);
if(lineIndex >= 0) {
if(!IsLineVisible(lineIndex)) {
//Scroll active line to middle of viewport if it wasn't already visible
ScrollToLine(lineIndex);
}
//Set line background to yellow
HighlightLine(lineIndex, Color.Yellow, Color.Black);
}
txtCode.EndUpdate();
txtCodeMargin.EndUpdate();
this.SetActiveAddress(address);
this.ctrlCodeViewer.ScrollIntoView((int)address);
}
public void SetActiveAddress(UInt32 address)
{
//Set line background to yellow
this.ctrlCodeViewer.ClearLineStyles();
this.ctrlCodeViewer.SetLineColor((int)address, Color.Black, Color.Yellow, null, LineSymbol.None);
_currentActiveAddress = address;
}
public void RemoveActiveHighlight()
public void ClearActiveAddress()
{
//Didn't update code, need to remove previous highlighting
if(_currentActiveAddress.HasValue) {
int lineIndex = GetAddressLine(_currentActiveAddress.Value);
if(lineIndex != -1) {
HighlightLine(lineIndex, Color.White, Color.Black);
}
}
}
public int GetCurrentLine()
{
int cursorPos = txtCode.GetFirstCharIndexOfCurrentLine();
return txtCode.GetLineFromCharIndex(cursorPos);
}
public string GetWordUnderLocation(Point position)
{
int charIndex = txtCode.GetCharIndexFromPosition(position);
if(txtCode.Text.Length > charIndex) {
List<char> wordDelimiters = new List<char>(new char[] { ' ', '\r', '\n', ',' });
if(wordDelimiters.Contains(txtCode.Text[charIndex])) {
return string.Empty;
} else {
int endIndex = txtCode.Text.IndexOfAny(wordDelimiters.ToArray(), charIndex);
int startIndex = txtCode.Text.LastIndexOfAny(wordDelimiters.ToArray(), charIndex);
return txtCode.Text.Substring(startIndex + 1, endIndex - startIndex - 1);
}
} else {
return string.Empty;
}
_currentActiveAddress = null;
}
private int GetLineCount()
public string GetWordUnderLocation(Point position)
{
return (int)((float)txtCodeMargin.Height / (txtCodeMargin.Font.GetHeight() + 1)) - 1;
return this.ctrlCodeViewer.GetWordUnderLocation(position);
}
private void ScrollToAddress(UInt32 address)
{
int lineIndex = GetAddressLine(address);
if(lineIndex != -1 && !IsLineVisible(lineIndex)) {
ScrollToLine(lineIndex);
}
}
private void ScrollToLine(int lineIndex)
{
lineIndex = Math.Max(0, lineIndex - GetLineCount()/2);
txtCodeMargin.SelectionStart = txtCodeMargin.GetFirstCharIndexFromLine(lineIndex);
txtCodeMargin.ScrollToCaret();
txtCode.SelectionStart = txtCode.GetFirstCharIndexFromLine(lineIndex);
txtCode.ScrollToCaret();
}
private bool IsLineVisible(int lineIndex)
{
int firstLine = txtCodeMargin.GetLineFromCharIndex(txtCodeMargin.GetCharIndexFromPosition(new Point(0, 0)));
return lineIndex >= firstLine && lineIndex <= firstLine+GetLineCount();
}
public bool UpdateCode(bool forceUpdate = false)
{
if(_codeChanged || forceUpdate) {
StringBuilder lineNumbers = new StringBuilder();
StringBuilder codeString = new StringBuilder();
this.ctrlCodeViewer.ClearLineStyles();
List<int> lineNumbers = new List<int>();
List<string> codeLines = new List<string>();
bool diassembledCodeOnly = mnuShowOnlyDisassembledCode.Checked;
bool skippingCode = false;
foreach(string line in _code.Split('\n')) {
string[] lineParts = line.Split(':');
if(skippingCode && (lineParts.Length != 2 || lineParts[1][0] != '.')) {
lineNumbers.AppendLine(" .. ");
codeString.AppendLine("[code not disassembled]");
lineNumbers.Add(-1);
codeLines.Add("[code not disassembled]");
UInt32 previousAddress = lineParts[0].Length > 0 ? ParseHexAddress(lineParts[0])-1 : 0xFFFF;
lineNumbers.AppendLine(previousAddress.ToString("X"));
codeString.AppendLine("[code not disassembled]");
int previousAddress = lineParts[0].Length > 0 ? (int)ParseHexAddress(lineParts[0])-1 : 0xFFFF;
lineNumbers.Add(previousAddress);
codeLines.Add("[code not disassembled]");
skippingCode = false;
}
@ -147,21 +85,19 @@ namespace Mesen.GUI.Debugger
if(lineParts.Length == 2) {
if(diassembledCodeOnly && lineParts[1][0] == '.') {
if(!skippingCode) {
lineNumbers.AppendLine(lineParts[0]);
codeString.AppendLine("[code not disassembled]");
lineNumbers.Add((int)ParseHexAddress(lineParts[0]));
codeLines.Add("[code not disassembled]");
skippingCode = true;
}
} else {
lineNumbers.AppendLine(lineParts[0]);
codeString.AppendLine(lineParts[1]);
lineNumbers.Add((int)ParseHexAddress(lineParts[0]));
codeLines.Add(lineParts[1]);
}
}
}
txtCode.Text = codeString.ToString();
txtCodeMargin.Text = lineNumbers.ToString();
txtCodeMargin.SelectAll();
txtCodeMargin.SelectionAlignment = HorizontalAlignment.Right;
txtCodeMargin.SelectionLength = 0;
ctrlCodeViewer.TextLines = codeLines.ToArray();
ctrlCodeViewer.LineNumbers = lineNumbers.ToArray();
_codeChanged = false;
return true;
}
@ -172,9 +108,9 @@ namespace Mesen.GUI.Debugger
{
int attempts = 8;
do {
int pos = txtCodeMargin.Text.IndexOf(address.ToString("x"), StringComparison.InvariantCultureIgnoreCase);
if(pos >= 0) {
return txtCodeMargin.GetLineFromCharIndex(pos);
int lineIndex = this.ctrlCodeViewer.GetLineIndex((int)address);
if(lineIndex >= 0) {
return lineIndex;
}
address--;
attempts--;
@ -187,40 +123,38 @@ namespace Mesen.GUI.Debugger
return UInt32.Parse(hexAddress, System.Globalization.NumberStyles.AllowHexSpecifier);
}
private UInt32 GetLineAddress(int lineIndex)
public void HighlightBreakpoints(List<Breakpoint> breakpoints)
{
int lineStartIndex = txtCodeMargin.GetFirstCharIndexFromLine(lineIndex);
txtCodeMargin.SelectionStart = lineStartIndex;
txtCodeMargin.SelectionLength = 4;
return ParseHexAddress(txtCodeMargin.SelectedText);
ctrlCodeViewer.ClearLineStyles();
if(_currentActiveAddress.HasValue) {
this.ctrlCodeViewer.SetLineColor((int)_currentActiveAddress.Value, Color.Black, Color.Yellow, null, LineSymbol.None);
}
foreach(Breakpoint breakpoint in breakpoints) {
Color? fgColor = Color.White;
Color? bgColor = null;
Color? outlineColor = Color.FromArgb(140, 40, 40);
if(breakpoint.Enabled) {
bgColor = Color.FromArgb(140, 40, 40);
} else {
fgColor = Color.Black;
}
if(breakpoint.Address == (UInt32)(_currentActiveAddress.HasValue ? (int)_currentActiveAddress.Value : -1)) {
fgColor = Color.Black;
bgColor = Color.Yellow;
}
ctrlCodeViewer.SetLineColor((int)breakpoint.Address, fgColor, bgColor, outlineColor, breakpoint.Enabled ? LineSymbol.Circle : LineSymbol.CircleOutline);
}
}
public void HighlightLine(int lineIndex, Color bgColor, Color fgColor)
public int GetCurrentLine()
{
int lineStartIndex = txtCodeMargin.GetFirstCharIndexFromLine(lineIndex);
txtCodeMargin.SelectionStart = lineStartIndex;
txtCodeMargin.SelectionLength = 4;
txtCodeMargin.SelectionBackColor = bgColor;
txtCodeMargin.SelectionColor = fgColor;
txtCodeMargin.SelectionLength = 0;
lineStartIndex = txtCode.GetFirstCharIndexFromLine(lineIndex);
txtCode.SelectionStart = lineStartIndex;
txtCode.SelectionLength = txtCode.GetFirstCharIndexFromLine(lineIndex+1) - lineStartIndex;
txtCode.SelectionBackColor = bgColor;
txtCode.SelectionColor = fgColor;
txtCode.SelectionLength = 0;
}
public void ToggleBreakpoint()
{
HighlightLine(GetCurrentLine(), Color.FromArgb(158, 84, 94), Color.White);
InteropEmu.DebugAddBreakpoint(BreakpointType.Execute, GetLineAddress(GetCurrentLine()), false);
return this.ctrlCodeViewer.CurrentLine;
}
#region Events
private Point _previousLocation;
private void txtCode_MouseMove(object sender, MouseEventArgs e)
private void ctrlCodeViewer_MouseMove(object sender, MouseEventArgs e)
{
if(_previousLocation != e.Location) {
string word = GetWordUnderLocation(e.Location);
@ -228,14 +162,14 @@ 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, txtCode, e.Location.X + 5, e.Location.Y + 5, 3000);
toolTip.Show(valueText, ctrlCodeViewer, e.Location.X + 5, e.Location.Y + 5, 3000);
}
_previousLocation = e.Location;
}
}
UInt32 _lastClickedAddress = UInt32.MaxValue;
private void txtCode_MouseUp(object sender, MouseEventArgs e)
private void ctrlCodeViewer_MouseUp(object sender, MouseEventArgs e)
{
string word = GetWordUnderLocation(e.Location);
if(word.StartsWith("$")) {
@ -253,11 +187,6 @@ namespace Mesen.GUI.Debugger
}
}
private void txtCodeMargin_Enter(object sender, EventArgs e)
{
txtCode.Focus();
}
#region Context Menu
private void contextMenuCode_Opening(object sender, CancelEventArgs e)
{
@ -267,17 +196,20 @@ namespace Mesen.GUI.Debugger
private void mnuShowNextStatement_Click(object sender, EventArgs e)
{
ScrollToAddress(_currentActiveAddress.Value);
this.ctrlCodeViewer.ScrollIntoView((int)_currentActiveAddress.Value);
}
private void mnuShowOnlyDisassembledCode_Click(object sender, EventArgs e)
{
UpdateCode(true);
if(_currentActiveAddress.HasValue) {
SelectActiveAddress(_currentActiveAddress.Value);
}
}
private void mnuGoToLocation_Click(object sender, EventArgs e)
{
ScrollToAddress(_lastClickedAddress);
this.ctrlCodeViewer.ScrollIntoView((int)_lastClickedAddress);
}
private void mnuAddToWatch_Click(object sender, EventArgs e)

View file

@ -118,7 +118,7 @@
<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>143, 24</value>
<value>128, 15</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>

View file

@ -0,0 +1,127 @@
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;
namespace Mesen.GUI.Debugger
{
public partial class ctrlScrollableTextbox : UserControl
{
public new event MouseEventHandler MouseUp
{
add { this.ctrlTextbox.MouseUp += value; }
remove { this.ctrlTextbox.MouseUp -= value; }
}
public new event MouseEventHandler MouseMove
{
add { this.ctrlTextbox.MouseMove += value; }
remove { this.ctrlTextbox.MouseMove -= value; }
}
public ctrlScrollableTextbox()
{
InitializeComponent();
this.ctrlTextbox.ShowLineNumbers = true;
this.ctrlTextbox.ShowLineInHex = true;
this.vScrollBar.ValueChanged += vScrollBar_ValueChanged;
this.ctrlTextbox.ScrollPositionChanged += ctrlTextbox_ScrollPositionChanged;
}
public string GetWordUnderLocation(Point position)
{
return this.ctrlTextbox.GetWordUnderLocation(position);
}
private void ctrlTextbox_ScrollPositionChanged(object sender, EventArgs e)
{
this.vScrollBar.Value = this.ctrlTextbox.ScrollPosition;
}
public void ClearLineStyles()
{
this.ctrlTextbox.ClearLineStyles();
}
public void SetLineColor(int lineNumber, Color? fgColor = null, Color? bgColor = null, Color? outlineColor = null, LineSymbol symbol = LineSymbol.None)
{
this.ctrlTextbox.SetLineColor(lineNumber, fgColor, bgColor, outlineColor, symbol);
}
public int GetLineIndex(int lineNumber)
{
return this.ctrlTextbox.GetLineIndex(lineNumber);
}
public int GetLineNumber(int lineIndex)
{
return this.ctrlTextbox.GetLineNumber(lineIndex);
}
public void ScrollIntoView(int lineNumber)
{
this.ctrlTextbox.ScrollIntoView(lineNumber);
}
public int CurrentLine
{
get { return this.ctrlTextbox.CurrentLine; }
}
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
this.vScrollBar.Value = Math.Min(this.vScrollBar.Maximum, Math.Max(0, this.vScrollBar.Value - e.Delta / 40));
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
switch(keyData) {
case Keys.Down:
this.ctrlTextbox.CursorPosition++;
return true;
case Keys.Up:
this.ctrlTextbox.CursorPosition--;
return true;
case Keys.PageUp:
this.ctrlTextbox.CursorPosition-=20;
return true;
case Keys.PageDown:
this.ctrlTextbox.CursorPosition+=20;
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
private void vScrollBar_ValueChanged(object sender, EventArgs e)
{
this.ctrlTextbox.ScrollPosition = this.vScrollBar.Value;
}
public string[] TextLines
{
set
{
this.ctrlTextbox.TextLines = value;
this.vScrollBar.Maximum = this.ctrlTextbox.LineCount;
}
}
public int[] LineNumbers
{
set
{
this.ctrlTextbox.CustomLineNumbers = value;
}
}
}
}

View file

@ -0,0 +1,75 @@
namespace Mesen.GUI.Debugger
{
partial class ctrlScrollableTextbox
{
/// <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.vScrollBar = new System.Windows.Forms.VScrollBar();
this.ctrlTextbox = new Mesen.GUI.Debugger.ctrlTextbox();
this.SuspendLayout();
//
// vScrollBar
//
this.vScrollBar.Dock = System.Windows.Forms.DockStyle.Right;
this.vScrollBar.LargeChange = 20;
this.vScrollBar.Location = new System.Drawing.Point(130, 0);
this.vScrollBar.Name = "vScrollBar";
this.vScrollBar.Size = new System.Drawing.Size(18, 148);
this.vScrollBar.TabIndex = 0;
//
// ctrlTextbox
//
this.ctrlTextbox.CursorPosition = -1;
this.ctrlTextbox.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlTextbox.Font = new System.Drawing.Font("Consolas", 13F);
this.ctrlTextbox.Location = new System.Drawing.Point(0, 0);
this.ctrlTextbox.Name = "ctrlTextbox";
this.ctrlTextbox.ScrollPosition = 0;
this.ctrlTextbox.ShowLineInHex = false;
this.ctrlTextbox.ShowLineNumbers = true;
this.ctrlTextbox.Size = new System.Drawing.Size(130, 148);
this.ctrlTextbox.TabIndex = 1;
//
// ctrlScrollableTextbox
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Controls.Add(this.ctrlTextbox);
this.Controls.Add(this.vScrollBar);
this.Name = "ctrlScrollableTextbox";
this.Size = new System.Drawing.Size(148, 148);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.VScrollBar vScrollBar;
private ctrlTextbox ctrlTextbox;
}
}

View 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>

View file

@ -1,110 +0,0 @@
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 System.Runtime.InteropServices;
namespace Mesen.GUI.Debugger
{
class ctrlSyncTextBox : RichTextBox
{
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
private const int WM_MOUSEWHEEL = 0x20A;
private const int WM_VSCROLL = 0x115;
private const int WM_USER = 0x0400;
private const int EM_SETEVENTMASK = (WM_USER + 69);
private const int WM_SETREDRAW = 0x0b;
private IntPtr OldEventMask;
private Timer _syncTimer;
private RichTextBox _syncedTextbox;
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public RichTextBox SyncedTextbox
{
get
{
return _syncedTextbox;
}
set
{
if(_syncedTextbox == null) {
_syncedTextbox = value;
if(!DesignMode && value != null && _syncTimer == null) {
CreateTimer();
}
}
}
}
public void BeginUpdate()
{
SendMessage(Handle, WM_SETREDRAW, IntPtr.Zero, IntPtr.Zero);
OldEventMask = (IntPtr)SendMessage(Handle, EM_SETEVENTMASK, IntPtr.Zero, IntPtr.Zero);
}
public void EndUpdate()
{
SendMessage(Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
SendMessage(Handle, EM_SETEVENTMASK, IntPtr.Zero, OldEventMask);
}
private void CreateTimer()
{
_syncTimer = new Timer();
_syncTimer.Interval = 50;
_syncTimer.Enabled = true;
_syncTimer.Tick += (object sender, EventArgs e) => {
int line1 = SyncedTextbox.GetLineFromCharIndex(SyncedTextbox.GetCharIndexFromPosition(new Point(0, 0)));
int line2 = GetLineFromCharIndex(GetCharIndexFromPosition(new Point(0, 0)));
if(line1 != line2) {
int selectionStart = SyncedTextbox.GetFirstCharIndexFromLine(line2);
if(selectionStart >= 0) {
SyncedTextbox.SelectionStart = selectionStart;
SyncedTextbox.ScrollToCaret();
}
}
};
_syncTimer.Start();
}
protected override void WndProc(ref Message m)
{
if(m.Msg == WM_VSCROLL && SyncedTextbox != null && SyncedTextbox.IsHandleCreated) {
SendMessage(SyncedTextbox.Handle, m.Msg, m.WParam, m.LParam);
}
if(m.Msg == WM_MOUSEWHEEL) {
//Disable smooth scrolling by replacing the WM_MOUSEWHEEL event by regular VM_VSCROLL events
int scrollLines = SystemInformation.MouseWheelScrollLines;
for(int i = 0; i < scrollLines; i++) {
if((int)m.WParam > 0) {
SendMessage(Handle, WM_VSCROLL, (IntPtr)0, IntPtr.Zero);
} else {
SendMessage(Handle, WM_VSCROLL, (IntPtr)1, IntPtr.Zero);
}
}
return;
} else {
base.WndProc(ref m);
}
}
protected override void Dispose(bool disposing)
{
if(disposing) {
if(_syncTimer != null) {
_syncTimer.Stop();
_syncTimer = null;
}
}
base.Dispose(disposing);
}
}
}

View file

@ -0,0 +1,35 @@
namespace Mesen.GUI.Debugger
{
partial class ctrlTextbox
{
/// <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()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View file

@ -0,0 +1,333 @@
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;
namespace Mesen.GUI.Debugger
{
public enum LineSymbol
{
None = 0,
Circle,
CircleOutline,
}
public class LineProperties
{
public Color? BgColor;
public Color? FgColor;
public Color? OutlineColor;
public LineSymbol Symbol;
}
public partial class ctrlTextbox : Control
{
public event EventHandler ScrollPositionChanged;
//Dictionary<int,
private string[] _contents = new string[0];
private int[] _lineNumbers = new int[0];
private Dictionary<int, int> _lineNumberIndex = new Dictionary<int,int>();
private Dictionary<int, LineProperties> _lineProperties = new Dictionary<int,LineProperties>();
private bool _showLineNumbers = false;
private bool _showLineInHex = false;
private int _cursorPosition = 0;
private int _scrollPosition = 0;
public ctrlTextbox()
{
InitializeComponent();
this.ResizeRedraw = true;
this.DoubleBuffered = true;
this.Font = new Font("Consolas", 13);
}
public string[] TextLines
{
set
{
_contents = value;
_lineNumbers = new int[_contents.Length];
_lineNumberIndex.Clear();
for(int i = _contents.Length - 1; i >=0; i--) {
_lineNumbers[i] = i;
_lineNumberIndex[i] = i;
}
this.Invalidate();
}
}
public int LineCount
{
get
{
return _contents.Length;
}
}
public int[] CustomLineNumbers
{
set
{
_lineNumbers = value;
_lineNumberIndex.Clear();
int i = 0;
foreach(int line in _lineNumbers) {
_lineNumberIndex[line] = i;
i++;
}
this.Invalidate();
}
}
public void ClearLineStyles()
{
_lineProperties.Clear();
this.Invalidate();
}
public void SetLineColor(int lineNumber, Color? fgColor = null, Color? bgColor = null, Color? outlineColor = null, LineSymbol symbol = LineSymbol.None)
{
if(lineNumber != -1) {
if(_lineNumberIndex.ContainsKey(lineNumber)) {
LineProperties properties = new LineProperties() {
BgColor = bgColor,
FgColor = fgColor,
OutlineColor = outlineColor,
Symbol = symbol
};
_lineProperties[_lineNumberIndex[lineNumber]] = properties;
this.Invalidate();
}
}
}
public int GetLineIndex(int lineNumber)
{
return _lineNumberIndex.ContainsKey(lineNumber) ? _lineNumberIndex[lineNumber] : -1;
}
public int GetLineNumber(int lineIndex)
{
return _lineNumbers[lineIndex];
}
public void ScrollIntoView(int lineNumber)
{
int lineIndex = this.GetLineIndex(lineNumber);
if(lineIndex >= 0) {
if(lineIndex < this.ScrollPosition || lineIndex > this.GetLastVisibleLineIndex()) {
//Line isn't currently visible, scroll it to the middle of the viewport
this.ScrollPosition = lineIndex - this.GetNumberVisibleLines()/2;
}
this.CursorPosition = lineIndex;
}
}
private int GetMargin(Graphics g)
{
return this.ShowLineNumbers ? (int)(g.MeasureString("W", this.Font).Width * 6) : 0;
}
public string GetWordUnderLocation(Point position)
{
using(Graphics g = Graphics.FromHwnd(this.Handle)) {
int marginLeft = this.GetMargin(g);
int positionX = position.X - marginLeft;
int lineOffset = position.Y / (this.Font.Height - 1);
if(positionX >= 0 && this.ScrollPosition + lineOffset < _contents.Length) {
string text = _contents[this.ScrollPosition + lineOffset];
int charIndex = -1;
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;
}
previousWidth = width;
}
if(charIndex >= 0) {
List<char> wordDelimiters = new List<char>(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;
}
private int GetLastVisibleLineIndex()
{
return this.ScrollPosition + this.GetNumberVisibleLines() - 1;
}
private int GetNumberVisibleLines()
{
Rectangle rect = this.ClientRectangle;
return rect.Height / (this.Font.Height - 1);
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public int CursorPosition
{
get { return _cursorPosition; }
set
{
_cursorPosition = Math.Min(this._contents.Length - 1, Math.Max(0, value));
if(_cursorPosition < this.ScrollPosition) {
this.ScrollPosition = _cursorPosition;
} else if(_cursorPosition > this.GetLastVisibleLineIndex()) {
this.ScrollPosition = _cursorPosition - this.GetNumberVisibleLines() + 1;
}
this.Invalidate();
}
}
public int CurrentLine
{
get { return _lineNumbers[_cursorPosition]; }
}
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public int ScrollPosition
{
get { return _scrollPosition; }
set
{
value = Math.Max(0, Math.Min(value, this._contents.Length-1));
_scrollPosition = value;
if(this.ScrollPositionChanged != null) {
ScrollPositionChanged(this, null);
}
this.Invalidate();
}
}
public bool ShowLineNumbers
{
get { return _showLineNumbers; }
set { _showLineNumbers = value; }
}
public bool ShowLineInHex
{
get { return _showLineInHex; }
set { _showLineInHex = value; }
}
protected override void OnMouseDown(MouseEventArgs e)
{
this.Focus();
base.OnMouseDown(e);
}
protected override void OnMouseClick(MouseEventArgs e)
{
if(e.Button == System.Windows.Forms.MouseButtons.Left) {
int clickedLine = e.Y / (this.Font.Height - 1);
this.CursorPosition = this.ScrollPosition + clickedLine;
}
base.OnMouseClick(e);
}
private void DrawLine(Graphics g, int currentLine, int marginLeft, int positionY)
{
if(this.ShowLineNumbers) {
//Show line number
string lineNumber = _lineNumbers[currentLine] >= 0 ? _lineNumbers[currentLine].ToString(_showLineInHex ? "X4" : "") : "..";
float width = g.MeasureString(lineNumber, this.Font).Width;
g.DrawString(lineNumber, this.Font, Brushes.Gray, marginLeft - width, positionY);
}
if(currentLine == this.CursorPosition) {
//Highlight current line
g.FillRectangle(Brushes.AliceBlue, marginLeft, positionY, this.ClientRectangle.Width - marginLeft, this.Font.Height-1);
}
Color textColor = Color.Black;
if(_lineProperties.ContainsKey(currentLine)) {
//Process background, foreground, outline color and line symbol
LineProperties lineProperties = _lineProperties[currentLine];
textColor = lineProperties.FgColor ?? Color.Black;
float stringLength = g.MeasureString(_contents[currentLine], this.Font).Width;
if(lineProperties.BgColor.HasValue) {
using(Brush bgBrush = new SolidBrush(lineProperties.BgColor.Value)) {
g.FillRectangle(bgBrush, marginLeft + 1, positionY + 1, stringLength, this.Font.Height-2);
}
}
if(lineProperties.OutlineColor.HasValue) {
using(Pen outlinePen = new Pen(lineProperties.OutlineColor.Value, 1)) {
g.DrawRectangle(outlinePen, marginLeft + 1, positionY + 1, stringLength, this.Font.Height-2);
}
}
switch(lineProperties.Symbol) {
case LineSymbol.Circle:
using(Brush brush = new SolidBrush(lineProperties.OutlineColor.Value)) {
g.FillEllipse(brush, 2, positionY + 3, this.Font.Height - 7, this.Font.Height - 7);
if(lineProperties.OutlineColor.HasValue) {
using(Pen pen = new Pen(lineProperties.OutlineColor.Value, 1)) {
g.DrawEllipse(pen, 2, positionY + 3, this.Font.Height - 7, this.Font.Height - 7);
}
}
}
break;
case LineSymbol.CircleOutline:
if(lineProperties.OutlineColor.HasValue) {
using(Pen pen = new Pen(lineProperties.OutlineColor.Value, 1)) {
g.DrawEllipse(pen, 2, positionY + 3, this.Font.Height - 7, this.Font.Height - 7);
}
}
break;
}
}
using(Brush fgBrush = new SolidBrush(textColor)) {
g.DrawString(_contents[currentLine], this.Font, fgBrush, marginLeft, positionY);
}
}
protected override void OnPaint(PaintEventArgs pe)
{
pe.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
using(Brush lightGrayBrush = new SolidBrush(Color.FromArgb(240,240,240))) {
using(Pen grayPen = new Pen(Color.LightGray)) {
Rectangle rect = this.ClientRectangle;
pe.Graphics.FillRectangle(Brushes.White, rect);
int marginLeft = this.GetMargin(pe.Graphics);
if(this.ShowLineNumbers) {
pe.Graphics.FillRectangle(lightGrayBrush, 0, 0, marginLeft, rect.Bottom);
pe.Graphics.DrawLine(grayPen, marginLeft, rect.Top, marginLeft, rect.Bottom);
}
int currentLine = this.ScrollPosition;
int positionY = 0;
while(positionY < rect.Bottom && currentLine < _contents.Length) {
this.DrawLine(pe.Graphics, currentLine, marginLeft, positionY);
positionY += this.Font.Height - 1;
currentLine++;
}
}
}
}
}
}

View file

@ -31,7 +31,7 @@ namespace Mesen.GUI.Debugger
AdjustColumnWidth();
}
void lstWatch_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
private void lstWatch_ColumnWidthChanged(object sender, ColumnWidthChangedEventArgs e)
{
AdjustColumnWidth();
}

185
GUI.NET/Debugger/frmBreakpoint.Designer.cs generated Normal file
View file

@ -0,0 +1,185 @@
namespace Mesen.GUI.Debugger
{
partial class frmBreakpoint
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.lblBreakOn = new System.Windows.Forms.Label();
this.lblAddress = new System.Windows.Forms.Label();
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
this.radTypeExecute = new System.Windows.Forms.RadioButton();
this.radTypeRead = new System.Windows.Forms.RadioButton();
this.radTypeWrite = new System.Windows.Forms.RadioButton();
this.txtAddress = new System.Windows.Forms.TextBox();
this.chkEnabled = new System.Windows.Forms.CheckBox();
this.tableLayoutPanel1.SuspendLayout();
this.flowLayoutPanel2.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 142);
//
// 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.lblBreakOn, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.lblAddress, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.txtAddress, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.chkEnabled, 0, 2);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 4;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(327, 142);
this.tableLayoutPanel1.TabIndex = 2;
//
// lblBreakOn
//
this.lblBreakOn.AutoSize = true;
this.lblBreakOn.Location = new System.Drawing.Point(3, 4);
this.lblBreakOn.Margin = new System.Windows.Forms.Padding(3, 4, 3, 0);
this.lblBreakOn.Name = "lblBreakOn";
this.lblBreakOn.Size = new System.Drawing.Size(53, 13);
this.lblBreakOn.TabIndex = 0;
this.lblBreakOn.Text = "Break on:";
//
// lblAddress
//
this.lblAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAddress.AutoSize = true;
this.lblAddress.Location = new System.Drawing.Point(3, 76);
this.lblAddress.Name = "lblAddress";
this.lblAddress.Size = new System.Drawing.Size(48, 13);
this.lblAddress.TabIndex = 3;
this.lblAddress.Text = "Address:";
//
// flowLayoutPanel2
//
this.flowLayoutPanel2.Controls.Add(this.radTypeExecute);
this.flowLayoutPanel2.Controls.Add(this.radTypeRead);
this.flowLayoutPanel2.Controls.Add(this.radTypeWrite);
this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel2.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.flowLayoutPanel2.Location = new System.Drawing.Point(59, 0);
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
this.flowLayoutPanel2.Size = new System.Drawing.Size(268, 70);
this.flowLayoutPanel2.TabIndex = 4;
//
// radTypeExecute
//
this.radTypeExecute.AutoSize = true;
this.radTypeExecute.Location = new System.Drawing.Point(3, 3);
this.radTypeExecute.Name = "radTypeExecute";
this.radTypeExecute.Size = new System.Drawing.Size(72, 17);
this.radTypeExecute.TabIndex = 0;
this.radTypeExecute.TabStop = true;
this.radTypeExecute.Text = "Execution";
this.radTypeExecute.UseVisualStyleBackColor = true;
//
// radTypeRead
//
this.radTypeRead.AutoSize = true;
this.radTypeRead.Location = new System.Drawing.Point(3, 26);
this.radTypeRead.Name = "radTypeRead";
this.radTypeRead.Size = new System.Drawing.Size(51, 17);
this.radTypeRead.TabIndex = 1;
this.radTypeRead.TabStop = true;
this.radTypeRead.Text = "Read";
this.radTypeRead.UseVisualStyleBackColor = true;
//
// radTypeWrite
//
this.radTypeWrite.AutoSize = true;
this.radTypeWrite.Location = new System.Drawing.Point(3, 49);
this.radTypeWrite.Name = "radTypeWrite";
this.radTypeWrite.Size = new System.Drawing.Size(50, 17);
this.radTypeWrite.TabIndex = 2;
this.radTypeWrite.TabStop = true;
this.radTypeWrite.Text = "Write";
this.radTypeWrite.UseVisualStyleBackColor = true;
//
// txtAddress
//
this.txtAddress.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtAddress.Location = new System.Drawing.Point(62, 73);
this.txtAddress.Name = "txtAddress";
this.txtAddress.Size = new System.Drawing.Size(262, 20);
this.txtAddress.TabIndex = 5;
//
// chkEnabled
//
this.chkEnabled.AutoSize = true;
this.tableLayoutPanel1.SetColumnSpan(this.chkEnabled, 2);
this.chkEnabled.Location = new System.Drawing.Point(3, 99);
this.chkEnabled.Name = "chkEnabled";
this.chkEnabled.Size = new System.Drawing.Size(65, 17);
this.chkEnabled.TabIndex = 2;
this.chkEnabled.Text = "Enabled";
this.chkEnabled.UseVisualStyleBackColor = true;
//
// frmBreakpoint
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(327, 171);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "frmBreakpoint";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Breakpoint";
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label lblBreakOn;
private System.Windows.Forms.Label lblAddress;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
private System.Windows.Forms.RadioButton radTypeExecute;
private System.Windows.Forms.RadioButton radTypeRead;
private System.Windows.Forms.RadioButton radTypeWrite;
private System.Windows.Forms.TextBox txtAddress;
private System.Windows.Forms.CheckBox chkEnabled;
}
}

View 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>

View file

@ -34,23 +34,12 @@
this.components = new System.ComponentModel.Container();
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.tlpTop = new System.Windows.Forms.TableLayoutPanel();
this.ctrlDebuggerCode = new Mesen.GUI.Debugger.ctrlDebuggerCode();
this.contextMenuCode = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuShowNextStatement = new System.Windows.Forms.ToolStripMenuItem();
this.mnuSetNextStatement = new System.Windows.Forms.ToolStripMenuItem();
this.ctrlConsoleStatus = new Mesen.GUI.Debugger.ctrlConsoleStatus();
this.ctrlDebuggerCodeSplit = new Mesen.GUI.Debugger.ctrlDebuggerCode();
this.tableLayoutPanel10 = new System.Windows.Forms.TableLayoutPanel();
this.grpBreakpoints = new System.Windows.Forms.GroupBox();
this.lstBreakpoints = new System.Windows.Forms.ListView();
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader4 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.contextMenuBreakpoints = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuRemoveBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
this.mnuDisableBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAddBreakpoint = new System.Windows.Forms.ToolStripMenuItem();
this.grpWatch = new System.Windows.Forms.GroupBox();
this.ctrlWatch = new Mesen.GUI.Debugger.ctrlWatch();
this.menuStrip = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
@ -71,6 +60,16 @@
this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFindPrev = new System.Windows.Forms.ToolStripMenuItem();
this.mnuGoTo = new System.Windows.Forms.ToolStripMenuItem();
this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.nametableViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.cHRViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
this.mnuMemoryViewer = new System.Windows.Forms.ToolStripMenuItem();
this.ctrlDebuggerCode = new Mesen.GUI.Debugger.ctrlDebuggerCode();
this.ctrlConsoleStatus = new Mesen.GUI.Debugger.ctrlConsoleStatus();
this.ctrlDebuggerCodeSplit = new Mesen.GUI.Debugger.ctrlDebuggerCode();
this.ctrlBreakpoints = new Mesen.GUI.Debugger.Controls.ctrlBreakpoints();
this.ctrlWatch = new Mesen.GUI.Debugger.ctrlWatch();
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
@ -79,7 +78,6 @@
this.contextMenuCode.SuspendLayout();
this.tableLayoutPanel10.SuspendLayout();
this.grpBreakpoints.SuspendLayout();
this.contextMenuBreakpoints.SuspendLayout();
this.grpWatch.SuspendLayout();
this.menuStrip.SuspendLayout();
this.SuspendLayout();
@ -122,17 +120,6 @@
this.tlpTop.Size = new System.Drawing.Size(984, 422);
this.tlpTop.TabIndex = 2;
//
// ctrlDebuggerCode
//
this.ctrlDebuggerCode.Code = null;
this.ctrlDebuggerCode.ContextMenuStrip = this.contextMenuCode;
this.ctrlDebuggerCode.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlDebuggerCode.Location = new System.Drawing.Point(3, 3);
this.ctrlDebuggerCode.Name = "ctrlDebuggerCode";
this.ctrlDebuggerCode.Size = new System.Drawing.Size(270, 416);
this.ctrlDebuggerCode.TabIndex = 2;
this.ctrlDebuggerCode.OnWatchAdded += new Mesen.GUI.Debugger.ctrlDebuggerCode.WatchAddedEventHandler(this.ctrlDebuggerCode_OnWatchAdded);
//
// contextMenuCode
//
this.contextMenuCode.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@ -157,24 +144,6 @@
this.mnuSetNextStatement.Size = new System.Drawing.Size(258, 22);
this.mnuSetNextStatement.Text = "Set Next Statement";
//
// ctrlConsoleStatus
//
this.ctrlConsoleStatus.Dock = System.Windows.Forms.DockStyle.Top;
this.ctrlConsoleStatus.Location = new System.Drawing.Point(552, 0);
this.ctrlConsoleStatus.Margin = new System.Windows.Forms.Padding(0);
this.ctrlConsoleStatus.Name = "ctrlConsoleStatus";
this.ctrlConsoleStatus.Size = new System.Drawing.Size(432, 362);
this.ctrlConsoleStatus.TabIndex = 3;
//
// ctrlDebuggerCodeSplit
//
this.ctrlDebuggerCodeSplit.Code = null;
this.ctrlDebuggerCodeSplit.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(279, 3);
this.ctrlDebuggerCodeSplit.Name = "ctrlDebuggerCodeSplit";
this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(270, 416);
this.ctrlDebuggerCodeSplit.TabIndex = 4;
//
// tableLayoutPanel10
//
this.tableLayoutPanel10.ColumnCount = 2;
@ -197,7 +166,7 @@
this.grpBreakpoints.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.grpBreakpoints.Controls.Add(this.lstBreakpoints);
this.grpBreakpoints.Controls.Add(this.ctrlBreakpoints);
this.grpBreakpoints.Location = new System.Drawing.Point(495, 3);
this.grpBreakpoints.Name = "grpBreakpoints";
this.grpBreakpoints.Size = new System.Drawing.Size(486, 156);
@ -205,61 +174,6 @@
this.grpBreakpoints.TabStop = false;
this.grpBreakpoints.Text = "Breakpoints";
//
// lstBreakpoints
//
this.lstBreakpoints.CheckBoxes = true;
this.lstBreakpoints.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader3,
this.columnHeader4});
this.lstBreakpoints.ContextMenuStrip = this.contextMenuBreakpoints;
this.lstBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstBreakpoints.FullRowSelect = true;
this.lstBreakpoints.GridLines = true;
this.lstBreakpoints.LabelEdit = true;
this.lstBreakpoints.Location = new System.Drawing.Point(3, 16);
this.lstBreakpoints.Name = "lstBreakpoints";
this.lstBreakpoints.Size = new System.Drawing.Size(480, 137);
this.lstBreakpoints.TabIndex = 5;
this.lstBreakpoints.UseCompatibleStateImageBehavior = false;
this.lstBreakpoints.View = System.Windows.Forms.View.Details;
//
// columnHeader3
//
this.columnHeader3.Text = "Address";
this.columnHeader3.Width = 59;
//
// columnHeader4
//
this.columnHeader4.Text = "Breakpoint Type";
this.columnHeader4.Width = 100;
//
// contextMenuBreakpoints
//
this.contextMenuBreakpoints.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuRemoveBreakpoint,
this.mnuDisableBreakpoint,
this.mnuAddBreakpoint});
this.contextMenuBreakpoints.Name = "contextMenuWatch";
this.contextMenuBreakpoints.Size = new System.Drawing.Size(173, 70);
//
// mnuRemoveBreakpoint
//
this.mnuRemoveBreakpoint.Name = "mnuRemoveBreakpoint";
this.mnuRemoveBreakpoint.Size = new System.Drawing.Size(172, 22);
this.mnuRemoveBreakpoint.Text = "Remove";
//
// mnuDisableBreakpoint
//
this.mnuDisableBreakpoint.Name = "mnuDisableBreakpoint";
this.mnuDisableBreakpoint.Size = new System.Drawing.Size(172, 22);
this.mnuDisableBreakpoint.Text = "Disable Breakpoint";
//
// mnuAddBreakpoint
//
this.mnuAddBreakpoint.Name = "mnuAddBreakpoint";
this.mnuAddBreakpoint.Size = new System.Drawing.Size(172, 22);
this.mnuAddBreakpoint.Text = "Add...";
//
// grpWatch
//
this.grpWatch.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
@ -273,21 +187,14 @@
this.grpWatch.TabStop = false;
this.grpWatch.Text = "Watch";
//
// ctrlWatch
//
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(480, 137);
this.ctrlWatch.TabIndex = 0;
//
// menuStrip
//
this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.mnuView,
this.debugToolStripMenuItem,
this.searchToolStripMenuItem});
this.searchToolStripMenuItem,
this.toolsToolStripMenuItem});
this.menuStrip.Location = new System.Drawing.Point(0, 0);
this.menuStrip.Name = "menuStrip";
this.menuStrip.Size = new System.Drawing.Size(984, 24);
@ -448,6 +355,90 @@
this.mnuGoTo.Size = new System.Drawing.Size(196, 22);
this.mnuGoTo.Text = "Go to...";
//
// toolsToolStripMenuItem
//
this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.nametableViewerToolStripMenuItem,
this.cHRViewerToolStripMenuItem,
this.toolStripMenuItem3,
this.mnuMemoryViewer});
this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
this.toolsToolStripMenuItem.Size = new System.Drawing.Size(48, 20);
this.toolsToolStripMenuItem.Text = "Tools";
//
// nametableViewerToolStripMenuItem
//
this.nametableViewerToolStripMenuItem.Name = "nametableViewerToolStripMenuItem";
this.nametableViewerToolStripMenuItem.Size = new System.Drawing.Size(170, 22);
this.nametableViewerToolStripMenuItem.Text = "Nametable Viewer";
//
// cHRViewerToolStripMenuItem
//
this.cHRViewerToolStripMenuItem.Name = "cHRViewerToolStripMenuItem";
this.cHRViewerToolStripMenuItem.Size = new System.Drawing.Size(170, 22);
this.cHRViewerToolStripMenuItem.Text = "CHR Viewer";
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
this.toolStripMenuItem3.Size = new System.Drawing.Size(167, 6);
//
// mnuMemoryViewer
//
this.mnuMemoryViewer.Name = "mnuMemoryViewer";
this.mnuMemoryViewer.Size = new System.Drawing.Size(170, 22);
this.mnuMemoryViewer.Text = "Memory Viewer";
this.mnuMemoryViewer.Click += new System.EventHandler(this.mnuMemoryViewer_Click);
//
// ctrlDebuggerCode
//
this.ctrlDebuggerCode.Code = null;
this.ctrlDebuggerCode.ContextMenuStrip = this.contextMenuCode;
this.ctrlDebuggerCode.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlDebuggerCode.Location = new System.Drawing.Point(3, 3);
this.ctrlDebuggerCode.Name = "ctrlDebuggerCode";
this.ctrlDebuggerCode.Size = new System.Drawing.Size(270, 416);
this.ctrlDebuggerCode.TabIndex = 2;
this.ctrlDebuggerCode.OnWatchAdded += new Mesen.GUI.Debugger.ctrlDebuggerCode.WatchAddedEventHandler(this.ctrlDebuggerCode_OnWatchAdded);
this.ctrlDebuggerCode.Enter += new System.EventHandler(this.ctrlDebuggerCode_Enter);
//
// ctrlConsoleStatus
//
this.ctrlConsoleStatus.Dock = System.Windows.Forms.DockStyle.Top;
this.ctrlConsoleStatus.Location = new System.Drawing.Point(552, 0);
this.ctrlConsoleStatus.Margin = new System.Windows.Forms.Padding(0);
this.ctrlConsoleStatus.Name = "ctrlConsoleStatus";
this.ctrlConsoleStatus.Size = new System.Drawing.Size(432, 362);
this.ctrlConsoleStatus.TabIndex = 3;
//
// ctrlDebuggerCodeSplit
//
this.ctrlDebuggerCodeSplit.Code = null;
this.ctrlDebuggerCodeSplit.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(279, 3);
this.ctrlDebuggerCodeSplit.Name = "ctrlDebuggerCodeSplit";
this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(270, 416);
this.ctrlDebuggerCodeSplit.TabIndex = 4;
this.ctrlDebuggerCodeSplit.OnWatchAdded += new Mesen.GUI.Debugger.ctrlDebuggerCode.WatchAddedEventHandler(this.ctrlDebuggerCode_OnWatchAdded);
this.ctrlDebuggerCodeSplit.Enter += new System.EventHandler(this.ctrlDebuggerCodeSplit_Enter);
//
// ctrlBreakpoints
//
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(480, 137);
this.ctrlBreakpoints.TabIndex = 0;
this.ctrlBreakpoints.BreakpointChanged += new System.EventHandler(this.ctrlBreakpoints_BreakpointChanged);
//
// ctrlWatch
//
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(480, 137);
this.ctrlWatch.TabIndex = 0;
//
// frmDebugger
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -468,7 +459,6 @@
this.contextMenuCode.ResumeLayout(false);
this.tableLayoutPanel10.ResumeLayout(false);
this.grpBreakpoints.ResumeLayout(false);
this.contextMenuBreakpoints.ResumeLayout(false);
this.grpWatch.ResumeLayout(false);
this.menuStrip.ResumeLayout(false);
this.menuStrip.PerformLayout();
@ -483,15 +473,10 @@
private System.Windows.Forms.TableLayoutPanel tlpTop;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel10;
private System.Windows.Forms.GroupBox grpBreakpoints;
private System.Windows.Forms.ListView lstBreakpoints;
private System.Windows.Forms.GroupBox grpWatch;
private System.Windows.Forms.MenuStrip menuStrip;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem debugToolStripMenuItem;
private System.Windows.Forms.ContextMenuStrip contextMenuBreakpoints;
private System.Windows.Forms.ToolStripMenuItem mnuRemoveBreakpoint;
private System.Windows.Forms.ToolStripMenuItem mnuDisableBreakpoint;
private System.Windows.Forms.ToolStripMenuItem mnuAddBreakpoint;
private System.Windows.Forms.ToolStripMenuItem mnuContinue;
private System.Windows.Forms.ToolStripMenuItem mnuBreak;
private System.Windows.Forms.ToolStripMenuItem mnuStepInto;
@ -502,8 +487,6 @@
private System.Windows.Forms.ToolStripMenuItem mnuFindNext;
private System.Windows.Forms.ToolStripMenuItem mnuFindPrev;
private System.Windows.Forms.ToolStripMenuItem mnuGoTo;
private System.Windows.Forms.ColumnHeader columnHeader3;
private System.Windows.Forms.ColumnHeader columnHeader4;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem mnuToggleBreakpoint;
private ctrlDebuggerCode ctrlDebuggerCode;
@ -518,5 +501,11 @@
private ctrlDebuggerCode ctrlDebuggerCodeSplit;
private System.Windows.Forms.ToolStripMenuItem mnuView;
private System.Windows.Forms.ToolStripMenuItem mnuSplitView;
private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem nametableViewerToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem cHRViewerToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
private System.Windows.Forms.ToolStripMenuItem mnuMemoryViewer;
private Controls.ctrlBreakpoints ctrlBreakpoints;
}
}

View file

@ -15,10 +15,13 @@ namespace Mesen.GUI.Debugger
public partial class frmDebugger : Form
{
InteropEmu.NotificationListener _notifListener;
ctrlDebuggerCode _lastCodeWindow;
public frmDebugger()
{
InitializeComponent();
_lastCodeWindow = ctrlDebuggerCode;
}
protected override void OnLoad(EventArgs e)
@ -70,22 +73,39 @@ namespace Mesen.GUI.Debugger
if(UpdateSplitView()) {
ctrlDebuggerCodeSplit.UpdateCode(true);
} else {
_lastCodeWindow = ctrlDebuggerCode;
}
ctrlDebuggerCode.SelectActiveAddress(state.CPU.PC);
ctrlDebuggerCode.SelectActiveAddress(state.CPU.DebugPC);
ctrlDebuggerCodeSplit.SetActiveAddress(state.CPU.DebugPC);
RefreshBreakpoints();
ctrlConsoleStatus.UpdateStatus(ref state);
ctrlWatch.UpdateWatch();
}
private void ClearActiveStatement()
{
ctrlDebuggerCode.ClearActiveAddress();
RefreshBreakpoints();
}
private void ToggleBreakpoint()
{
this.ctrlDebuggerCode.ToggleBreakpoint();
ctrlBreakpoints.ToggleBreakpoint(_lastCodeWindow.GetCurrentLine());
}
private void RefreshBreakpoints()
{
ctrlDebuggerCodeSplit.HighlightBreakpoints(ctrlBreakpoints.GetBreakpoints());
ctrlDebuggerCode.HighlightBreakpoints(ctrlBreakpoints.GetBreakpoints());
}
private void mnuContinue_Click(object sender, EventArgs e)
{
ClearActiveStatement();
InteropEmu.DebugRun();
this.ctrlDebuggerCode.RemoveActiveHighlight();
}
private void frmDebugger_FormClosed(object sender, FormClosedEventArgs e)
@ -137,5 +157,25 @@ namespace Mesen.GUI.Debugger
{
UpdateDebugger();
}
private void mnuMemoryViewer_Click(object sender, EventArgs e)
{
}
private void ctrlBreakpoints_BreakpointChanged(object sender, EventArgs e)
{
RefreshBreakpoints();
}
private void ctrlDebuggerCode_Enter(object sender, EventArgs e)
{
_lastCodeWindow = ctrlDebuggerCode;
}
private void ctrlDebuggerCodeSplit_Enter(object sender, EventArgs e)
{
_lastCodeWindow = ctrlDebuggerCodeSplit;
}
}
}

View file

@ -120,9 +120,6 @@
<metadata name="contextMenuCode.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>561, 17</value>
</metadata>
<metadata name="contextMenuBreakpoints.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>373, 17</value>
</metadata>
<metadata name="menuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>107, 17</value>
</metadata>

View file

@ -0,0 +1,37 @@
namespace Mesen.GUI.Debugger
{
partial class frmMemoryViewer
{
/// <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.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Text = "frmMemoryViewer";
}
#endregion
}
}

View file

@ -0,0 +1,21 @@
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.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmMemoryViewer : BaseForm
{
public frmMemoryViewer()
{
InitializeComponent();
}
}
}

View file

@ -97,7 +97,7 @@ namespace Mesen.GUI.Forms
return true;
}
protected void AddBinding(string fieldName, Control bindedField, object enumValue = null)
protected void AddBinding(string fieldName, Control bindedField)
{
if(BindedType == null) {
throw new Exception("Need to override BindedType to use bindings");
@ -108,7 +108,6 @@ namespace Mesen.GUI.Forms
_fieldInfo[info.Name] = info;
}
}
bindedField.Tag = enumValue;
_bindings[fieldName] = bindedField;
}

View file

@ -110,7 +110,6 @@ namespace Mesen.GUI.Forms.Cheats
this.tableLayoutPanel1.SetColumnSpan(this.lstCheats, 2);
this.lstCheats.ContextMenuStrip = this.contextMenuCheats;
this.lstCheats.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstCheats.DoubleClickDoesCheck = false;
this.lstCheats.FullRowSelect = true;
this.lstCheats.GridLines = true;
this.lstCheats.Location = new System.Drawing.Point(3, 26);

View file

@ -99,6 +99,13 @@
<Compile Include="Controls\MyListView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Debugger\Breakpoint.cs" />
<Compile Include="Debugger\Controls\ctrlBreakpoints.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlBreakpoints.Designer.cs">
<DependentUpon>ctrlBreakpoints.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlConsoleStatus.cs">
<SubType>UserControl</SubType>
</Compile>
@ -111,21 +118,42 @@
<Compile Include="Debugger\Controls\ctrlDebuggerCode.Designer.cs">
<DependentUpon>ctrlDebuggerCode.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlSyncTextBox.cs">
<Compile Include="Debugger\Controls\ctrlScrollableTextbox.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlScrollableTextbox.designer.cs">
<DependentUpon>ctrlScrollableTextbox.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlTextbox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlTextbox.Designer.cs">
<DependentUpon>ctrlTextbox.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlWatch.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlWatch.Designer.cs">
<DependentUpon>ctrlWatch.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmBreakpoint.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmBreakpoint.Designer.cs">
<DependentUpon>frmBreakpoint.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmDebugger.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmDebugger.Designer.cs">
<DependentUpon>frmDebugger.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmMemoryViewer.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmMemoryViewer.Designer.cs">
<DependentUpon>frmMemoryViewer.cs</DependentUpon>
</Compile>
<Compile Include="Forms\BaseConfigForm.Designer.cs">
<DependentUpon>BaseConfigForm.cs</DependentUpon>
</Compile>
@ -213,15 +241,24 @@
<EmbeddedResource Include="Controls\ctrlTrackbar.resx">
<DependentUpon>ctrlTrackbar.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlBreakpoints.resx">
<DependentUpon>ctrlBreakpoints.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlConsoleStatus.resx">
<DependentUpon>ctrlConsoleStatus.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlDebuggerCode.resx">
<DependentUpon>ctrlDebuggerCode.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlScrollableTextbox.resx">
<DependentUpon>ctrlScrollableTextbox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlWatch.resx">
<DependentUpon>ctrlWatch.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmBreakpoint.resx">
<DependentUpon>frmBreakpoint.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmDebugger.resx">
<DependentUpon>frmDebugger.cs</DependentUpon>
</EmbeddedResource>

View file

@ -47,7 +47,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void DisplayMessage([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string title, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string message);
[DllImport(DLLPath)] public static extern void MoviePlay([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename);
[DllImport(DLLPath)] public static extern void MovieRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename, bool reset);
[DllImport(DLLPath)] public static extern void MovieRecord([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(UTF8Marshaler))]string filename, [MarshalAs(UnmanagedType.I1)]bool reset);
[DllImport(DLLPath)] public static extern void MovieStop();
[DllImport(DLLPath)] public static extern bool MoviePlaying();
[DllImport(DLLPath)] public static extern bool MovieRecording();
@ -56,7 +56,7 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void LoadState(UInt32 stateIndex);
[DllImport(DLLPath)] public static extern Int64 GetStateInfo(UInt32 stateIndex);
[DllImport(DLLPath)] public static extern void CheatAddCustom(UInt32 address, Byte value, Int32 compareValue, bool isRelativeAddress);
[DllImport(DLLPath)] public static extern void CheatAddCustom(UInt32 address, Byte value, Int32 compareValue, [MarshalAs(UnmanagedType.I1)]bool isRelativeAddress);
[DllImport(DLLPath)] public static extern void CheatAddGameGenie(string code);
[DllImport(DLLPath)] public static extern void CheatAddProActionRocky(UInt32 code);
[DllImport(DLLPath)] public static extern void CheatClear();
@ -69,9 +69,10 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void SetOverscanDimensions(UInt32 left, UInt32 right, UInt32 top, UInt32 bottom);
[DllImport(DLLPath)] public static extern void DebugInitialize();
[DllImport(DLLPath)] public static extern void DebugRelease();
[DllImport(DLLPath)] public static extern void DebugRelease();
[DllImport(DLLPath)] public static extern void DebugGetState(ref DebugState state);
[DllImport(DLLPath)] public static extern void DebugAddBreakpoint(BreakpointType type, UInt32 address, bool isAbsoluteAddr);
[DllImport(DLLPath)] public static extern void DebugAddBreakpoint(BreakpointType type, UInt32 address, [MarshalAs(UnmanagedType.I1)]bool isAbsoluteAddr, [MarshalAs(UnmanagedType.I1)]bool enabled);
[DllImport(DLLPath)] public static extern void DebugRemoveBreakpoint(BreakpointType type, UInt32 address, [MarshalAs(UnmanagedType.I1)]bool isAbsoluteAddr);
[DllImport(DLLPath)] public static extern void DebugStep(UInt32 count);
[DllImport(DLLPath)] public static extern void DebugStepCycles(UInt32 count);
[DllImport(DLLPath)] public static extern void DebugStepOut();
@ -235,7 +236,11 @@ namespace Mesen.GUI
public Byte Y;
public Byte PS;
public IRQSource IRQFlag;
[MarshalAs(UnmanagedType.I1)]
public bool NMIFlag;
public UInt16 DebugPC;
};
[Flags]

View file

@ -149,12 +149,12 @@ namespace InteropEmu {
DllExport int64_t __stdcall GetStateInfo(uint32_t stateIndex) { return SaveStateManager::GetStateInfo(stateIndex); }
DllExport void __stdcall MoviePlay(char* filename) { Movie::Play(filename); }
DllExport void __stdcall MovieRecord(char* filename, int reset) { Movie::Record(filename, reset != 0); }
DllExport void __stdcall MovieRecord(char* filename, bool reset) { Movie::Record(filename, reset); }
DllExport void __stdcall MovieStop() { Movie::Stop(); }
DllExport int __stdcall MoviePlaying() { return Movie::Playing(); }
DllExport int __stdcall MovieRecording() { return Movie::Recording(); }
DllExport void __stdcall CheatAddCustom(uint32_t address, uint8_t value, int32_t compareValue, int isRelativeAddress) { CheatManager::AddCustomCode(address, value, compareValue, isRelativeAddress != 0); }
DllExport void __stdcall CheatAddCustom(uint32_t address, uint8_t value, int32_t compareValue, bool isRelativeAddress) { CheatManager::AddCustomCode(address, value, compareValue, isRelativeAddress); }
DllExport void __stdcall CheatAddGameGenie(char* code) { CheatManager::AddGameGenieCode(code); }
DllExport void __stdcall CheatAddProActionRocky(uint32_t code) { CheatManager::AddProActionRockyCode(code); }
DllExport void __stdcall CheatClear() { CheatManager::ClearCodes(); }

View file

@ -22,7 +22,8 @@ extern "C"
DllExport void __stdcall DebugGetState(DebugState *state) { _debugger->GetState(state); }
DllExport void DebugAddBreakpoint(uint32_t type, uint32_t address, int isAbsoluteAddr) { _debugger->AddBreakpoint((BreakpointType)type, address, isAbsoluteAddr == 1); }
DllExport void __stdcall DebugAddBreakpoint(uint32_t type, uint32_t address, bool isAbsoluteAddr, bool enabled) { _debugger->AddBreakpoint((BreakpointType)type, address, isAbsoluteAddr, enabled); }
DllExport void __stdcall DebugRemoveBreakpoint(uint32_t type, uint32_t address, bool isAbsoluteAddr) { _debugger->RemoveBreakpoint((BreakpointType)type, address, isAbsoluteAddr); }
DllExport void __stdcall DebugRun() { _debugger->Run(); }
DllExport void __stdcall DebugStep(uint32_t count) { _debugger->Step(count); }