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 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);

View file

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

View file

@ -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);

View file

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

View file

@ -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;
}
}

View file

@ -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);
}
}
}