Debugger: Fixed some issues with "Show in split view" option

This commit is contained in:
Sour 2019-01-01 16:00:45 -05:00
parent 413cf7a212
commit 57a4435443
6 changed files with 116 additions and 76 deletions

View file

@ -20,13 +20,14 @@ namespace Mesen.GUI.Debugger.Controls
private int _lastClickedAddress = Int32.MaxValue; private int _lastClickedAddress = Int32.MaxValue;
private Ld65DbgImporter.SymbolInfo _lastClickedSymbol = null; private Ld65DbgImporter.SymbolInfo _lastClickedSymbol = null;
private CodeLabel _lastClickedLabel = null;
private string _newWatchValue = string.Empty; private string _newWatchValue = string.Empty;
private string _lastWord = string.Empty; private string _lastWord = string.Empty;
private Point _lastLocation = Point.Empty; private Point _lastLocation = Point.Empty;
private DebugViewInfo _config; private DebugViewInfo _config;
public ICodeViewer Viewer { get; set; } public ICodeViewer Viewer { get; set; }
public bool SourceView { get; private set; } public bool IsSourceView { get; private set; }
public CodeViewerActions() public CodeViewerActions()
{ {
@ -36,7 +37,7 @@ namespace Mesen.GUI.Debugger.Controls
public CodeViewerActions(ICodeViewer viewer, bool isSourceView) : this() public CodeViewerActions(ICodeViewer viewer, bool isSourceView) : this()
{ {
Viewer = viewer; Viewer = viewer;
SourceView = isSourceView; IsSourceView = isSourceView;
this.InitShortcuts(); this.InitShortcuts();
} }
@ -55,7 +56,7 @@ namespace Mesen.GUI.Debugger.Controls
mnuSwitchView.InitShortcut(parent, nameof(DebuggerShortcutsConfig.CodeWindow_SwitchView)); mnuSwitchView.InitShortcut(parent, nameof(DebuggerShortcutsConfig.CodeWindow_SwitchView));
if(!SourceView) { if(!IsSourceView) {
mnuNavigateBackward.InitShortcut(parent, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateBack)); mnuNavigateBackward.InitShortcut(parent, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateBack));
mnuNavigateForward.InitShortcut(parent, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateForward)); mnuNavigateForward.InitShortcut(parent, nameof(DebuggerShortcutsConfig.CodeWindow_NavigateForward));
@ -211,6 +212,19 @@ namespace Mesen.GUI.Debugger.Controls
GoToLocation(); 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() private void GoToLocation()
{ {
if(_lastClickedSymbol != null && Viewer is ctrlSourceViewer) { if(_lastClickedSymbol != null && Viewer is ctrlSourceViewer) {
@ -219,9 +233,9 @@ namespace Mesen.GUI.Debugger.Controls
((ctrlSourceViewer)Viewer).ScrollToFileLine(def.FileName, def.Line); ((ctrlSourceViewer)Viewer).ScrollToFileLine(def.FileName, def.Line);
return; return;
} }
} } else if(_lastClickedLabel != null) {
Viewer.ScrollToAddress(new AddressTypeInfo() { Address = (int)_lastClickedLabel.Address, Type = _lastClickedLabel.AddressType });
if(_lastClickedAddress >= 0) { } else if(_lastClickedAddress >= 0) {
Viewer.ScrollToLineNumber((int)_lastClickedAddress); Viewer.ScrollToLineNumber((int)_lastClickedAddress);
} }
} }
@ -243,15 +257,7 @@ namespace Mesen.GUI.Debugger.Controls
private void ShowInSplitView() private void ShowInSplitView()
{ {
if(_lastClickedAddress >= 0) { this.OnShowInSplitView?.Invoke(Viewer, GetDestination());
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 });
}
}
} }
private void mnuEditLabel_Click(object sender, EventArgs e) private void mnuEditLabel_Click(object sender, EventArgs e)
@ -263,6 +269,8 @@ namespace Mesen.GUI.Debugger.Controls
if(info.Address >= 0) { if(info.Address >= 0) {
ctrlLabelList.EditLabel((UInt32)info.Address, info.Type); ctrlLabelList.EditLabel((UInt32)info.Address, info.Type);
} }
} else if(_lastClickedLabel != null) {
ctrlLabelList.EditLabel(_lastClickedLabel.Address, _lastClickedLabel.AddressType);
} else if(_lastClickedSymbol != null) { } else if(_lastClickedSymbol != null) {
AddressTypeInfo info = Viewer.SymbolProvider.GetSymbolAddressInfo(_lastClickedSymbol); AddressTypeInfo info = Viewer.SymbolProvider.GetSymbolAddressInfo(_lastClickedSymbol);
if(info != null && info.Address >= 0) { if(info != null && info.Address >= 0) {
@ -407,14 +415,7 @@ namespace Mesen.GUI.Debugger.Controls
private void mnuEditInMemoryViewer_Click(object sender, EventArgs e) private void mnuEditInMemoryViewer_Click(object sender, EventArgs e)
{ {
if(UpdateContextMenu(_lastLocation)) { if(UpdateContextMenu(_lastLocation)) {
if(_lastClickedAddress >= 0) { DebugWindowManager.OpenMemoryViewer(GetDestination());
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());
}
}
} }
} }
@ -470,7 +471,7 @@ namespace Mesen.GUI.Debugger.Controls
items[nameof(mnuSwitchView)].Visible = hasSymbolProvider; items[nameof(mnuSwitchView)].Visible = hasSymbolProvider;
items[nameof(sepSwitchView)].Visible = hasSymbolProvider; items[nameof(sepSwitchView)].Visible = hasSymbolProvider;
if(SourceView) { if(IsSourceView) {
items[nameof(mnuMarkSelectionAs)].Visible = false; items[nameof(mnuMarkSelectionAs)].Visible = false;
items[nameof(mnuFindOccurrences)].Visible = false; items[nameof(mnuFindOccurrences)].Visible = false;
@ -491,7 +492,7 @@ namespace Mesen.GUI.Debugger.Controls
UpdateContextMenuItemVisibility(contextMenu.Items, true); 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); string word = Viewer.CodeViewer.GetWordUnderLocation(mouseLocation);
Ld65DbgImporter.SymbolInfo symbol = null; Ld65DbgImporter.SymbolInfo symbol = null;
@ -500,13 +501,10 @@ namespace Mesen.GUI.Debugger.Controls
if(!word.StartsWith("$")) { if(!word.StartsWith("$")) {
codeLabel = LabelManager.GetLabel(word); codeLabel = LabelManager.GetLabel(word);
if(Viewer.SymbolProvider != null) { if(Viewer.SymbolProvider != null && IsSourceView) {
int rangeStart, rangeEnd; int rangeStart, rangeEnd;
if(Viewer.CodeViewer.GetNoteRangeAtLocation(mouseLocation.Y, out rangeStart, out rangeEnd)) { if(Viewer.CodeViewer.GetNoteRangeAtLocation(mouseLocation.Y, out rangeStart, out rangeEnd)) {
symbol = Viewer.SymbolProvider.GetSymbol(word, rangeStart, 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 //CPU Address
_lastClickedAddress = Int32.Parse(word.Substring(1), NumberStyles.AllowHexSpecifier); _lastClickedAddress = Int32.Parse(word.Substring(1), NumberStyles.AllowHexSpecifier);
_lastClickedSymbol = null; _lastClickedSymbol = null;
_lastClickedLabel = null;
_newWatchValue = "[$" + _lastClickedAddress.ToString("X") + "]"; _newWatchValue = "[$" + _lastClickedAddress.ToString("X") + "]";
} else if(symbol != null) { } else if(symbol != null) {
//Symbol //Symbol
_lastClickedAddress = -1; _lastClickedAddress = -1;
_lastClickedLabel = null;
_lastClickedSymbol = symbol; _lastClickedSymbol = symbol;
_newWatchValue = "[" + word + "]"; _newWatchValue = "[" + word + "]";
} else if(codeLabel != null) { } else if(codeLabel != null) {
//Label //Label
_lastClickedAddress = (Int32)InteropEmu.DebugGetRelativeAddress(codeLabel.Address, codeLabel.AddressType); _lastClickedLabel = codeLabel;
_lastClickedAddress = -1;
_lastClickedSymbol = null; _lastClickedSymbol = null;
_newWatchValue = "[" + word + "]"; _newWatchValue = "[" + word + "]";
} }
@ -565,6 +566,7 @@ namespace Mesen.GUI.Debugger.Controls
mnuEditInMemoryViewer.Enabled = false; mnuEditInMemoryViewer.Enabled = false;
mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer"; mnuEditInMemoryViewer.Text = $"Edit in Memory Viewer";
_lastClickedLabel = null;
_lastClickedSymbol = null; _lastClickedSymbol = null;
if(mouseLocation.X < Viewer.CodeViewer.CodeMargin) { if(mouseLocation.X < Viewer.CodeViewer.CodeMargin) {
_lastClickedAddress = Viewer.CodeViewer.GetLineNumberAtPosition(mouseLocation.Y); _lastClickedAddress = Viewer.CodeViewer.GetLineNumberAtPosition(mouseLocation.Y);

View file

@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace Mesen.GUI.Debugger.Controls namespace Mesen.GUI.Debugger.Controls
{ {
public delegate void SetNextStatementEventHandler(AddressEventArgs args); 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 delegate void SwitchToSourceEventHandler(ICodeViewer sender);
public interface ICodeViewer public interface ICodeViewer

View file

@ -47,7 +47,7 @@ namespace Mesen.GUI.Debugger
frm.Show(); frm.Show();
} }
public static void OpenMemoryViewer(int address, DebugMemoryType memoryType) private static frmMemoryViewer OpenMemoryViewer()
{ {
frmMemoryViewer frm = GetMemoryViewer(); frmMemoryViewer frm = GetMemoryViewer();
if(frm == null) { if(frm == null) {
@ -56,9 +56,21 @@ namespace Mesen.GUI.Debugger
_openedWindows.Add(frm); _openedWindows.Add(frm);
} }
frm.Show(); frm.Show();
return frm;
}
public static void OpenMemoryViewer(int address, DebugMemoryType memoryType)
{
frmMemoryViewer frm = OpenMemoryViewer();
frm.ShowAddress(address, memoryType); frm.ShowAddress(address, memoryType);
} }
public static void OpenMemoryViewer(GoToDestination dest)
{
frmMemoryViewer frm = OpenMemoryViewer();
frm.GoToDestination(dest);
}
public static frmScript OpenScriptWindow(bool forceBlank) public static frmScript OpenScriptWindow(bool forceBlank)
{ {
frmScript frm = new frmScript(forceBlank); frmScript frm = new frmScript(forceBlank);

View file

@ -606,7 +606,7 @@ namespace Mesen.GUI.Debugger
_previousCycle = state.CPU.CycleCount; _previousCycle = state.CPU.CycleCount;
if(UpdateSplitView()) { if(UpdateSplitView()) {
if(newCode != null || ctrlDebuggerCodeSplit.Code == null) { if(ctrlDebuggerCodeSplit.Code != ctrlDebuggerCode.Code) {
ctrlDebuggerCodeSplit.Code = ctrlDebuggerCode.Code; ctrlDebuggerCodeSplit.Code = ctrlDebuggerCode.Code;
} }
} else { } else {
@ -756,7 +756,7 @@ namespace Mesen.GUI.Debugger
InteropEmu.DebugPpuStep((UInt32)cycleCount); 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) { if(!ConfigManager.Config.DebugInfo.SplitView) {
mnuSplitView.Checked = true; mnuSplitView.Checked = true;
@ -765,18 +765,17 @@ namespace Mesen.GUI.Debugger
UpdateDebugger(false); UpdateDebugger(false);
} }
UInt16 addr = (UInt16)args.Address;
if(sender == ctrlDebuggerCode || sender == ctrlSourceViewer) { if(sender == ctrlDebuggerCode || sender == ctrlSourceViewer) {
if(ctrlSourceViewerSplit.Visible) { if(ctrlSourceViewerSplit.Visible) {
ctrlSourceViewerSplit.ScrollToLineNumber(addr); GoToDestination(ctrlSourceViewerSplit, dest);
} else { } else {
ctrlDebuggerCodeSplit.ScrollToLineNumber(addr); GoToDestination(ctrlDebuggerCodeSplit, dest);
} }
} else { } else {
if(ctrlSourceViewer.Visible) { if(ctrlSourceViewer.Visible) {
ctrlSourceViewer.ScrollToLineNumber(addr); GoToDestination(ctrlSourceViewer, dest);
} else { } 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) private void mnuGoToAll_Click(object sender, EventArgs e)
{ {
using(frmGoToAll frm = new frmGoToAll(false, true)) { using(frmGoToAll frm = new frmGoToAll(false, true)) {
if(frm.ShowDialog() == DialogResult.OK) { if(frm.ShowDialog() == DialogResult.OK) {
frmGoToAll.GoToDestination dest = frm.Destination; GoToDestination(_lastCodeWindow, 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);
}
}
if(Program.IsMono) { if(Program.IsMono) {
//Delay by 150ms before giving focus when running on Mono //Delay by 150ms before giving focus when running on Mono

View file

@ -298,14 +298,14 @@ namespace Mesen.GUI.Debugger
} }
} }
} }
}
public struct GoToDestination public struct GoToDestination
{ {
public CodeLabel Label; public CodeLabel Label;
public AddressTypeInfo AddressInfo; public AddressTypeInfo AddressInfo;
public int CpuAddress; public int CpuAddress;
public string File; public string File;
public int Line; public int Line;
}
} }
} }

View file

@ -196,30 +196,37 @@ namespace Mesen.GUI.Debugger
public void ShowAddress(int address, DebugMemoryType memoryType) 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; tabMain.SelectedTab = tpgMemoryViewer;
cboMemoryType.SetEnumValue(memoryType); cboMemoryType.SetEnumValue(memoryType);
ctrlHexViewer.GoToAddress(address); 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() public void GoToAll()
{ {
using(frmGoToAll frm = new frmGoToAll(true, false)) { using(frmGoToAll frm = new frmGoToAll(true, false)) {
if(frm.ShowDialog() == DialogResult.OK) { if(frm.ShowDialog() == DialogResult.OK) {
frmGoToAll.GoToDestination dest = frm.Destination; GoToDestination(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);
}
} }
} }
} }