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; namespace Mesen.GUI.Debugger.Controls { public partial class ctrlFunctionList : UserControl { public event EventHandler OnFunctionSelected; public ctrlFunctionList() { InitializeComponent(); } private class FunctionComparer : IComparer { int IComparer.Compare(object x, object y) { ListViewItem a = x as ListViewItem; ListViewItem b = y as ListViewItem; string aText = string.IsNullOrWhiteSpace(a.Text) ? "ZZZZZZZZZZZZZZZZZZZZZZZ" : a.Text; string bText = string.IsNullOrWhiteSpace(b.Text) ? "ZZZZZZZZZZZZZZZZZZZZZZZ" : b.Text; Int32 aRelative = (Int32)a.Tag == -1 ? Int32.MaxValue : (Int32)a.Tag; Int32 bRelative = (Int32)b.Tag == -1 ? Int32.MaxValue : (Int32)b.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) { return aAbsolute > bAbsolute ? 1 : -1; } else { return aRelative > bRelative ? 1 : -1; } } else { return string.Compare(aText, bText); } } } private Dictionary _functions = new Dictionary(); public void UpdateFunctionList(bool reset) { if(reset) { lstFunctions.Items.Clear(); _functions.Clear(); } Int32[] entryPoints = InteropEmu.DebugGetFunctionEntryPoints(); bool updating = false; for(int i = 0; entryPoints[i] >= 0; i++) { Int32 entryPoint = entryPoints[i]; ListViewItem item; if(!_functions.TryGetValue(entryPoint, out item)) { if(!updating) { updating = true; lstFunctions.BeginUpdate(); lstFunctions.ListViewItemSorter = null; } CodeLabel label = LabelManager.GetLabel((UInt32)entryPoint, AddressType.PrgRom); item = lstFunctions.Items.Add(label?.Label); item.Tag = -1; item.SubItems.Add(""); item.SubItems.Add("$" + entryPoint.ToString("X4")); item.SubItems[2].Tag = entryPoint; _functions[entryPoint] = item; } Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress((UInt32)entryPoint, AddressType.PrgRom); if(relativeAddress != (Int32)item.Tag) { if(!updating) { updating = true; lstFunctions.BeginUpdate(); lstFunctions.ListViewItemSorter = null; } if(relativeAddress >= 0) { item.SubItems[1].Text = "$" + relativeAddress.ToString("X4"); item.ForeColor = Color.Black; item.Font = new Font(item.Font, FontStyle.Regular); } else { item.SubItems[1].Text = "[n/a]"; item.ForeColor = Color.Gray; item.Font = new Font(item.Font, FontStyle.Italic); } item.Tag = relativeAddress; } } if(updating) { lstFunctions.ListViewItemSorter = new FunctionComparer(); lstFunctions.Sort(); lstFunctions.EndUpdate(); } } private void lstFunctions_DoubleClick(object sender, EventArgs e) { if(lstFunctions.SelectedItems.Count > 0) { Int32 relativeAddress = (Int32)lstFunctions.SelectedItems[0].Tag; if(relativeAddress >= 0) { OnFunctionSelected?.Invoke(relativeAddress, e); } } } } }