diff --git a/GUI.NET/Debugger/Controls/CodeViewerActions.cs b/GUI.NET/Debugger/Controls/CodeViewerActions.cs index 57bafab5..35fb965c 100644 --- a/GUI.NET/Debugger/Controls/CodeViewerActions.cs +++ b/GUI.NET/Debugger/Controls/CodeViewerActions.cs @@ -20,13 +20,14 @@ namespace Mesen.GUI.Debugger.Controls private int _lastClickedAddress = Int32.MaxValue; private Ld65DbgImporter.SymbolInfo _lastClickedSymbol = null; + private CodeLabel _lastClickedLabel = null; private string _newWatchValue = string.Empty; private string _lastWord = string.Empty; private Point _lastLocation = Point.Empty; private DebugViewInfo _config; public ICodeViewer Viewer { get; set; } - public bool SourceView { get; private set; } + public bool IsSourceView { get; private set; } public CodeViewerActions() { @@ -36,7 +37,7 @@ namespace Mesen.GUI.Debugger.Controls public CodeViewerActions(ICodeViewer viewer, bool isSourceView) : this() { Viewer = viewer; - SourceView = isSourceView; + IsSourceView = isSourceView; this.InitShortcuts(); } @@ -55,7 +56,7 @@ namespace Mesen.GUI.Debugger.Controls mnuSwitchView.InitShortcut(parent, nameof(DebuggerShortcutsConfig.CodeWindow_SwitchView)); - if(!SourceView) { + if(!IsSourceView) { mnuNavigateBackward.InitShortcut(parent, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateBack)); mnuNavigateForward.InitShortcut(parent, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateForward)); @@ -211,6 +212,19 @@ namespace Mesen.GUI.Debugger.Controls GoToLocation(); } + private GoToDestination GetDestination() + { + Ld65DbgImporter.DefinitionInfo definitionInfo = _lastClickedSymbol != null ? Viewer.SymbolProvider?.GetSymbolDefinition(_lastClickedSymbol) : null; + AddressTypeInfo addressInfo = _lastClickedSymbol != null ? Viewer.SymbolProvider?.GetSymbolAddressInfo(_lastClickedSymbol) : null; + return new GoToDestination() { + CpuAddress = _lastClickedAddress >= 0 ? _lastClickedAddress : (addressInfo != null ? InteropEmu.DebugGetRelativeAddress((UInt32)addressInfo.Address, addressInfo.Type) : -1), + Label = _lastClickedLabel, + AddressInfo = addressInfo, + File = definitionInfo?.FileName, + Line = definitionInfo?.Line ?? 0 + }; + } + private void GoToLocation() { if(_lastClickedSymbol != null && Viewer is ctrlSourceViewer) { @@ -219,9 +233,9 @@ namespace Mesen.GUI.Debugger.Controls ((ctrlSourceViewer)Viewer).ScrollToFileLine(def.FileName, def.Line); return; } - } - - if(_lastClickedAddress >= 0) { + } else if(_lastClickedLabel != null) { + Viewer.ScrollToAddress(new AddressTypeInfo() { Address = (int)_lastClickedLabel.Address, Type = _lastClickedLabel.AddressType }); + } else if(_lastClickedAddress >= 0) { Viewer.ScrollToLineNumber((int)_lastClickedAddress); } } @@ -243,15 +257,7 @@ namespace Mesen.GUI.Debugger.Controls private void ShowInSplitView() { - if(_lastClickedAddress >= 0) { - this.OnShowInSplitView?.Invoke(Viewer, new AddressEventArgs() { Address = (UInt32)_lastClickedAddress }); - } else if(_lastClickedSymbol != null) { - AddressTypeInfo info = Viewer.SymbolProvider.GetSymbolAddressInfo(_lastClickedSymbol); - if(info != null && info.Address >= 0) { - int relAddress = InteropEmu.DebugGetRelativeAddress((UInt32)info.Address, info.Type); - this.OnShowInSplitView?.Invoke(Viewer, new AddressEventArgs() { Address = (UInt32)relAddress }); - } - } + this.OnShowInSplitView?.Invoke(Viewer, GetDestination()); } private void mnuEditLabel_Click(object sender, EventArgs e) @@ -263,6 +269,8 @@ namespace Mesen.GUI.Debugger.Controls if(info.Address >= 0) { ctrlLabelList.EditLabel((UInt32)info.Address, info.Type); } + } else if(_lastClickedLabel != null) { + ctrlLabelList.EditLabel(_lastClickedLabel.Address, _lastClickedLabel.AddressType); } else if(_lastClickedSymbol != null) { AddressTypeInfo info = Viewer.SymbolProvider.GetSymbolAddressInfo(_lastClickedSymbol); if(info != null && info.Address >= 0) { @@ -407,14 +415,7 @@ namespace Mesen.GUI.Debugger.Controls private void mnuEditInMemoryViewer_Click(object sender, EventArgs e) { if(UpdateContextMenu(_lastLocation)) { - if(_lastClickedAddress >= 0) { - DebugWindowManager.OpenMemoryViewer(_lastClickedAddress, DebugMemoryType.CpuMemory); - } else { - AddressTypeInfo info = Viewer.SymbolProvider.GetSymbolAddressInfo(_lastClickedSymbol); - if(info != null && info.Address >= 0) { - DebugWindowManager.OpenMemoryViewer(info.Address, info.Type.ToMemoryType()); - } - } + DebugWindowManager.OpenMemoryViewer(GetDestination()); } } @@ -470,7 +471,7 @@ namespace Mesen.GUI.Debugger.Controls items[nameof(mnuSwitchView)].Visible = hasSymbolProvider; items[nameof(sepSwitchView)].Visible = hasSymbolProvider; - if(SourceView) { + if(IsSourceView) { items[nameof(mnuMarkSelectionAs)].Visible = false; items[nameof(mnuFindOccurrences)].Visible = false; @@ -491,7 +492,7 @@ namespace Mesen.GUI.Debugger.Controls UpdateContextMenuItemVisibility(contextMenu.Items, true); - mnuSwitchView.Text = SourceView ? "Switch to Disassembly View" : "Switch to Source View"; + mnuSwitchView.Text = IsSourceView ? "Switch to Disassembly View" : "Switch to Source View"; string word = Viewer.CodeViewer.GetWordUnderLocation(mouseLocation); Ld65DbgImporter.SymbolInfo symbol = null; @@ -500,13 +501,10 @@ namespace Mesen.GUI.Debugger.Controls if(!word.StartsWith("$")) { codeLabel = LabelManager.GetLabel(word); - if(Viewer.SymbolProvider != null) { + if(Viewer.SymbolProvider != null && IsSourceView) { int rangeStart, rangeEnd; if(Viewer.CodeViewer.GetNoteRangeAtLocation(mouseLocation.Y, out rangeStart, out rangeEnd)) { symbol = Viewer.SymbolProvider.GetSymbol(word, rangeStart, rangeEnd); - if(symbol?.SegmentID == null) { - symbol = null; - } } } } @@ -519,15 +517,18 @@ namespace Mesen.GUI.Debugger.Controls //CPU Address _lastClickedAddress = Int32.Parse(word.Substring(1), NumberStyles.AllowHexSpecifier); _lastClickedSymbol = null; + _lastClickedLabel = null; _newWatchValue = "[$" + _lastClickedAddress.ToString("X") + "]"; } else if(symbol != null) { //Symbol _lastClickedAddress = -1; + _lastClickedLabel = null; _lastClickedSymbol = symbol; _newWatchValue = "[" + word + "]"; } else if(codeLabel != null) { //Label - _lastClickedAddress = (Int32)InteropEmu.DebugGetRelativeAddress(codeLabel.Address, codeLabel.AddressType); + _lastClickedLabel = codeLabel; + _lastClickedAddress = -1; _lastClickedSymbol = null; _newWatchValue = "[" + word + "]"; } @@ -565,6 +566,7 @@ namespace Mesen.GUI.Debugger.Controls mnuEditInMemoryViewer.Enabled = false; mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer"; + _lastClickedLabel = null; _lastClickedSymbol = null; if(mouseLocation.X < Viewer.CodeViewer.CodeMargin) { _lastClickedAddress = Viewer.CodeViewer.GetLineNumberAtPosition(mouseLocation.Y); diff --git a/GUI.NET/Debugger/Controls/ICodeViewer.cs b/GUI.NET/Debugger/Controls/ICodeViewer.cs index 7c98375d..f651e43c 100644 --- a/GUI.NET/Debugger/Controls/ICodeViewer.cs +++ b/GUI.NET/Debugger/Controls/ICodeViewer.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace Mesen.GUI.Debugger.Controls { public delegate void SetNextStatementEventHandler(AddressEventArgs args); - public delegate void ShowInSplitViewEventHandler(ICodeViewer sender, AddressEventArgs args); + public delegate void ShowInSplitViewEventHandler(ICodeViewer sender, GoToDestination dest); public delegate void SwitchToSourceEventHandler(ICodeViewer sender); public interface ICodeViewer diff --git a/GUI.NET/Debugger/DebugWindowManager.cs b/GUI.NET/Debugger/DebugWindowManager.cs index 781d1bbc..2d6bb185 100644 --- a/GUI.NET/Debugger/DebugWindowManager.cs +++ b/GUI.NET/Debugger/DebugWindowManager.cs @@ -47,7 +47,7 @@ namespace Mesen.GUI.Debugger frm.Show(); } - public static void OpenMemoryViewer(int address, DebugMemoryType memoryType) + private static frmMemoryViewer OpenMemoryViewer() { frmMemoryViewer frm = GetMemoryViewer(); if(frm == null) { @@ -56,9 +56,21 @@ namespace Mesen.GUI.Debugger _openedWindows.Add(frm); } frm.Show(); + return frm; + } + + public static void OpenMemoryViewer(int address, DebugMemoryType memoryType) + { + frmMemoryViewer frm = OpenMemoryViewer(); frm.ShowAddress(address, memoryType); } + public static void OpenMemoryViewer(GoToDestination dest) + { + frmMemoryViewer frm = OpenMemoryViewer(); + frm.GoToDestination(dest); + } + public static frmScript OpenScriptWindow(bool forceBlank) { frmScript frm = new frmScript(forceBlank); diff --git a/GUI.NET/Debugger/frmDebugger.cs b/GUI.NET/Debugger/frmDebugger.cs index d1550318..d818dbf2 100644 --- a/GUI.NET/Debugger/frmDebugger.cs +++ b/GUI.NET/Debugger/frmDebugger.cs @@ -606,7 +606,7 @@ namespace Mesen.GUI.Debugger _previousCycle = state.CPU.CycleCount; if(UpdateSplitView()) { - if(newCode != null || ctrlDebuggerCodeSplit.Code == null) { + if(ctrlDebuggerCodeSplit.Code != ctrlDebuggerCode.Code) { ctrlDebuggerCodeSplit.Code = ctrlDebuggerCode.Code; } } else { @@ -756,7 +756,7 @@ namespace Mesen.GUI.Debugger InteropEmu.DebugPpuStep((UInt32)cycleCount); } - private void ctrlDebuggerCode_OnShowInSplitView(ICodeViewer sender, AddressEventArgs args) + private void ctrlDebuggerCode_OnShowInSplitView(ICodeViewer sender, GoToDestination dest) { if(!ConfigManager.Config.DebugInfo.SplitView) { mnuSplitView.Checked = true; @@ -765,18 +765,17 @@ namespace Mesen.GUI.Debugger UpdateDebugger(false); } - UInt16 addr = (UInt16)args.Address; if(sender == ctrlDebuggerCode || sender == ctrlSourceViewer) { if(ctrlSourceViewerSplit.Visible) { - ctrlSourceViewerSplit.ScrollToLineNumber(addr); + GoToDestination(ctrlSourceViewerSplit, dest); } else { - ctrlDebuggerCodeSplit.ScrollToLineNumber(addr); + GoToDestination(ctrlDebuggerCodeSplit, dest); } } else { if(ctrlSourceViewer.Visible) { - ctrlSourceViewer.ScrollToLineNumber(addr); + GoToDestination(ctrlSourceViewer, dest); } else { - ctrlDebuggerCode.ScrollToLineNumber(addr); + GoToDestination(ctrlDebuggerCode, dest); } } } @@ -1728,24 +1727,44 @@ namespace Mesen.GUI.Debugger } } + private ICodeViewer GetAlternateView(ICodeViewer viewer) + { + if(viewer == ctrlDebuggerCode) { + return ctrlSourceViewer; + } else if(viewer == ctrlSourceViewer) { + return ctrlDebuggerCode; + } else if(viewer == ctrlDebuggerCodeSplit) { + return ctrlSourceViewerSplit; + } else if(viewer == ctrlSourceViewerSplit) { + return ctrlDebuggerCodeSplit; + } + return null; + } + + private void GoToDestination(ICodeViewer target, GoToDestination dest) + { + if(target is ctrlSourceViewer && !string.IsNullOrWhiteSpace(dest.File)) { + ((ctrlSourceViewer)target).ScrollToFileLine(dest.File, dest.Line); + } else if(dest.Label != null && dest.Label.GetRelativeAddress() >= 0) { + target.ScrollToAddress(new AddressTypeInfo() { Address = (int)dest.Label.Address, Type = dest.Label.AddressType }); + } else if(!string.IsNullOrWhiteSpace(dest.File)) { + if(!(target is ctrlSourceViewer)) { + ctrlDebuggerCode_OnSwitchView(target); + target = GetAlternateView(target); + } + if(target is ctrlSourceViewer) { + ((ctrlSourceViewer)target).ScrollToFileLine(dest.File, dest.Line); + } + } else if(dest.CpuAddress >= 0) { + target.ScrollToLineNumber(dest.CpuAddress); + } + } + private void mnuGoToAll_Click(object sender, EventArgs e) { using(frmGoToAll frm = new frmGoToAll(false, true)) { if(frm.ShowDialog() == DialogResult.OK) { - frmGoToAll.GoToDestination dest = frm.Destination; - - if(_lastCodeWindow is ctrlSourceViewer && !string.IsNullOrWhiteSpace(dest.File)) { - ((ctrlSourceViewer)_lastCodeWindow).ScrollToFileLine(dest.File, dest.Line); - } else if(dest.Label != null && dest.Label.GetRelativeAddress() >= 0) { - _lastCodeWindow.ScrollToAddress(new AddressTypeInfo() { Address = (int)dest.Label.Address, Type = dest.Label.AddressType }); - } else if(!string.IsNullOrWhiteSpace(dest.File)) { - if(!(_lastCodeWindow is ctrlSourceViewer)) { - ctrlDebuggerCode_OnSwitchView(_lastCodeWindow); - } - if(_lastCodeWindow is ctrlSourceViewer) { - ((ctrlSourceViewer)_lastCodeWindow).ScrollToFileLine(dest.File, dest.Line); - } - } + GoToDestination(_lastCodeWindow, frm.Destination); if(Program.IsMono) { //Delay by 150ms before giving focus when running on Mono diff --git a/GUI.NET/Debugger/frmGoToAll.cs b/GUI.NET/Debugger/frmGoToAll.cs index 4583de0e..432ffa36 100644 --- a/GUI.NET/Debugger/frmGoToAll.cs +++ b/GUI.NET/Debugger/frmGoToAll.cs @@ -298,14 +298,14 @@ namespace Mesen.GUI.Debugger } } } + } - public struct GoToDestination - { - public CodeLabel Label; - public AddressTypeInfo AddressInfo; - public int CpuAddress; - public string File; - public int Line; - } + public struct GoToDestination + { + public CodeLabel Label; + public AddressTypeInfo AddressInfo; + public int CpuAddress; + public string File; + public int Line; } } diff --git a/GUI.NET/Debugger/frmMemoryViewer.cs b/GUI.NET/Debugger/frmMemoryViewer.cs index 3c75ad3a..c9156a6d 100644 --- a/GUI.NET/Debugger/frmMemoryViewer.cs +++ b/GUI.NET/Debugger/frmMemoryViewer.cs @@ -196,30 +196,37 @@ namespace Mesen.GUI.Debugger public void ShowAddress(int address, DebugMemoryType memoryType) { + if(memoryType == DebugMemoryType.InternalRam) { + //There is no specific "tab" for the internal ram, show it in the cpu memory tab + memoryType = DebugMemoryType.CpuMemory; + } + tabMain.SelectedTab = tpgMemoryViewer; cboMemoryType.SetEnumValue(memoryType); ctrlHexViewer.GoToAddress(address); } + public void GoToDestination(GoToDestination dest) + { + if(_memoryType == DebugMemoryType.CpuMemory && dest.CpuAddress >= 0) { + this.ShowAddress(dest.CpuAddress, DebugMemoryType.CpuMemory); + } else if(dest.AddressInfo != null) { + this.ShowAddress(dest.AddressInfo.Address, dest.AddressInfo.Type.ToMemoryType()); + } else if(dest.Label != null) { + int relAddress = dest.Label.GetRelativeAddress(); + if(_memoryType == DebugMemoryType.CpuMemory && relAddress >= 0) { + this.ShowAddress(relAddress, DebugMemoryType.CpuMemory); + } else { + this.ShowAddress((int)dest.Label.Address, dest.Label.AddressType.ToMemoryType()); + } + } + } + public void GoToAll() { using(frmGoToAll frm = new frmGoToAll(true, false)) { if(frm.ShowDialog() == DialogResult.OK) { - frmGoToAll.GoToDestination dest = frm.Destination; - - tabMain.SelectedTab = tpgMemoryViewer; - if(_memoryType == DebugMemoryType.CpuMemory && dest.CpuAddress >= 0) { - ctrlHexViewer.GoToAddress(dest.CpuAddress); - } else { - DebugMemoryType memType = dest.AddressInfo.Type.ToMemoryType(); - if(memType == DebugMemoryType.InternalRam) { - //There is no specific "tab" for the internal ram, show it in the cpu memory tab - memType = DebugMemoryType.CpuMemory; - } - - cboMemoryType.SetEnumValue(memType); - ctrlHexViewer.GoToAddress(dest.AddressInfo.Address); - } + GoToDestination(frm.Destination); } } }