Debugger: Highlight (and fade) read/write/exec in hex editor

This commit is contained in:
Souryo 2017-03-01 20:52:15 -05:00
parent e7ac6e428b
commit 66753c843c
16 changed files with 687 additions and 110 deletions

View file

@ -340,7 +340,7 @@ void Debugger::PrivateProcessRamOperation(MemoryOperationType type, uint16_t &ad
int32_t absoluteRamAddr = addressInfo.Type == AddressType::WorkRam ? addressInfo.Address : -1; int32_t absoluteRamAddr = addressInfo.Type == AddressType::WorkRam ? addressInfo.Address : -1;
if(addressInfo.Address >= 0 && type != MemoryOperationType::DummyRead) { if(addressInfo.Address >= 0 && type != MemoryOperationType::DummyRead) {
_memoryAccessCounter->ProcessMemoryAccess(addressInfo, type); _memoryAccessCounter->ProcessMemoryAccess(addressInfo, type, _cpu->GetCycleCount());
} }
if(absoluteAddr >= 0) { if(absoluteAddr >= 0) {

View file

@ -13,25 +13,34 @@ MemoryAccessCounter::MemoryAccessCounter(Debugger* debugger)
_readCounts[i].insert(_readCounts[i].end(), memorySizes[i], 0); _readCounts[i].insert(_readCounts[i].end(), memorySizes[i], 0);
_writeCounts[i].insert(_writeCounts[i].end(), memorySizes[i], 0); _writeCounts[i].insert(_writeCounts[i].end(), memorySizes[i], 0);
_execCounts[i].insert(_execCounts[i].end(), memorySizes[i], 0); _execCounts[i].insert(_execCounts[i].end(), memorySizes[i], 0);
_readStamps[i].insert(_readStamps[i].end(), memorySizes[i], 0);
_writeStamps[i].insert(_writeStamps[i].end(), memorySizes[i], 0);
_execStamps[i].insert(_execStamps[i].end(), memorySizes[i], 0);
} }
} }
vector<int>& MemoryAccessCounter::GetArray(MemoryOperationType operationType, AddressType addressType) vector<int>& MemoryAccessCounter::GetArray(MemoryOperationType operationType, AddressType addressType, bool stampArray)
{ {
switch(operationType) { switch(operationType) {
case MemoryOperationType::Read: return _readCounts[(int)addressType]; case MemoryOperationType::Read: return stampArray ? _readStamps[(int)addressType] : _readCounts[(int)addressType];
case MemoryOperationType::Write: return _writeCounts[(int)addressType]; case MemoryOperationType::Write: return stampArray ? _writeStamps[(int)addressType] : _writeCounts[(int)addressType];
default: default:
case MemoryOperationType::ExecOpCode: case MemoryOperationType::ExecOpCode:
case MemoryOperationType::ExecOperand: return _execCounts[(int)addressType]; case MemoryOperationType::ExecOperand: return stampArray ? _execStamps[(int)addressType] : _execCounts[(int)addressType];
} }
} }
void MemoryAccessCounter::ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation) void MemoryAccessCounter::ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, int32_t cpuCycle)
{ {
int index = (int)addressInfo.Type; int index = (int)addressInfo.Type;
vector<int> &counts = GetArray(operation, addressInfo.Type); vector<int> &counts = GetArray(operation, addressInfo.Type, false);
counts.data()[addressInfo.Address]++;
vector<int> &stamps = GetArray(operation, addressInfo.Type, true);
stamps.data()[addressInfo.Address] = cpuCycle;
if(operation != MemoryOperationType::Write && if(operation != MemoryOperationType::Write &&
(addressInfo.Type == AddressType::InternalRam || addressInfo.Type == AddressType::WorkRam) && (addressInfo.Type == AddressType::InternalRam || addressInfo.Type == AddressType::WorkRam) &&
_initWrites[index].find(addressInfo.Address) == _initWrites[index].end()) { _initWrites[index].find(addressInfo.Address) == _initWrites[index].end()) {
@ -40,8 +49,6 @@ void MemoryAccessCounter::ProcessMemoryAccess(AddressTypeInfo &addressInfo, Memo
} else if(operation == MemoryOperationType::Write) { } else if(operation == MemoryOperationType::Write) {
_initWrites[index].emplace(addressInfo.Address); _initWrites[index].emplace(addressInfo.Address);
} }
counts.data()[addressInfo.Address]++;
} }
void MemoryAccessCounter::ResetCounts() void MemoryAccessCounter::ResetCounts()
@ -61,6 +68,35 @@ void MemoryAccessCounter::GetAccessCounts(AddressType memoryType, MemoryOperatio
counts[address] = 1; counts[address] = 1;
} }
} else { } else {
memcpy(counts, GetArray(operationType, memoryType).data(), GetArray(operationType, memoryType).size() * sizeof(uint32_t)); memcpy(counts, GetArray(operationType, memoryType, false).data(), GetArray(operationType, memoryType, false).size() * sizeof(uint32_t));
}
}
void MemoryAccessCounter::GetAccessStamps(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, uint32_t stamps[])
{
switch(memoryType) {
case DebugMemoryType::InternalRam:
memcpy(stamps, GetArray(operationType, AddressType::InternalRam, true).data() + offset, length * sizeof(uint32_t));
break;
case DebugMemoryType::WorkRam:
memcpy(stamps, GetArray(operationType, AddressType::WorkRam, true).data() + offset, length * sizeof(uint32_t));
break;
case DebugMemoryType::SaveRam:
memcpy(stamps, GetArray(operationType, AddressType::SaveRam, true).data() + offset, length * sizeof(uint32_t));
break;
case DebugMemoryType::PrgRom:
memcpy(stamps, GetArray(operationType, AddressType::PrgRom, true).data() + offset, length * sizeof(uint32_t));
break;
case DebugMemoryType::CpuMemory:
for(uint32_t i = 0; i < length; i++) {
AddressTypeInfo info;
_debugger->GetAbsoluteAddressAndType(offset + i, &info);
stamps[i] = GetArray(operationType, info.Type, true).data()[info.Address];
}
break;
} }
} }

View file

@ -9,20 +9,25 @@ class MemoryAccessCounter
{ {
private: private:
Debugger* _debugger; Debugger* _debugger;
vector<int> _readCounts[4]; vector<int32_t> _readCounts[4];
vector<int> _writeCounts[4]; vector<int32_t> _writeCounts[4];
vector<int> _execCounts[4]; vector<int32_t> _execCounts[4];
std::unordered_set<int> _initWrites[4]; vector<int32_t> _readStamps[4];
std::unordered_set<int> _uninitReads[4]; vector<int32_t> _writeStamps[4];
vector<int32_t> _execStamps[4];
vector<int>& GetArray(MemoryOperationType operationType, AddressType addressType); std::unordered_set<int32_t> _initWrites[4];
std::unordered_set<int32_t> _uninitReads[4];
vector<int32_t>& GetArray(MemoryOperationType operationType, AddressType addressType, bool stampArray);
public: public:
MemoryAccessCounter(Debugger* debugger); MemoryAccessCounter(Debugger* debugger);
void ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation); void ProcessMemoryAccess(AddressTypeInfo &addressInfo, MemoryOperationType operation, int32_t cpuCycle);
void ResetCounts(); void ResetCounts();
void GetAccessCounts(AddressType memoryType, MemoryOperationType operationType, uint32_t counts[], bool forUninitReads); void GetAccessCounts(AddressType memoryType, MemoryOperationType operationType, uint32_t counts[], bool forUninitReads);
void GetAccessStamps(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, uint32_t stamps[]);
}; };

View file

@ -121,6 +121,10 @@ namespace Mesen.GUI.Config
public int RamColumnCount = 2; public int RamColumnCount = 2;
public float RamFontSize = BaseControl.DefaultFontSize; public float RamFontSize = BaseControl.DefaultFontSize;
public bool RamShowCharacters = true; public bool RamShowCharacters = true;
public bool RamHighlightExecution = true;
public bool RamHighlightWrites = true;
public bool RamHighlightReads = true;
public int RamFadeSpeed = 300;
public int WindowWidth = -1; public int WindowWidth = -1;
public int WindowHeight = -1; public int WindowHeight = -1;

View file

@ -0,0 +1,65 @@
using System;
using System.Drawing;
using Be.Windows.Forms;
namespace Mesen.GUI.Debugger
{
public class ByteColorProvider : IByteColorProvider
{
DebugMemoryType _memoryType;
Int32[] _readStamps;
Int32[] _writeStamps;
Int32[] _execStamps;
DebugState _state = new DebugState();
bool _showExec;
bool _showWrite;
bool _showRead;
int _framesToFade;
public ByteColorProvider(DebugMemoryType memoryType, bool showExec, bool showWrite, bool showRead, int framesToFade)
{
_memoryType = memoryType;
_showExec = showExec;
_showWrite = showWrite;
_showRead = showRead;
_framesToFade = framesToFade;
}
public void Prepare(long firstByteIndex, long lastByteIndex)
{
_readStamps = InteropEmu.DebugGetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)(lastByteIndex - firstByteIndex + 1), _memoryType, MemoryOperationType.Read);
_writeStamps = InteropEmu.DebugGetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)(lastByteIndex - firstByteIndex + 1), _memoryType, MemoryOperationType.Write);
_execStamps = InteropEmu.DebugGetMemoryAccessStamps((UInt32)firstByteIndex, (UInt32)(lastByteIndex - firstByteIndex + 1), _memoryType, MemoryOperationType.Exec);
InteropEmu.DebugGetState(ref _state);
}
public Color DarkerColor(Color input, double brightnessPercentage)
{
if(brightnessPercentage < 0.20) {
brightnessPercentage *= 5;
} else {
brightnessPercentage = 1.0;
}
return Color.FromArgb((int)(input.R * brightnessPercentage), (int)(input.G * brightnessPercentage), (int)(input.B * brightnessPercentage));
}
public Color GetByteColor(long firstByteIndex, long byteIndex)
{
const int CyclesPerFrame = 29780;
long index = byteIndex - firstByteIndex;
double framesSinceExec = (double)(_state.CPU.CycleCount - _execStamps[index]) / CyclesPerFrame;
double framesSinceWrite = (double)(_state.CPU.CycleCount - _writeStamps[index]) / CyclesPerFrame;
double framesSinceRead = (double)(_state.CPU.CycleCount - _readStamps[index]) / CyclesPerFrame;
if(_showExec && _execStamps[index] != 0 && framesSinceExec < _framesToFade) {
return DarkerColor(Color.Green, (_framesToFade - framesSinceExec) / _framesToFade);
} else if(_showWrite && _writeStamps[index] != 0 && framesSinceWrite < _framesToFade) {
return DarkerColor(Color.Red, (_framesToFade - framesSinceWrite) / _framesToFade);
} else if(_showRead && _readStamps[index] != 0 && framesSinceRead < _framesToFade) {
return DarkerColor(Color.Blue, (_framesToFade - framesSinceRead) / _framesToFade);
}
return Color.Black;
}
}
}

View file

@ -26,8 +26,6 @@ namespace Mesen.GUI.Debugger.Controls
this.ctrlHexBox.Font = new Font(BaseControl.MonospaceFontFamily, 10, FontStyle.Regular); this.ctrlHexBox.Font = new Font(BaseControl.MonospaceFontFamily, 10, FontStyle.Regular);
this.ctrlHexBox.SelectionForeColor = Color.White; this.ctrlHexBox.SelectionForeColor = Color.White;
this.ctrlHexBox.SelectionBackColor = Color.FromArgb(31, 123, 205); this.ctrlHexBox.SelectionBackColor = Color.FromArgb(31, 123, 205);
this.ctrlHexBox.ChangeColor = Color.Red;
this.ctrlHexBox.SelectionChangeColor = Color.FromArgb(255, 125, 125);
this.ctrlHexBox.ShadowSelectionColor = Color.FromArgb(100, 60, 128, 200); this.ctrlHexBox.ShadowSelectionColor = Color.FromArgb(100, 60, 128, 200);
this.ctrlHexBox.InfoBackColor = Color.FromArgb(235, 235, 235); this.ctrlHexBox.InfoBackColor = Color.FromArgb(235, 235, 235);
this.ctrlHexBox.InfoForeColor = Color.Gray; this.ctrlHexBox.InfoForeColor = Color.Gray;
@ -42,7 +40,7 @@ namespace Mesen.GUI.Debugger.Controls
return this._byteProvider != null ? this._byteProvider.Bytes.ToArray() : new byte[0]; return this._byteProvider != null ? this._byteProvider.Bytes.ToArray() : new byte[0];
} }
public void SetData(byte[] data, bool clearHistory) public void SetData(byte[] data)
{ {
if(data != null) { if(data != null) {
bool changed = true; bool changed = true;
@ -62,9 +60,6 @@ namespace Mesen.GUI.Debugger.Controls
ByteChanged?.Invoke(byteIndex, newValue, oldValue); ByteChanged?.Invoke(byteIndex, newValue, oldValue);
}; };
this.ctrlHexBox.ByteProvider = _byteProvider; this.ctrlHexBox.ByteProvider = _byteProvider;
if(clearHistory) {
this.ctrlHexBox.ClearHistory();
}
} }
} }
} }
@ -294,6 +289,13 @@ namespace Mesen.GUI.Debugger.Controls
set { this.ctrlHexBox.ByteCharConverter = value; } set { this.ctrlHexBox.ByteCharConverter = value; }
} }
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IByteColorProvider ByteColorProvider
{
get { return this.ctrlHexBox.ByteColorProvider; }
set { this.ctrlHexBox.ByteColorProvider = value; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool StringViewVisible public bool StringViewVisible
{ {

View file

@ -2591,6 +2591,10 @@ namespace Be.Windows.Forms
} }
int skipCount = 0; int skipCount = 0;
if(this.ByteColorProvider != null) {
this.ByteColorProvider.Prepare(_startByte, intern_endByte);
}
for(long i = startByte; i < intern_endByte + 1; i++) { for(long i = startByte; i < intern_endByte + 1; i++) {
counter++; counter++;
Point gridPoint = GetGridBytePoint(counter); Point gridPoint = GetGridBytePoint(counter);
@ -2607,66 +2611,60 @@ namespace Be.Windows.Forms
yPrevious = gridPoint.Y; yPrevious = gridPoint.Y;
byte b = _byteProvider.ReadByte(i); byte b = _byteProvider.ReadByte(i);
bool byteHasChanged = false;
if(_prevByteProvider != null && _prevByteProvider.Length == _byteProvider.Length) {
byteHasChanged = _prevByteProvider.ReadByte(i) != b;
}
bool isSelectedByte = i >= _bytePos && i <= (_bytePos + _selectionLength - 1) && _selectionLength != 0; bool isSelectedByte = i >= _bytePos && i <= (_bytePos + _selectionLength - 1) && _selectionLength != 0;
using(Brush brush = new SolidBrush(GetDefaultForeColor())) { using(Brush selBrushBack = new SolidBrush(_selectionBackColor)) {
using(Brush changeBrush = new SolidBrush(_changeColor)) { Color byteColor = this.ForeColor;
using(Brush selectionChangeBrush = new SolidBrush(_selectionChangeColor)) { if(this.ByteColorProvider != null) {
using(Brush selBrush = new SolidBrush(_selectionForeColor)) { byteColor = this.ByteColorProvider.GetByteColor(_startByte, i);
using(Brush selBrushBack = new SolidBrush(_selectionBackColor)) { }
if(isSelectedByte && isKeyInterpreterActive) {
PaintHexStringSelected(g, b, byteHasChanged ? selectionChangeBrush : selBrush, selBrushBack, gridPoint);
} else {
PaintHexString(g, b, byteHasChanged ? changeBrush : brush, gridPoint);
}
string s; using(Brush byteBrush = new SolidBrush(byteColor)) {
if(skipCount > 0) { if(isSelectedByte && isKeyInterpreterActive) {
skipCount--; PaintHexStringSelected(g, b, byteBrush, selBrushBack, gridPoint);
s = ""; } else {
} else { PaintHexString(g, b, byteBrush, gridPoint);
long len = _byteProvider.Length; }
UInt64 tblValue = (UInt64)b;
for(int j = 1; j < 8; j++) {
if(len > i + j) {
tblValue += (UInt64)_byteProvider.ReadByte(i+j) << (8 * j);
}
}
int keyLength; string s;
s = ByteCharConverter.ToChar(tblValue, out keyLength); if(skipCount > 0) {
skipCount = keyLength - 1; skipCount--;
} s = "";
} else {
float width = (float)Math.Ceiling(g.MeasureString(s, Font, 100, _stringFormat).Width); long len = _byteProvider.Length;
float xPos = byteStringPointF.X+xOffset; UInt64 tblValue = (UInt64)b;
_xPosCache[gridPoint] = xPos; for(int j = 1; j < 8; j++) {
_xPosList[gridPoint.Y].Add(xPos); if(len > i + j) {
tblValue += (UInt64)_byteProvider.ReadByte(i+j) << (8 * j);
if(gridPoint == caretPoint) {
int caretWidth = (this.InsertActive) ? 1 : (int)width;
int caretHeight = (int)_charSize.Height;
g.FillRectangle(Brushes.Yellow, xPos - 1, _caretPos.Y, caretWidth, caretHeight);
g.DrawRectangle(Pens.Gray, xPos - 1, _caretPos.Y, caretWidth, caretHeight);
}
if(isSelectedByte && isStringKeyInterpreterActive) {
g.FillRectangle(selBrushBack, xPos, byteStringPointF.Y, width, _charSize.Height);
g.DrawString(s, Font, selBrush, new PointF(xPos, byteStringPointF.Y), _stringFormat);
} else {
g.DrawString(s, Font, brush, new PointF(xPos, byteStringPointF.Y), _stringFormat);
}
xOffset += width - _charSize.Width;
xPrevious = xPos + width;
} }
} }
int keyLength;
s = ByteCharConverter.ToChar(tblValue, out keyLength);
skipCount = keyLength - 1;
} }
float width = (float)Math.Ceiling(g.MeasureString(s, Font, 100, _stringFormat).Width);
float xPos = byteStringPointF.X+xOffset;
_xPosCache[gridPoint] = xPos;
_xPosList[gridPoint.Y].Add(xPos);
if(gridPoint == caretPoint) {
int caretWidth = (this.InsertActive) ? 1 : (int)width;
int caretHeight = (int)_charSize.Height;
g.FillRectangle(Brushes.Yellow, xPos - 1, _caretPos.Y, caretWidth, caretHeight);
g.DrawRectangle(Pens.Gray, xPos - 1, _caretPos.Y, caretWidth, caretHeight);
}
if(isSelectedByte && isStringKeyInterpreterActive) {
g.FillRectangle(selBrushBack, xPos, byteStringPointF.Y, width, _charSize.Height);
g.DrawString(s, Font, byteBrush, new PointF(xPos, byteStringPointF.Y), _stringFormat);
} else {
g.DrawString(s, Font, byteBrush, new PointF(xPos, byteStringPointF.Y), _stringFormat);
}
xOffset += width - _charSize.Width;
xPrevious = xPos + width;
} }
} }
} }
@ -3261,7 +3259,6 @@ namespace Be.Windows.Forms
if (_byteProvider != null) if (_byteProvider != null)
_byteProvider.LengthChanged -= new EventHandler(_byteProvider_LengthChanged); _byteProvider.LengthChanged -= new EventHandler(_byteProvider_LengthChanged);
_prevByteProvider = _byteProvider;
_byteProvider = value; _byteProvider = value;
if (_byteProvider != null) if (_byteProvider != null)
_byteProvider.LengthChanged += new EventHandler(_byteProvider_LengthChanged); _byteProvider.LengthChanged += new EventHandler(_byteProvider_LengthChanged);
@ -3304,12 +3301,8 @@ namespace Be.Windows.Forms
} }
IByteProvider _byteProvider; IByteProvider _byteProvider;
IByteProvider _prevByteProvider;
internal void ClearHistory() public IByteColorProvider ByteColorProvider { get; set; }
{
this._prevByteProvider = null;
}
/// <summary> /// <summary>
/// Gets or sets the visibility of the group separator. /// Gets or sets the visibility of the group separator.
@ -3546,30 +3539,6 @@ namespace Be.Windows.Forms
set { _selectionForeColor = value; Invalidate(); } set { _selectionForeColor = value; Invalidate(); }
} Color _selectionForeColor = Color.White; } Color _selectionForeColor = Color.White;
/// <summary>
/// Gets or sets the foreground color for the changed bytes.
/// </summary>
[DefaultValue(typeof(Color), "White"), Category("Hex"), Description("Gets or sets the foreground color for the selected bytes.")]
public Color ChangeColor
{
get { return _changeColor; }
set { _changeColor = value; Invalidate(); }
}
Color _changeColor = Color.White;
/// <summary>
/// Gets or sets the foreground color for the selected changed bytes.
/// </summary>
[DefaultValue(typeof(Color), "White"), Category("Hex"), Description("Gets or sets the foreground color for the selected bytes.")]
public Color SelectionChangeColor
{
get { return _selectionChangeColor; }
set { _selectionChangeColor = value; Invalidate(); }
}
Color _selectionChangeColor = Color.White;
/// <summary> /// <summary>
/// Gets or sets the visibility of a shadow selection. /// Gets or sets the visibility of a shadow selection.
/// </summary> /// </summary>

View file

@ -0,0 +1,11 @@
using System;
using System.Drawing;
namespace Be.Windows.Forms
{
public interface IByteColorProvider
{
void Prepare(long firstByteIndex, long lastByteIndex);
Color GetByteColor(long firstByteIndex, long byteIndex);
}
}

130
GUI.NET/Debugger/frmFadeSpeed.Designer.cs generated Normal file
View file

@ -0,0 +1,130 @@
namespace Mesen.GUI.Debugger
{
partial class frmFadeSpeed
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.lblAddress = new System.Windows.Forms.Label();
this.lblFrames = new System.Windows.Forms.Label();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.nudFrameCount = new System.Windows.Forms.NumericUpDown();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.nudFrameCount)).BeginInit();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 28);
this.baseConfigPanel.Size = new System.Drawing.Size(226, 29);
//
// lblAddress
//
this.lblAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAddress.AutoSize = true;
this.lblAddress.Location = new System.Drawing.Point(3, 6);
this.lblAddress.Name = "lblAddress";
this.lblAddress.Size = new System.Drawing.Size(55, 13);
this.lblAddress.TabIndex = 0;
this.lblAddress.Text = "Fade after";
//
// lblFrames
//
this.lblFrames.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblFrames.AutoSize = true;
this.lblFrames.Location = new System.Drawing.Point(149, 6);
this.lblFrames.Name = "lblFrames";
this.lblFrames.Size = new System.Drawing.Size(38, 13);
this.lblFrames.TabIndex = 2;
this.lblFrames.Text = "frames";
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 3;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F));
this.tableLayoutPanel1.Controls.Add(this.lblFrames, 2, 0);
this.tableLayoutPanel1.Controls.Add(this.lblAddress, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.nudFrameCount, 1, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(226, 57);
this.tableLayoutPanel1.TabIndex = 0;
//
// nudFrameCount
//
this.nudFrameCount.Dock = System.Windows.Forms.DockStyle.Fill;
this.nudFrameCount.Location = new System.Drawing.Point(64, 3);
this.nudFrameCount.Maximum = new decimal(new int[] {
99999,
0,
0,
0});
this.nudFrameCount.Minimum = new decimal(new int[] {
1,
0,
0,
0});
this.nudFrameCount.Name = "nudFrameCount";
this.nudFrameCount.Size = new System.Drawing.Size(79, 20);
this.nudFrameCount.TabIndex = 3;
this.nudFrameCount.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// frmFadeSpeed
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(226, 57);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "frmFadeSpeed";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Fade speed...";
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.nudFrameCount)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label lblAddress;
private System.Windows.Forms.Label lblFrames;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.NumericUpDown nudFrameCount;
}
}

View file

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmFadeSpeed : BaseConfigForm
{
public frmFadeSpeed(int initialValue)
{
InitializeComponent();
nudFrameCount.Value = initialValue;
}
public int FadeSpeed
{
get { return (int)nudFrameCount.Value; }
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
nudFrameCount.Focus();
}
}
}

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -46,6 +46,18 @@
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem(); this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
this.mnuView = new System.Windows.Forms.ToolStripMenuItem(); this.mnuView = new System.Windows.Forms.ToolStripMenuItem();
this.highlightToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHightlightReads = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightWrites = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightExecution = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator();
this.fadeSpeedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFadeSlow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFadeNormal = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFadeFast = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripSeparator();
this.mnuCustomFadeSpeed = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem(); this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.fontSizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.fontSizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuIncreaseFontSize = new System.Windows.Forms.ToolStripMenuItem(); this.mnuIncreaseFontSize = new System.Windows.Forms.ToolStripMenuItem();
@ -205,6 +217,8 @@
// mnuView // mnuView
// //
this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.highlightToolStripMenuItem,
this.toolStripMenuItem5,
this.mnuRefresh, this.mnuRefresh,
this.fontSizeToolStripMenuItem, this.fontSizeToolStripMenuItem,
this.toolStripMenuItem2, this.toolStripMenuItem2,
@ -214,6 +228,96 @@
this.mnuView.Size = new System.Drawing.Size(44, 20); this.mnuView.Size = new System.Drawing.Size(44, 20);
this.mnuView.Text = "View"; this.mnuView.Text = "View";
// //
// highlightToolStripMenuItem
//
this.highlightToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuHightlightReads,
this.mnuHighlightWrites,
this.mnuHighlightExecution,
this.toolStripMenuItem6,
this.fadeSpeedToolStripMenuItem});
this.highlightToolStripMenuItem.Name = "highlightToolStripMenuItem";
this.highlightToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.highlightToolStripMenuItem.Text = "Highlight";
//
// mnuHightlightReads
//
this.mnuHightlightReads.CheckOnClick = true;
this.mnuHightlightReads.Name = "mnuHightlightReads";
this.mnuHightlightReads.Size = new System.Drawing.Size(152, 22);
this.mnuHightlightReads.Text = "Reads";
//
// mnuHighlightWrites
//
this.mnuHighlightWrites.CheckOnClick = true;
this.mnuHighlightWrites.Name = "mnuHighlightWrites";
this.mnuHighlightWrites.Size = new System.Drawing.Size(152, 22);
this.mnuHighlightWrites.Text = "Writes";
//
// mnuHighlightExecution
//
this.mnuHighlightExecution.CheckOnClick = true;
this.mnuHighlightExecution.Name = "mnuHighlightExecution";
this.mnuHighlightExecution.Size = new System.Drawing.Size(152, 22);
this.mnuHighlightExecution.Text = "Execution";
//
// toolStripMenuItem6
//
this.toolStripMenuItem6.Name = "toolStripMenuItem6";
this.toolStripMenuItem6.Size = new System.Drawing.Size(149, 6);
//
// fadeSpeedToolStripMenuItem
//
this.fadeSpeedToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuFadeSlow,
this.mnuFadeNormal,
this.mnuFadeFast,
this.toolStripMenuItem7,
this.mnuCustomFadeSpeed});
this.fadeSpeedToolStripMenuItem.Name = "fadeSpeedToolStripMenuItem";
this.fadeSpeedToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.fadeSpeedToolStripMenuItem.Text = "Fade speed";
//
// mnuFadeSlow
//
this.mnuFadeSlow.Name = "mnuFadeSlow";
this.mnuFadeSlow.Size = new System.Drawing.Size(152, 22);
this.mnuFadeSlow.Text = "Slow";
this.mnuFadeSlow.Click += new System.EventHandler(this.mnuFadeSpeed_Click);
//
// mnuFadeNormal
//
this.mnuFadeNormal.Checked = true;
this.mnuFadeNormal.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuFadeNormal.Name = "mnuFadeNormal";
this.mnuFadeNormal.Size = new System.Drawing.Size(152, 22);
this.mnuFadeNormal.Text = "Normal";
this.mnuFadeNormal.Click += new System.EventHandler(this.mnuFadeSpeed_Click);
//
// mnuFadeFast
//
this.mnuFadeFast.Name = "mnuFadeFast";
this.mnuFadeFast.Size = new System.Drawing.Size(152, 22);
this.mnuFadeFast.Text = "Fast";
this.mnuFadeFast.Click += new System.EventHandler(this.mnuFadeSpeed_Click);
//
// toolStripMenuItem7
//
this.toolStripMenuItem7.Name = "toolStripMenuItem7";
this.toolStripMenuItem7.Size = new System.Drawing.Size(149, 6);
//
// mnuCustomFadeSpeed
//
this.mnuCustomFadeSpeed.Name = "mnuCustomFadeSpeed";
this.mnuCustomFadeSpeed.Size = new System.Drawing.Size(152, 22);
this.mnuCustomFadeSpeed.Text = "Custom...";
this.mnuCustomFadeSpeed.Click += new System.EventHandler(this.mnuCustomFadeSpeed_Click);
//
// toolStripMenuItem5
//
this.toolStripMenuItem5.Name = "toolStripMenuItem5";
this.toolStripMenuItem5.Size = new System.Drawing.Size(157, 6);
//
// mnuRefresh // mnuRefresh
// //
this.mnuRefresh.Name = "mnuRefresh"; this.mnuRefresh.Name = "mnuRefresh";
@ -489,5 +593,17 @@
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4; private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4;
private System.Windows.Forms.ToolStripMenuItem mnuShowCharacters; private System.Windows.Forms.ToolStripMenuItem mnuShowCharacters;
private System.Windows.Forms.ToolStripMenuItem mnuResetTblMappings; private System.Windows.Forms.ToolStripMenuItem mnuResetTblMappings;
private System.Windows.Forms.ToolStripMenuItem highlightToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuHightlightReads;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightWrites;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightExecution;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem6;
private System.Windows.Forms.ToolStripMenuItem fadeSpeedToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
private System.Windows.Forms.ToolStripMenuItem mnuFadeSlow;
private System.Windows.Forms.ToolStripMenuItem mnuFadeNormal;
private System.Windows.Forms.ToolStripMenuItem mnuFadeFast;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem7;
private System.Windows.Forms.ToolStripMenuItem mnuCustomFadeSpeed;
} }
} }

View file

@ -35,9 +35,14 @@ namespace Mesen.GUI.Debugger
this.mnuAutoRefresh.Checked = ConfigManager.Config.DebugInfo.RamAutoRefresh; this.mnuAutoRefresh.Checked = ConfigManager.Config.DebugInfo.RamAutoRefresh;
this.mnuShowCharacters.Checked = ConfigManager.Config.DebugInfo.RamShowCharacters; this.mnuShowCharacters.Checked = ConfigManager.Config.DebugInfo.RamShowCharacters;
this.ctrlHexViewer.SetFontSize((int)ConfigManager.Config.DebugInfo.RamFontSize); this.ctrlHexViewer.SetFontSize((int)ConfigManager.Config.DebugInfo.RamFontSize);
this.mnuHighlightExecution.Checked = ConfigManager.Config.DebugInfo.RamHighlightExecution;
this.mnuHightlightReads.Checked = ConfigManager.Config.DebugInfo.RamHighlightReads;
this.mnuHighlightWrites.Checked = ConfigManager.Config.DebugInfo.RamHighlightWrites;
this.UpdateFadeOptions();
this.InitTblMappings(); this.InitTblMappings();
this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked; this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked;
UpdateImportButton(); UpdateImportButton();
@ -68,7 +73,7 @@ namespace Mesen.GUI.Debugger
this.BeginInvoke((MethodInvoker)(() => this.RefreshData())); this.BeginInvoke((MethodInvoker)(() => this.RefreshData()));
} }
} }
private void cboMemoryType_SelectedIndexChanged(object sender, EventArgs e) private void cboMemoryType_SelectedIndexChanged(object sender, EventArgs e)
{ {
this._memoryType = (DebugMemoryType)this.cboMemoryType.SelectedIndex; this._memoryType = (DebugMemoryType)this.cboMemoryType.SelectedIndex;
@ -76,6 +81,23 @@ namespace Mesen.GUI.Debugger
this.RefreshData(); this.RefreshData();
} }
private void UpdateByteColorProvider()
{
switch((DebugMemoryType)this.cboMemoryType.SelectedIndex) {
case DebugMemoryType.CpuMemory:
case DebugMemoryType.PrgRom:
case DebugMemoryType.WorkRam:
case DebugMemoryType.SaveRam:
case DebugMemoryType.InternalRam:
this.ctrlHexViewer.ByteColorProvider = new ByteColorProvider((DebugMemoryType)this.cboMemoryType.SelectedIndex, mnuHighlightExecution.Checked, mnuHighlightWrites.Checked, mnuHightlightReads.Checked, ConfigManager.Config.DebugInfo.RamFadeSpeed);
break;
default:
this.ctrlHexViewer.ByteColorProvider = null;
break;
}
}
private void mnuRefresh_Click(object sender, EventArgs e) private void mnuRefresh_Click(object sender, EventArgs e)
{ {
this.RefreshData(); this.RefreshData();
@ -93,7 +115,8 @@ namespace Mesen.GUI.Debugger
if(this.tabMain.SelectedTab == this.tpgAccessCounters) { if(this.tabMain.SelectedTab == this.tpgAccessCounters) {
this.ctrlMemoryAccessCounters.RefreshData(); this.ctrlMemoryAccessCounters.RefreshData();
} else if(this.tabMain.SelectedTab == this.tpgMemoryViewer) { } else if(this.tabMain.SelectedTab == this.tpgMemoryViewer) {
this.ctrlHexViewer.SetData(InteropEmu.DebugGetMemoryState((DebugMemoryType)this.cboMemoryType.SelectedIndex), this.cboMemoryType.SelectedIndex != _previousIndex); this.UpdateByteColorProvider();
this.ctrlHexViewer.SetData(InteropEmu.DebugGetMemoryState((DebugMemoryType)this.cboMemoryType.SelectedIndex));
this._previousIndex = this.cboMemoryType.SelectedIndex; this._previousIndex = this.cboMemoryType.SelectedIndex;
} }
} }
@ -249,5 +272,38 @@ namespace Mesen.GUI.Debugger
this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked; this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked;
this.UpdateConfig(); this.UpdateConfig();
} }
private void UpdateFadeOptions()
{
int fadeSpeed = ConfigManager.Config.DebugInfo.RamFadeSpeed;
mnuFadeSlow.Checked = fadeSpeed == 600;
mnuFadeNormal.Checked = fadeSpeed == 300;
mnuFadeFast.Checked = fadeSpeed == 120;
mnuCustomFadeSpeed.Checked = !mnuFadeSlow.Checked && !mnuFadeNormal.Checked && !mnuFadeFast.Checked;
}
private void mnuFadeSpeed_Click(object sender, EventArgs e)
{
if(sender == mnuFadeSlow) {
ConfigManager.Config.DebugInfo.RamFadeSpeed = 600;
} else if(sender == mnuFadeNormal) {
ConfigManager.Config.DebugInfo.RamFadeSpeed = 300;
} else if(sender == mnuFadeFast) {
ConfigManager.Config.DebugInfo.RamFadeSpeed = 120;
}
ConfigManager.ApplyChanges();
UpdateFadeOptions();
}
private void mnuCustomFadeSpeed_Click(object sender, EventArgs e)
{
using(frmFadeSpeed frm = new frmFadeSpeed(ConfigManager.Config.DebugInfo.RamFadeSpeed)) {
if(frm.ShowDialog() == DialogResult.OK) {
ConfigManager.Config.DebugInfo.RamFadeSpeed = frm.FadeSpeed;
ConfigManager.ApplyChanges();
UpdateFadeOptions();
}
}
}
} }
} }

View file

@ -269,6 +269,7 @@
</Compile> </Compile>
<Compile Include="Debugger\Breakpoint.cs" /> <Compile Include="Debugger\Breakpoint.cs" />
<Compile Include="Debugger\BreakpointManager.cs" /> <Compile Include="Debugger\BreakpointManager.cs" />
<Compile Include="Debugger\ByteColorProvider.cs" />
<Compile Include="Debugger\Controls\BaseScrollableTextboxUserControl.cs"> <Compile Include="Debugger\Controls\BaseScrollableTextboxUserControl.cs">
<SubType>UserControl</SubType> <SubType>UserControl</SubType>
</Compile> </Compile>
@ -410,6 +411,12 @@
<Compile Include="Debugger\frmFindOccurrences.Designer.cs"> <Compile Include="Debugger\frmFindOccurrences.Designer.cs">
<DependentUpon>frmFindOccurrences.cs</DependentUpon> <DependentUpon>frmFindOccurrences.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="Debugger\frmFadeSpeed.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmFadeSpeed.Designer.cs">
<DependentUpon>frmFadeSpeed.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmGoToLine.cs"> <Compile Include="Debugger\frmGoToLine.cs">
<SubType>Form</SubType> <SubType>Form</SubType>
</Compile> </Compile>
@ -451,6 +458,7 @@
<SubType>Component</SubType> <SubType>Component</SubType>
</Compile> </Compile>
<Compile Include="Debugger\HexBox\HexCasing.cs" /> <Compile Include="Debugger\HexBox\HexCasing.cs" />
<Compile Include="Debugger\HexBox\IByteColorProvider.cs" />
<Compile Include="Debugger\HexBox\IByteProvider.cs" /> <Compile Include="Debugger\HexBox\IByteProvider.cs" />
<Compile Include="Debugger\HexBox\MemoryDataBlock.cs" /> <Compile Include="Debugger\HexBox\MemoryDataBlock.cs" />
<Compile Include="Debugger\HexBox\NativeMethods.cs" /> <Compile Include="Debugger\HexBox\NativeMethods.cs" />
@ -731,6 +739,9 @@
<EmbeddedResource Include="Debugger\frmFindOccurrences.resx"> <EmbeddedResource Include="Debugger\frmFindOccurrences.resx">
<DependentUpon>frmFindOccurrences.cs</DependentUpon> <DependentUpon>frmFindOccurrences.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Debugger\frmFadeSpeed.resx">
<DependentUpon>frmFadeSpeed.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmGoToLine.resx"> <EmbeddedResource Include="Debugger\frmGoToLine.resx">
<DependentUpon>frmGoToLine.cs</DependentUpon> <DependentUpon>frmGoToLine.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>

View file

@ -349,6 +349,21 @@ namespace Mesen.GUI
return counts; return counts;
} }
[DllImport(DLLPath, EntryPoint= "DebugGetMemoryAccessStamps")] private static extern void DebugGetMemoryAccessStampsWrapper(UInt32 offset, UInt32 length, DebugMemoryType type, MemoryOperationType operationType, IntPtr stamps);
public static Int32[] DebugGetMemoryAccessStamps(UInt32 offset, UInt32 length, DebugMemoryType type, MemoryOperationType operationType)
{
Int32[] stamps = new Int32[length];
GCHandle hStamps = GCHandle.Alloc(stamps, GCHandleType.Pinned);
try {
InteropEmu.DebugGetMemoryAccessStampsWrapper(offset, length, type, operationType, hStamps.AddrOfPinnedObject());
} finally {
hStamps.Free();
}
return stamps;
}
[DllImport(DLLPath, EntryPoint="DebugGetCallstack")] private static extern void DebugGetCallstackWrapper(IntPtr callstackAbsolute, IntPtr callstackRelative); [DllImport(DLLPath, EntryPoint="DebugGetCallstack")] private static extern void DebugGetCallstackWrapper(IntPtr callstackAbsolute, IntPtr callstackRelative);
public static void DebugGetCallstack(out Int32[] callstackAbsolute, out Int32[] callstackRelative) public static void DebugGetCallstack(out Int32[] callstackAbsolute, out Int32[] callstackRelative)
{ {

View file

@ -81,6 +81,7 @@ extern "C"
DllExport int32_t __stdcall DebugGetMemorySize(DebugMemoryType type) { return GetDebugger()->GetMemorySize(type); } DllExport int32_t __stdcall DebugGetMemorySize(DebugMemoryType type) { return GetDebugger()->GetMemorySize(type); }
DllExport void __stdcall DebugGetMemoryAccessCounts(AddressType memoryType, MemoryOperationType operationType, uint32_t* counts, bool forUninitReads) { GetDebugger()->GetMemoryAccessCounter()->GetAccessCounts(memoryType, operationType, counts, forUninitReads); } DllExport void __stdcall DebugGetMemoryAccessCounts(AddressType memoryType, MemoryOperationType operationType, uint32_t* counts, bool forUninitReads) { GetDebugger()->GetMemoryAccessCounter()->GetAccessCounts(memoryType, operationType, counts, forUninitReads); }
DllExport void __stdcall DebugResetMemoryAccessCounts() { GetDebugger()->GetMemoryAccessCounter()->ResetCounts(); } DllExport void __stdcall DebugResetMemoryAccessCounts() { GetDebugger()->GetMemoryAccessCounter()->ResetCounts(); }
DllExport void __stdcall DebugGetMemoryAccessStamps(uint32_t offset, uint32_t length, DebugMemoryType memoryType, MemoryOperationType operationType, uint32_t* stamps) { GetDebugger()->GetMemoryAccessCounter()->GetAccessStamps(offset, length, memoryType, operationType, stamps); }
DllExport void __stdcall DebugGetProfilerData(int64_t* profilerData, ProfilerDataType dataType) { GetDebugger()->GetProfiler()->GetProfilerData(profilerData, dataType); } DllExport void __stdcall DebugGetProfilerData(int64_t* profilerData, ProfilerDataType dataType) { GetDebugger()->GetProfiler()->GetProfilerData(profilerData, dataType); }
DllExport void __stdcall DebugResetProfiler() { GetDebugger()->GetProfiler()->Reset(); } DllExport void __stdcall DebugResetProfiler() { GetDebugger()->GetProfiler()->Reset(); }