mirror of
https://github.com/libretro/Mesen.git
synced 2024-12-16 13:56:48 +00:00
Debugger: Game-independent workspaces for debugger
This commit is contained in:
parent
a41731870f
commit
6fdaa7fedc
@ -6,6 +6,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using Mesen.GUI.Debugger;
|
||||
|
||||
namespace Mesen.GUI.Config
|
||||
@ -17,6 +18,49 @@ namespace Mesen.GUI.Config
|
||||
public float FontSize = 13;
|
||||
}
|
||||
|
||||
public class DebugWorkspace
|
||||
{
|
||||
public List<Breakpoint> Breakpoints = new List<Breakpoint>();
|
||||
public List<string> WatchValues = new List<string>();
|
||||
public List<CodeLabel> Labels = new List<CodeLabel>();
|
||||
private string _filePath;
|
||||
|
||||
public static DebugWorkspace GetWorkspace()
|
||||
{
|
||||
RomInfo info = InteropEmu.GetRomInfo();
|
||||
return Deserialize(Path.Combine(ConfigManager.DebuggerFolder, info.GetRomName() + ".Workspace.xml"));
|
||||
}
|
||||
|
||||
private static DebugWorkspace Deserialize(string path)
|
||||
{
|
||||
DebugWorkspace config = config = new DebugWorkspace();
|
||||
|
||||
if(File.Exists(path)) {
|
||||
try {
|
||||
XmlSerializer xmlSerializer = new XmlSerializer(typeof(DebugWorkspace));
|
||||
using(TextReader textReader = new StreamReader(path)) {
|
||||
config = (DebugWorkspace)xmlSerializer.Deserialize(textReader);
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
config._filePath = path;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
try {
|
||||
XmlSerializer xmlSerializer = new XmlSerializer(typeof(DebugWorkspace));
|
||||
using(TextWriter textWriter = new StreamWriter(_filePath)) {
|
||||
xmlSerializer.Serialize(textWriter, this);
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DebugInfo
|
||||
{
|
||||
public DebugViewInfo LeftView;
|
||||
@ -40,9 +84,6 @@ namespace Mesen.GUI.Config
|
||||
public int RamColumnCount = 2;
|
||||
public float RamFontSize = 13;
|
||||
|
||||
public List<Breakpoint> Breakpoints;
|
||||
public List<string> WatchValues;
|
||||
|
||||
public DebugInfo()
|
||||
{
|
||||
LeftView = new DebugViewInfo();
|
||||
|
@ -42,11 +42,11 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
|
||||
lstLabels.BeginUpdate();
|
||||
lstLabels.Items.Clear();
|
||||
foreach(KeyValuePair<string, CodeLabel> kvp in LabelManager.GetLabels()) {
|
||||
if(kvp.Value.Label.Length > 0) {
|
||||
ListViewItem item = lstLabels.Items.Add(kvp.Value.Label);
|
||||
foreach(CodeLabel label in LabelManager.GetLabels()) {
|
||||
if(label.Label.Length > 0) {
|
||||
ListViewItem item = lstLabels.Items.Add(label.Label);
|
||||
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress(kvp.Value.Address, kvp.Value.AddressType);
|
||||
Int32 relativeAddress = InteropEmu.DebugGetRelativeAddress(label.Address, label.AddressType);
|
||||
if(relativeAddress >= 0) {
|
||||
item.SubItems.Add("$" + relativeAddress.ToString("X4"));
|
||||
} else {
|
||||
@ -54,8 +54,8 @@ namespace Mesen.GUI.Debugger.Controls
|
||||
item.ForeColor = Color.Gray;
|
||||
item.Font = new Font(item.Font, FontStyle.Italic);
|
||||
}
|
||||
item.SubItems.Add("$" + kvp.Value.Address.ToString("X4"));
|
||||
item.SubItems[1].Tag = kvp.Value;
|
||||
item.SubItems.Add("$" + label.Address.ToString("X4"));
|
||||
item.SubItems[1].Tag = label;
|
||||
|
||||
item.Tag = relativeAddress;
|
||||
}
|
||||
|
@ -20,11 +20,6 @@ namespace Mesen.GUI.Debugger
|
||||
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
|
||||
if(!designMode) {
|
||||
this.mnuHexDisplay.Checked = ConfigManager.Config.DebugInfo.HexDisplay;
|
||||
|
||||
foreach(string watchValue in ConfigManager.Config.DebugInfo.WatchValues) {
|
||||
lstWatch.Items.Add(watchValue);
|
||||
}
|
||||
UpdateWatch();
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,6 +55,24 @@ namespace Mesen.GUI.Debugger
|
||||
lstWatch.ColumnWidthChanged += lstWatch_ColumnWidthChanged;
|
||||
}
|
||||
|
||||
public List<string> GetWatchValues()
|
||||
{
|
||||
List<string> watchValues = new List<string>();
|
||||
foreach(ListViewItem listView in lstWatch.Items) {
|
||||
watchValues.Add(listView.Text);
|
||||
}
|
||||
return watchValues;
|
||||
}
|
||||
|
||||
public void SetWatchValues(List<string> watchValues)
|
||||
{
|
||||
lstWatch.Items.Clear();
|
||||
foreach(string watchValue in watchValues) {
|
||||
lstWatch.Items.Add(watchValue);
|
||||
}
|
||||
UpdateWatch();
|
||||
}
|
||||
|
||||
public void UpdateWatch(int currentSelection = -1)
|
||||
{
|
||||
lstWatch.SelectedIndices.Clear();
|
||||
@ -113,13 +126,6 @@ namespace Mesen.GUI.Debugger
|
||||
lstWatch.FocusedItem = lstWatch.Items[currentSelection];
|
||||
lstWatch.Items[currentSelection].Selected = true;
|
||||
}
|
||||
|
||||
ConfigManager.Config.DebugInfo.WatchValues.Clear();
|
||||
foreach(ListViewItem item in lstWatch.Items) {
|
||||
if(!string.IsNullOrWhiteSpace(item.Text)) {
|
||||
ConfigManager.Config.DebugInfo.WatchValues.Add(item.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AddWatch(UInt32 address)
|
||||
|
@ -37,9 +37,18 @@ namespace Mesen.GUI.Debugger
|
||||
return _reverseLookup.ContainsKey(label) ? _reverseLookup[label] : null;
|
||||
}
|
||||
|
||||
public static Dictionary<string, CodeLabel> GetLabels()
|
||||
public static void SetLabels(List<CodeLabel> labels)
|
||||
{
|
||||
return _labels;
|
||||
ResetLabels();
|
||||
foreach(CodeLabel label in labels) {
|
||||
SetLabel(label.Address, label.AddressType, label.Label, label.Comment, false);
|
||||
}
|
||||
OnLabelUpdated?.Invoke(null, null);
|
||||
}
|
||||
|
||||
public static List<CodeLabel> GetLabels()
|
||||
{
|
||||
return _labels.Values.ToList<CodeLabel>();
|
||||
}
|
||||
|
||||
private static string GetKey(UInt32 address, AddressType addressType)
|
||||
@ -47,7 +56,7 @@ namespace Mesen.GUI.Debugger
|
||||
return address.ToString() + addressType.ToString();
|
||||
}
|
||||
|
||||
public static bool SetLabel(UInt32 address, AddressType type, string label, string comment)
|
||||
public static bool SetLabel(UInt32 address, AddressType type, string label, string comment, bool raiseEvent = true)
|
||||
{
|
||||
if(_labels.ContainsKey(GetKey(address, type))) {
|
||||
_reverseLookup.Remove(_labels[GetKey(address, type)].Label);
|
||||
@ -59,7 +68,9 @@ namespace Mesen.GUI.Debugger
|
||||
}
|
||||
|
||||
InteropEmu.DebugSetLabel(address, type, label, comment);
|
||||
OnLabelUpdated?.Invoke(null, null);
|
||||
if(raiseEvent) {
|
||||
OnLabelUpdated?.Invoke(null, null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -21,6 +21,8 @@ namespace Mesen.GUI.Debugger
|
||||
private ctrlDebuggerCode _lastCodeWindow;
|
||||
private frmTraceLogger _traceLogger;
|
||||
|
||||
private DebugWorkspace _workspace;
|
||||
|
||||
public frmDebugger()
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -30,6 +32,11 @@ namespace Mesen.GUI.Debugger
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
LabelManager.OnLabelUpdated += LabelManager_OnLabelUpdated;
|
||||
BreakpointManager.BreakpointsChanged += BreakpointManager_BreakpointsChanged;
|
||||
|
||||
this.UpdateWorkspace();
|
||||
|
||||
this.mnuSplitView.Checked = ConfigManager.Config.DebugInfo.SplitView;
|
||||
this.mnuPpuPartialDraw.Checked = ConfigManager.Config.DebugInfo.PpuPartialDraw;
|
||||
this.mnuShowEffectiveAddresses.Checked = ConfigManager.Config.DebugInfo.ShowEffectiveAddresses;
|
||||
@ -38,21 +45,11 @@ namespace Mesen.GUI.Debugger
|
||||
this.mnuShowOnlyDisassembledCode.Checked = ConfigManager.Config.DebugInfo.ShowOnlyDisassembledCode;
|
||||
this.mnuShowFunctionLabelLists.Checked = ConfigManager.Config.DebugInfo.ShowFunctionLabelLists;
|
||||
|
||||
LabelManager.ResetLabels();
|
||||
LabelManager.SetDefaultLabels(InteropEmu.FdsGetSideCount() > 0);
|
||||
LabelManager.OnLabelUpdated += LabelManager_OnLabelUpdated;
|
||||
|
||||
_lastCodeWindow = ctrlDebuggerCode;
|
||||
|
||||
this.ctrlDebuggerCode.SetConfig(ConfigManager.Config.DebugInfo.LeftView);
|
||||
this.ctrlDebuggerCodeSplit.SetConfig(ConfigManager.Config.DebugInfo.RightView);
|
||||
|
||||
BreakpointManager.Breakpoints.Clear();
|
||||
BreakpointManager.Breakpoints.AddRange(ConfigManager.Config.DebugInfo.Breakpoints);
|
||||
BreakpointManager.BreakpointsChanged += BreakpointManager_BreakpointsChanged;
|
||||
this.ctrlBreakpoints.RefreshList();
|
||||
RefreshBreakpoints();
|
||||
|
||||
this.toolTip.SetToolTip(this.picWatchHelp,
|
||||
"Most expressions/operators are accepted (C++ syntax)." + Environment.NewLine +
|
||||
"Note: Use the $ prefix to denote hexadecimal values." + Environment.NewLine +
|
||||
@ -84,6 +81,33 @@ namespace Mesen.GUI.Debugger
|
||||
tmrCdlRatios.Start();
|
||||
}
|
||||
|
||||
private void UpdateWorkspace()
|
||||
{
|
||||
if(_workspace != null) {
|
||||
_workspace.WatchValues = ctrlWatch.GetWatchValues();
|
||||
_workspace.Labels = LabelManager.GetLabels();
|
||||
_workspace.Breakpoints = BreakpointManager.Breakpoints;
|
||||
_workspace.Save();
|
||||
}
|
||||
|
||||
_workspace = DebugWorkspace.GetWorkspace();
|
||||
|
||||
LabelManager.OnLabelUpdated -= LabelManager_OnLabelUpdated;
|
||||
if(_workspace.Labels.Count == 0) {
|
||||
LabelManager.ResetLabels();
|
||||
LabelManager.SetDefaultLabels(InteropEmu.FdsGetSideCount() > 0);
|
||||
} else {
|
||||
LabelManager.SetLabels(_workspace.Labels);
|
||||
}
|
||||
LabelManager.OnLabelUpdated += LabelManager_OnLabelUpdated;
|
||||
|
||||
ctrlWatch.SetWatchValues(_workspace.WatchValues);
|
||||
|
||||
BreakpointManager.Breakpoints.Clear();
|
||||
BreakpointManager.Breakpoints.AddRange(_workspace.Breakpoints);
|
||||
ctrlBreakpoints.RefreshList();
|
||||
}
|
||||
|
||||
private void UpdateCdlRatios()
|
||||
{
|
||||
CdlRatios ratios = new CdlRatios();
|
||||
@ -119,7 +143,11 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
case InteropEmu.ConsoleNotificationType.GameReset:
|
||||
case InteropEmu.ConsoleNotificationType.GameLoaded:
|
||||
BreakpointManager.SetBreakpoints();
|
||||
this.BeginInvoke((MethodInvoker)(() => {
|
||||
this.UpdateWorkspace();
|
||||
UpdateDebugger();
|
||||
BreakpointManager.SetBreakpoints();
|
||||
}));
|
||||
InteropEmu.DebugStep(1);
|
||||
break;
|
||||
}
|
||||
@ -204,9 +232,6 @@ namespace Mesen.GUI.Debugger
|
||||
|
||||
private void RefreshBreakpoints()
|
||||
{
|
||||
ConfigManager.Config.DebugInfo.Breakpoints = new List<Breakpoint>(BreakpointManager.Breakpoints);
|
||||
ConfigManager.ApplyChanges();
|
||||
|
||||
ctrlDebuggerCodeSplit.HighlightBreakpoints();
|
||||
ctrlDebuggerCode.HighlightBreakpoints();
|
||||
}
|
||||
@ -380,6 +405,11 @@ namespace Mesen.GUI.Debugger
|
||||
foreach(Form frm in this._childForms.ToArray()) {
|
||||
frm.Close();
|
||||
}
|
||||
|
||||
if(_workspace != null) {
|
||||
_workspace.Save();
|
||||
}
|
||||
|
||||
base.OnFormClosed(e);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user