2016-11-20 13:15:37 -05:00
|
|
|
|
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.Collections;
|
2016-12-11 14:25:29 -05:00
|
|
|
|
using Mesen.GUI.Controls;
|
2018-03-10 09:58:24 -05:00
|
|
|
|
using Mesen.GUI.Config;
|
2016-11-20 13:15:37 -05:00
|
|
|
|
|
|
|
|
|
namespace Mesen.GUI.Debugger.Controls
|
|
|
|
|
{
|
2016-12-11 14:25:29 -05:00
|
|
|
|
public partial class ctrlFunctionList : BaseControl
|
2016-11-20 13:15:37 -05:00
|
|
|
|
{
|
2016-11-27 10:56:37 -05:00
|
|
|
|
public event EventHandler OnFindOccurrence;
|
2016-11-20 13:15:37 -05:00
|
|
|
|
public event EventHandler OnFunctionSelected;
|
2016-11-27 10:56:37 -05:00
|
|
|
|
|
2018-06-09 21:25:49 -04:00
|
|
|
|
private List<ListViewItem> _listItems = new List<ListViewItem>();
|
|
|
|
|
private Dictionary<Int32, ListViewItem> _functions = new Dictionary<int, ListViewItem>();
|
|
|
|
|
|
2016-11-20 13:15:37 -05:00
|
|
|
|
public ctrlFunctionList()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
2018-06-09 17:54:34 -04:00
|
|
|
|
}
|
2018-03-10 09:58:24 -05:00
|
|
|
|
|
2018-06-09 17:54:34 -04:00
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
base.OnLoad(e);
|
|
|
|
|
if(!IsDesignMode) {
|
|
|
|
|
InitShortcuts();
|
2018-03-10 09:58:24 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void InitShortcuts()
|
|
|
|
|
{
|
|
|
|
|
mnuEditLabel.InitShortcut(this, nameof(DebuggerShortcutsConfig.FunctionList_EditLabel));
|
|
|
|
|
mnuAddBreakpoint.InitShortcut(this, nameof(DebuggerShortcutsConfig.FunctionList_AddBreakpoint));
|
|
|
|
|
mnuFindOccurrences.InitShortcut(this, nameof(DebuggerShortcutsConfig.FunctionList_FindOccurrences));
|
2016-11-20 13:15:37 -05:00
|
|
|
|
}
|
|
|
|
|
|
2018-06-09 21:25:49 -04:00
|
|
|
|
private int CompareFunctions(ListViewItem a, ListViewItem b)
|
2016-11-20 13:15:37 -05:00
|
|
|
|
{
|
2018-06-09 21:25:49 -04:00
|
|
|
|
string aText = string.IsNullOrWhiteSpace(a.Text) ? "ZZZZZZZZZZZZZZZZZZZZZZZ" : a.Text;
|
|
|
|
|
string bText = string.IsNullOrWhiteSpace(b.Text) ? "ZZZZZZZZZZZZZZZZZZZZZZZ" : b.Text;
|
|
|
|
|
Int32 aRelative = (Int32)a.SubItems[1].Tag == -1 ? Int32.MaxValue : (Int32)a.SubItems[1].Tag;
|
|
|
|
|
Int32 bRelative = (Int32)b.SubItems[1].Tag == -1 ? Int32.MaxValue : (Int32)b.SubItems[1].Tag;
|
|
|
|
|
Int32 aAbsolute = (Int32)a.SubItems[2].Tag;
|
|
|
|
|
Int32 bAbsolute = (Int32)b.SubItems[2].Tag;
|
|
|
|
|
|
|
|
|
|
if(a.Text == b.Text) {
|
|
|
|
|
if(a.Tag == b.Tag) {
|
2018-07-29 11:52:18 -04:00
|
|
|
|
return aAbsolute - bAbsolute;
|
2016-11-20 13:15:37 -05:00
|
|
|
|
} else {
|
2018-07-29 11:52:18 -04:00
|
|
|
|
return aRelative - bRelative;
|
2016-11-20 13:15:37 -05:00
|
|
|
|
}
|
2018-06-09 21:25:49 -04:00
|
|
|
|
} else {
|
|
|
|
|
return string.Compare(aText, bText);
|
2016-11-20 13:15:37 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-26 14:15:50 -05:00
|
|
|
|
public void UpdateFunctionList(bool reset)
|
2016-11-20 13:15:37 -05:00
|
|
|
|
{
|
2016-11-26 14:15:50 -05:00
|
|
|
|
if(reset) {
|
2018-06-09 21:25:49 -04:00
|
|
|
|
_listItems.Clear();
|
2016-11-26 14:15:50 -05:00
|
|
|
|
_functions.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
2018-06-09 21:25:49 -04:00
|
|
|
|
Font italicFont = null;
|
|
|
|
|
Font regularFont = null;
|
|
|
|
|
|
2016-11-20 13:15:37 -05:00
|
|
|
|
Int32[] entryPoints = InteropEmu.DebugGetFunctionEntryPoints();
|
|
|
|
|
|
2017-04-30 20:27:02 -04:00
|
|
|
|
for(int i = 0; i < entryPoints.Length && entryPoints[i] >= 0; i++) {
|
2016-11-26 14:15:50 -05:00
|
|
|
|
Int32 entryPoint = entryPoints[i];
|
|
|
|
|
ListViewItem item;
|
|
|
|
|
if(!_functions.TryGetValue(entryPoint, out item)) {
|
|
|
|
|
CodeLabel label = LabelManager.GetLabel((UInt32)entryPoint, AddressType.PrgRom);
|
2018-06-09 21:25:49 -04:00
|
|
|
|
item = new ListViewItem(label?.Label);
|
2016-11-27 10:56:37 -05:00
|
|
|
|
item.Tag = label;
|
2016-11-26 18:50:34 -05:00
|
|
|
|
|
|
|
|
|
item.SubItems.Add("[n/a]");
|
2016-11-27 10:56:37 -05:00
|
|
|
|
item.SubItems[1].Tag = -1;
|
2016-11-26 18:50:34 -05:00
|
|
|
|
item.ForeColor = Color.Gray;
|
2018-06-09 21:25:49 -04:00
|
|
|
|
|
|
|
|
|
if(italicFont == null) {
|
|
|
|
|
italicFont = new Font(item.Font, FontStyle.Italic);
|
|
|
|
|
}
|
|
|
|
|
item.Font = italicFont;
|
2016-11-26 18:50:34 -05:00
|
|
|
|
|
2016-11-26 14:15:50 -05:00
|
|
|
|
item.SubItems.Add("$" + entryPoint.ToString("X4"));
|
|
|
|
|
item.SubItems[2].Tag = entryPoint;
|
|
|
|
|
|
2018-06-09 21:25:49 -04:00
|
|
|
|
_listItems.Add(item);
|
2016-11-26 14:15:50 -05:00
|
|
|
|
_functions[entryPoint] = item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress((UInt32)entryPoint, AddressType.PrgRom);
|
2016-11-27 10:56:37 -05:00
|
|
|
|
if(relativeAddress != (Int32)item.SubItems[1].Tag) {
|
2016-11-26 14:15:50 -05:00
|
|
|
|
if(relativeAddress >= 0) {
|
|
|
|
|
item.SubItems[1].Text = "$" + relativeAddress.ToString("X4");
|
|
|
|
|
item.ForeColor = Color.Black;
|
2018-06-09 21:25:49 -04:00
|
|
|
|
if(regularFont == null) {
|
|
|
|
|
regularFont = new Font(item.Font, FontStyle.Regular);
|
|
|
|
|
}
|
|
|
|
|
item.Font = regularFont;
|
2016-11-26 14:15:50 -05:00
|
|
|
|
} else {
|
|
|
|
|
item.SubItems[1].Text = "[n/a]";
|
|
|
|
|
item.ForeColor = Color.Gray;
|
2018-06-09 21:25:49 -04:00
|
|
|
|
if(italicFont == null) {
|
|
|
|
|
italicFont = new Font(item.Font, FontStyle.Italic);
|
|
|
|
|
}
|
|
|
|
|
item.Font = italicFont;
|
2016-11-26 14:15:50 -05:00
|
|
|
|
}
|
2016-11-27 10:56:37 -05:00
|
|
|
|
item.SubItems[1].Tag = relativeAddress;
|
2016-11-20 13:15:37 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-26 14:15:50 -05:00
|
|
|
|
|
2018-06-09 21:25:49 -04:00
|
|
|
|
lstFunctions.BeginUpdate();
|
|
|
|
|
_listItems.Sort(CompareFunctions);
|
|
|
|
|
lstFunctions.VirtualMode = true;
|
|
|
|
|
lstFunctions.VirtualListSize = _listItems.Count;
|
|
|
|
|
lstFunctions.EndUpdate();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ListViewItem GetSelectedItem()
|
|
|
|
|
{
|
|
|
|
|
return _listItems[lstFunctions.SelectedIndices[0]];
|
2016-11-20 13:15:37 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void lstFunctions_DoubleClick(object sender, EventArgs e)
|
|
|
|
|
{
|
2018-06-09 21:25:49 -04:00
|
|
|
|
if(lstFunctions.SelectedIndices.Count > 0) {
|
|
|
|
|
Int32 relativeAddress = (Int32)GetSelectedItem().SubItems[1].Tag;
|
2016-11-20 13:15:37 -05:00
|
|
|
|
|
|
|
|
|
if(relativeAddress >= 0) {
|
|
|
|
|
OnFunctionSelected?.Invoke(relativeAddress, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-27 10:56:37 -05:00
|
|
|
|
|
|
|
|
|
private void mnuEditLabel_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2018-06-09 21:25:49 -04:00
|
|
|
|
if(lstFunctions.SelectedIndices.Count > 0) {
|
|
|
|
|
CodeLabel label = GetSelectedItem().Tag as CodeLabel;
|
2016-12-03 09:57:58 -05:00
|
|
|
|
if(label != null) {
|
|
|
|
|
ctrlLabelList.EditLabel(label.Address, label.AddressType);
|
|
|
|
|
} else {
|
2018-06-09 21:25:49 -04:00
|
|
|
|
ctrlLabelList.EditLabel((UInt32)(Int32)GetSelectedItem().SubItems[2].Tag, AddressType.PrgRom);
|
2016-12-03 09:57:58 -05:00
|
|
|
|
}
|
2016-11-27 10:56:37 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void mnuFindOccurrences_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2018-06-09 21:25:49 -04:00
|
|
|
|
if(lstFunctions.SelectedIndices.Count > 0) {
|
|
|
|
|
int relativeAddress = (int)GetSelectedItem().SubItems[1].Tag;
|
2017-12-29 13:08:43 -05:00
|
|
|
|
if(relativeAddress >= 0) {
|
2018-06-09 21:25:49 -04:00
|
|
|
|
CodeLabel label = GetSelectedItem().Tag as CodeLabel;
|
2017-12-29 13:08:43 -05:00
|
|
|
|
if(label != null) {
|
|
|
|
|
OnFindOccurrence?.Invoke(label.Label, null);
|
|
|
|
|
} else {
|
2018-06-09 21:25:49 -04:00
|
|
|
|
OnFindOccurrence?.Invoke("$" + ((int)GetSelectedItem().SubItems[1].Tag).ToString("X4"), null);
|
2017-12-29 13:08:43 -05:00
|
|
|
|
}
|
2017-12-21 15:12:37 -05:00
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-27 10:56:37 -05:00
|
|
|
|
}
|
2018-03-10 09:58:24 -05:00
|
|
|
|
|
|
|
|
|
private void lstFunctions_SelectedIndexChanged(object sender, EventArgs e)
|
2016-11-27 10:56:37 -05:00
|
|
|
|
{
|
2018-06-09 21:25:49 -04:00
|
|
|
|
mnuEditLabel.Enabled = lstFunctions.SelectedIndices.Count == 1;
|
|
|
|
|
mnuFindOccurrences.Enabled = lstFunctions.SelectedIndices.Count == 1;
|
|
|
|
|
if(lstFunctions.SelectedIndices.Count == 1) {
|
|
|
|
|
int relativeAddress = (int)GetSelectedItem().SubItems[1].Tag;
|
2017-12-29 13:08:43 -05:00
|
|
|
|
if(relativeAddress < 0) {
|
|
|
|
|
mnuFindOccurrences.Enabled = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-27 10:56:37 -05:00
|
|
|
|
}
|
2017-12-21 15:12:37 -05:00
|
|
|
|
|
|
|
|
|
private void mnuAddBreakpoint_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
2018-06-09 21:25:49 -04:00
|
|
|
|
if(lstFunctions.SelectedIndices.Count > 0) {
|
|
|
|
|
int absoluteAddress = (int)GetSelectedItem().SubItems[2].Tag;
|
2017-12-21 15:12:37 -05:00
|
|
|
|
BreakpointManager.AddBreakpoint(new Breakpoint() {
|
2018-02-10 21:23:22 -05:00
|
|
|
|
MemoryType = DebugMemoryType.PrgRom,
|
2017-12-21 15:12:37 -05:00
|
|
|
|
BreakOnExec = true,
|
|
|
|
|
BreakOnRead = false,
|
|
|
|
|
BreakOnWrite = false,
|
|
|
|
|
Address = (UInt32)absoluteAddress,
|
|
|
|
|
StartAddress = (UInt32)absoluteAddress,
|
|
|
|
|
EndAddress = (UInt32)absoluteAddress,
|
2018-02-10 21:23:22 -05:00
|
|
|
|
AddressType = BreakpointAddressType.SingleAddress
|
2017-12-21 15:12:37 -05:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-09 21:25:49 -04:00
|
|
|
|
|
|
|
|
|
private void lstFunctions_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
e.Item = _listItems[e.ItemIndex];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void lstFunctions_SearchForVirtualItem(object sender, SearchForVirtualItemEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
2016-11-20 13:15:37 -05:00
|
|
|
|
}
|
|
|
|
|
}
|