Debugger: Added "Performance Tracker" tool

This commit is contained in:
Sour 2019-01-24 00:50:42 -05:00
parent fd2b7ab649
commit 9ceb522874
15 changed files with 408 additions and 14 deletions

View file

@ -558,6 +558,7 @@
<ClInclude Include="NESHeader.h" />
<ClInclude Include="NotificationManager.h" />
<ClInclude Include="OpenBusHandler.h" />
<ClInclude Include="PerformanceTracker.h" />
<ClInclude Include="RawVideoFilter.h" />
<ClInclude Include="ResetTxrom.h" />
<ClInclude Include="Sachen9602.h" />
@ -985,6 +986,7 @@
<ClCompile Include="NsfPpu.cpp" />
<ClCompile Include="OggMixer.cpp" />
<ClCompile Include="OggReader.cpp" />
<ClCompile Include="PerformanceTracker.cpp" />
<ClCompile Include="PgoUtilities.cpp" />
<ClCompile Include="RawVideoFilter.cpp" />
<ClCompile Include="RecordedRomTest.cpp" />

View file

@ -1474,6 +1474,10 @@
<ClInclude Include="DummyCpu.h">
<Filter>Debugger</Filter>
</ClInclude>
<ClInclude Include="PgoUtilities.h" />
<ClInclude Include="PerformanceTracker.h">
<Filter>Debugger</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -1767,11 +1771,11 @@
<ClCompile Include="StereoCombFilter.cpp">
<Filter>Nes\APU\Filters</Filter>
</ClCompile>
<ClCompile Include="PgoUtilities.h">
<Filter>Misc</Filter>
</ClCompile>
<ClCompile Include="PgoUtilities.cpp">
<Filter>Misc</Filter>
</ClCompile>
<ClCompile Include="PerformanceTracker.cpp">
<Filter>Debugger</Filter>
</ClCompile>
</ItemGroup>
</Project>

View file

@ -30,6 +30,7 @@
#include "NotificationManager.h"
#include "DebugHud.h"
#include "DummyCpu.h"
#include "PerformanceTracker.h"
const int Debugger::BreakpointTypeCount;
string Debugger::_disassemblerOutput = "";
@ -55,6 +56,7 @@ Debugger::Debugger(shared_ptr<Console> console, shared_ptr<CPU> cpu, shared_ptr<
_memoryAccessCounter.reset(new MemoryAccessCounter(this));
_profiler.reset(new Profiler(this));
_performanceTracker.reset(new PerformanceTracker(console));
_traceLogger.reset(new TraceLogger(this, memoryManager, _labelManager));
_bpExpEval.reset(new ExpressionEvaluator(this));
@ -790,6 +792,7 @@ bool Debugger::ProcessRamOperation(MemoryOperationType type, uint16_t &addr, uin
ProcessStepConditions(addr);
_performanceTracker->ProcessCpuExec(addressInfo);
_profiler->ProcessInstructionStart(absoluteAddr);
BreakSource breakSource = BreakSource::Unspecified;
@ -1273,6 +1276,11 @@ shared_ptr<MemoryAccessCounter> Debugger::GetMemoryAccessCounter()
return _memoryAccessCounter;
}
shared_ptr<PerformanceTracker> Debugger::GetPerformanceTracker()
{
return _performanceTracker;
}
bool Debugger::IsExecutionStopped()
{
return _executionStopped || _console->IsExecutionStopped();
@ -1563,6 +1571,7 @@ void Debugger::ProcessEvent(EventType type)
}
}
} else if(type == EventType::EndFrame) {
_performanceTracker->ProcessEndOfFrame();
_memoryDumper->GatherChrPaletteInfo();
} else if(type == EventType::StartFrame) {
//Update the event viewer

View file

@ -26,6 +26,7 @@ class CodeRunner;
class BaseMapper;
class ScriptHost;
class TraceLogger;
class PerformanceTracker;
class Breakpoint;
class CodeDataLogger;
class ExpressionEvaluator;
@ -51,6 +52,7 @@ private:
shared_ptr<LabelManager> _labelManager;
shared_ptr<TraceLogger> _traceLogger;
shared_ptr<Profiler> _profiler;
shared_ptr<PerformanceTracker> _performanceTracker;
unique_ptr<CodeRunner> _codeRunner;
shared_ptr<Console> _console;
@ -234,6 +236,7 @@ public:
shared_ptr<TraceLogger> GetTraceLogger();
shared_ptr<MemoryDumper> GetMemoryDumper();
shared_ptr<MemoryAccessCounter> GetMemoryAccessCounter();
shared_ptr<PerformanceTracker> GetPerformanceTracker();
int32_t EvaluateExpression(string expression, EvalResultType &resultType, bool useCache);

View file

@ -213,4 +213,12 @@ enum class NametableDisplayMode
Normal = 0,
Grayscale = 1,
AttributeView = 2
};
};
enum PerfTrackerMode
{
Disabled = 0,
Fullscreen = 1,
Compact = 2,
TextOnly = 3
};

179
Core/PerformanceTracker.cpp Normal file
View file

@ -0,0 +1,179 @@
/*
This is code is heavily based on the Lua scripts written by upsilandre
The original scripts can be found on his blog here: http://upsilandre.over-blog.com/2018/07/compte-rendu-framerate-nes.html
*/
#include "stdafx.h"
#include "PerformanceTracker.h"
#include "Console.h"
#include "PPU.h"
#include "DebugHud.h"
enum Colors
{
Red = 0x00FF0000,
Yellow = 0x00FFD800,
OpaqueWhite = 0x00FFFFFF,
OpaqueBlack = 0x00000000,
Black = 0x40000000,
White = 0x40FFFFFF,
Blue = 0xA00000FF,
Transparent = 0xFF000000,
};
PerformanceTracker::PerformanceTracker(shared_ptr<Console> console)
{
_console = console;
_data = PerfTrackerData();
}
void PerformanceTracker::Initialize(int32_t address, AddressType type, PerfTrackerMode mode)
{
_address = address;
_type = type;
_mode = mode;
_needReset = true;
}
PerfTrackerMode PerformanceTracker::GetMode()
{
return _mode;
}
void PerformanceTracker::ProcessEndOfFrame()
{
if(_mode == PerfTrackerMode::Disabled) {
return;
}
_data.frameCount++;
_data.frameProcessed = false;
shared_ptr<DebugHud> hud = _console->GetDebugHud();
int frame = _console->GetPpu()->GetFrameCount();
if(_mode == PerfTrackerMode::TextOnly) {
hud->DrawRectangle(2, 2, 33, 22, Colors::Black, true, 1, frame);
hud->DrawRectangle(2, 2, 33, 22, Colors::OpaqueWhite, false, 1, frame);
hud->DrawString(4, 4, std::to_string(_data.fps) + "FPS", Colors::OpaqueWhite, Colors::Transparent, 1, frame);
hud->DrawString(4, 14, std::to_string(_data.updateCpu) + "%", Colors::OpaqueWhite, Colors::Transparent, 1, frame);
} else if(_mode == PerfTrackerMode::Fullscreen || _mode == PerfTrackerMode::Compact) {
hud->DrawRectangle(0, 223, 256, 10, Colors::Black, true, 1, frame);
hud->DrawLine(0, 222, 255, 222, Colors::White, 1, frame);
hud->DrawLine(0, 233, 255, 233, Colors::White, 1, frame);
hud->DrawLine(40, 223, 40, 232, Colors::White, 1, frame);
hud->DrawLine(100, 223, 100, 232, Colors::White, 1, frame);
hud->DrawLine(170, 223, 170, 232, Colors::White, 1, frame);
hud->DrawString(6, 224, std::to_string(_data.fps) + "FPS", Colors::OpaqueWhite, Colors::Transparent, 1, frame);
string cpuUsage = std::to_string(_data.updateCpu);
cpuUsage = std::string(3 - cpuUsage.size(), ' ') + cpuUsage;
hud->DrawString(46, 224, "CPU: " + cpuUsage + "%", Colors::OpaqueWhite, Colors::Transparent, 1, frame);
string avgCpuUsage = std::to_string(_data.totalCpu / _data.cpuEntry);
avgCpuUsage = std::string(3 - avgCpuUsage.size(), ' ') + avgCpuUsage;
hud->DrawString(105, 224, "Avg FPS: " + std::to_string((_data.gameFrame * 60) / _data.totalFrame), Colors::OpaqueWhite, Colors::Transparent, 1, frame);
hud->DrawString(176, 224, "Avg CPU: " + avgCpuUsage + "%", Colors::OpaqueWhite, Colors::Transparent, 1, frame);
int scale = _mode == PerfTrackerMode::Fullscreen ? 200 : 60;
hud->DrawRectangle(0, 2, 256, scale + 1, (uint32_t)Colors::Blue, true, 1, frame);
hud->DrawLine(0, 2, 255, 2, Colors::White, 1, frame);
hud->DrawLine(0, (scale / 4) + 2, 255, (scale / 4) + 2, Colors::White, 1, frame);
hud->DrawLine(0, (scale / 2) + 2, 255, (scale / 2) + 2, Colors::White, 1, frame);
hud->DrawLine(0, (scale * 3 / 4) + 2, 255, (scale * 3 / 4) + 2, Colors::White, 1, frame);
hud->DrawLine(0, scale + 2, 255, scale + 2, Colors::White, 1, frame);
hud->DrawString(1, 4, "200%/60FPS", Colors::White, Colors::Transparent, 1, frame);
hud->DrawString(0, scale / 2 + 4, "100%/30FPS", Colors::White, Colors::Transparent, 1, frame);
DrawChart(_data.cpuChartDataPoints, _data.cpuChartPos, Colors::Red, scale, 200);
DrawChart(_data.fpsChartDataPoints, _data.fpsChartPos, Colors::Yellow, scale, 60);
}
}
void PerformanceTracker::DrawChart(int *dataPoints, int startPos, int color, int scale, int maxValue)
{
shared_ptr<DebugHud> hud = _console->GetDebugHud();
int frame = _console->GetPpu()->GetFrameCount();
int dotX = 0;
int i = startPos;
do {
int dotY1 = dataPoints[i] * scale / maxValue;
int dotY2 = dataPoints[(i + 1) % 256] * scale / maxValue;
hud->DrawLine(dotX, scale + 2 - dotY1, dotX + 1, scale + 2 - dotY2, color, 1, frame);
dotX++;
i = (i + 1) % 256;
} while(i != startPos);
}
void PerformanceTracker::ProcessCpuExec(AddressTypeInfo & addressInfo)
{
if(_mode == PerfTrackerMode::Disabled || addressInfo.Address != _address || addressInfo.Type != _type) {
//Performance tracker isn't running, or address doesn't match, ignore it
return;
}
if(_needReset) {
//Options have been changed, reset everything
_data = PerfTrackerData();
_needReset = false;
}
if(_data.frameProcessed) {
//We already hit this instruction once during this frame, don't count it again
return;
}
_data.frameProcessed = true;
//Count the number of frames since the last time we processed this instruction
int lag = _data.frameCount - _data.prevFrameCount - 1;
_data.prevFrameCount = _data.frameCount;
if(lag >= 0 && lag < 3 && _data.frameCount > 3) {
//Check what percentage of the current frame has been used (since the last NMI)
int scanline = _console->GetPpu()->GetCurrentScanline();
PPUDebugState state;
_console->GetPpu()->GetState(state);
int scanlineCount = state.ScanlineCount;
_data.partialCpu = ((scanline + 20) % scanlineCount) * 100 / scanlineCount;
if(scanline >= 241) {
_data.partialCpu = 0;
}
//Store the current frame's CPU usage as a data point for the chart (each lag frame counts as +100% CPU)
int finalCpu = _data.partialCpu + (lag * 100);
_data.cpuChartDataPoints[_data.cpuChartPos] = finalCpu;
_data.cpuChartPos = (_data.cpuChartPos + 1) % 256;
//Update the average CPU statistic
_data.totalCpu += finalCpu;
_data.cpuEntry++;
//Process the last X frames since NMI, and check which ones are lag frames
for(int i = 0; i <= lag; i++) {
_data.totalFrame++;
_data.isLagFramePos = (_data.isLagFramePos + 1) % 60;
_data.isLagFrame[_data.isLagFramePos] = true;
}
_data.isLagFrame[_data.isLagFramePos] = false;
_data.gameFrame++;
//Update the onscreen display for the CPU %
_data.updateCpu = finalCpu;
//Calculate the average FPS for the last 20 frames (and add it as a data point for the chart)
_data.fps = 0;
int i = _data.isLagFramePos < 20 ? (60 - (20 - _data.isLagFramePos)) : (_data.isLagFramePos - 20);
do {
_data.fps += _data.isLagFrame[i] ? 0 : 1;
i = (i + 1) % 60;
} while(i != _data.isLagFramePos);
_data.fps *= 3;
_data.fpsChartDataPoints[_data.fpsChartPos] = _data.fps;
_data.fpsChartPos = (_data.fpsChartPos + 1) % 256;
}
}

45
Core/PerformanceTracker.h Normal file
View file

@ -0,0 +1,45 @@
#include "stdafx.h"
#include "DebuggerTypes.h"
struct PerfTrackerData
{
int frameCount = 0;
int prevFrameCount = 0;
bool frameProcessed = false;
int fps = 60;
int totalFrame = 1;
int gameFrame = 1;
int isLagFramePos = 0;
bool isLagFrame[60] = {};
int fpsChartPos = 0;
int fpsChartDataPoints[256] = {};
int totalCpu = 50;
int cpuEntry = 1;
int partialCpu = 0;
int updateCpu = 50;
int cpuChartPos = 0;
int cpuChartDataPoints[256] = {};
};
class PerformanceTracker
{
private:
shared_ptr<Console> _console;
PerfTrackerData _data;
int32_t _address = -1;
AddressType _type = AddressType::InternalRam;
PerfTrackerMode _mode = PerfTrackerMode::Disabled;
bool _needReset = false;
void DrawChart(int *dataPoints, int startPos, int color, int scale, int maxValue);
public:
PerformanceTracker(shared_ptr<Console> console);
void Initialize(int32_t address, AddressType type, PerfTrackerMode mode);
PerfTrackerMode GetMode();
void ProcessEndOfFrame();
void ProcessCpuExec(AddressTypeInfo &addressInfo);
};

View file

@ -33,7 +33,15 @@
this.mnuMarkAsCode = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMarkAsData = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMarkAsUnidentifiedData = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
this.mnuPerfTracker = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPerfTrackerFullscreen = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPerfTrackerCompact = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPerfTrackerTextOnly = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
this.mnuPerfTrackerDisabled = new System.Windows.Forms.ToolStripMenuItem();
this.sepMarkSelectionAs = new System.Windows.Forms.ToolStripSeparator();
this.mnuEditSourceFile = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEditSelectedCode = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEditSubroutine = new System.Windows.Forms.ToolStripMenuItem();
this.mnuUndoPrgChrEdit = new System.Windows.Forms.ToolStripMenuItem();
@ -69,7 +77,6 @@
this.sepSwitchView = new System.Windows.Forms.ToolStripSeparator();
this.mnuSwitchView = new System.Windows.Forms.ToolStripMenuItem();
this.mnuShowSourceAsComments = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEditSourceFile = new System.Windows.Forms.ToolStripMenuItem();
this.contextMenu.SuspendLayout();
this.SuspendLayout();
//
@ -77,6 +84,8 @@
//
this.contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuMarkSelectionAs,
this.toolStripMenuItem3,
this.mnuPerfTracker,
this.sepMarkSelectionAs,
this.mnuEditSourceFile,
this.mnuEditSelectedCode,
@ -106,7 +115,7 @@
this.mnuSwitchView,
this.mnuShowSourceAsComments});
this.contextMenu.Name = "contextMenuWatch";
this.contextMenu.Size = new System.Drawing.Size(254, 536);
this.contextMenu.Size = new System.Drawing.Size(254, 564);
this.contextMenu.Closed += new System.Windows.Forms.ToolStripDropDownClosedEventHandler(this.contextMenuCode_Closed);
this.contextMenu.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuCode_Opening);
//
@ -144,11 +153,73 @@
this.mnuMarkAsUnidentifiedData.Text = "Unidentified Code/Data";
this.mnuMarkAsUnidentifiedData.Click += new System.EventHandler(this.mnuMarkAsUnidentifiedData_Click);
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
this.toolStripMenuItem3.Size = new System.Drawing.Size(250, 6);
//
// mnuPerfTracker
//
this.mnuPerfTracker.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuPerfTrackerFullscreen,
this.mnuPerfTrackerCompact,
this.mnuPerfTrackerTextOnly,
this.toolStripMenuItem4,
this.mnuPerfTrackerDisabled});
this.mnuPerfTracker.Image = global::Mesen.GUI.Properties.Resources.PerfTracker;
this.mnuPerfTracker.Name = "mnuPerfTracker";
this.mnuPerfTracker.Size = new System.Drawing.Size(253, 22);
this.mnuPerfTracker.Text = "Performance Tracker";
this.mnuPerfTracker.DropDownOpening += new System.EventHandler(this.mnuPerfTracker_DropDownOpening);
//
// mnuPerfTrackerFullscreen
//
this.mnuPerfTrackerFullscreen.Name = "mnuPerfTrackerFullscreen";
this.mnuPerfTrackerFullscreen.Size = new System.Drawing.Size(152, 22);
this.mnuPerfTrackerFullscreen.Text = "Fullscreen";
this.mnuPerfTrackerFullscreen.Click += new System.EventHandler(this.mnuPerfTrackerFullscreen_Click);
//
// mnuPerfTrackerCompact
//
this.mnuPerfTrackerCompact.Name = "mnuPerfTrackerCompact";
this.mnuPerfTrackerCompact.Size = new System.Drawing.Size(152, 22);
this.mnuPerfTrackerCompact.Text = "Compact";
this.mnuPerfTrackerCompact.Click += new System.EventHandler(this.mnuPerfTrackerCompact_Click);
//
// mnuPerfTrackerTextOnly
//
this.mnuPerfTrackerTextOnly.Name = "mnuPerfTrackerTextOnly";
this.mnuPerfTrackerTextOnly.Size = new System.Drawing.Size(152, 22);
this.mnuPerfTrackerTextOnly.Text = "Text-only";
this.mnuPerfTrackerTextOnly.Click += new System.EventHandler(this.mnuPerfTrackerTextOnly_Click);
//
// toolStripMenuItem4
//
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
this.toolStripMenuItem4.Size = new System.Drawing.Size(149, 6);
//
// mnuPerfTrackerDisabled
//
this.mnuPerfTrackerDisabled.Checked = true;
this.mnuPerfTrackerDisabled.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuPerfTrackerDisabled.Name = "mnuPerfTrackerDisabled";
this.mnuPerfTrackerDisabled.Size = new System.Drawing.Size(152, 22);
this.mnuPerfTrackerDisabled.Text = "Disabled";
this.mnuPerfTrackerDisabled.Click += new System.EventHandler(this.mnuPerfTrackerDisabled_Click);
//
// sepMarkSelectionAs
//
this.sepMarkSelectionAs.Name = "sepMarkSelectionAs";
this.sepMarkSelectionAs.Size = new System.Drawing.Size(250, 6);
//
// mnuEditSourceFile
//
this.mnuEditSourceFile.Image = global::Mesen.GUI.Properties.Resources.Edit;
this.mnuEditSourceFile.Name = "mnuEditSourceFile";
this.mnuEditSourceFile.Size = new System.Drawing.Size(253, 22);
this.mnuEditSourceFile.Text = "Edit Source File";
this.mnuEditSourceFile.Click += new System.EventHandler(this.mnuEditSourceFile_Click);
//
// mnuEditSelectedCode
//
this.mnuEditSelectedCode.Image = global::Mesen.GUI.Properties.Resources.Edit;
@ -404,14 +475,6 @@
this.mnuShowSourceAsComments.Text = "Show source code as comments";
this.mnuShowSourceAsComments.Click += new System.EventHandler(this.mnuShowSourceAsComments_Click);
//
// mnuEditSourceFile
//
this.mnuEditSourceFile.Image = global::Mesen.GUI.Properties.Resources.Edit;
this.mnuEditSourceFile.Name = "mnuEditSourceFile";
this.mnuEditSourceFile.Size = new System.Drawing.Size(253, 22);
this.mnuEditSourceFile.Text = "Edit Source File";
this.mnuEditSourceFile.Click += new System.EventHandler(this.mnuEditSourceFile_Click);
//
// CodeViewerActions
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -465,5 +528,12 @@
public System.Windows.Forms.ContextMenuStrip contextMenu;
private System.Windows.Forms.ToolStripMenuItem mnuShowSourceAsComments;
private System.Windows.Forms.ToolStripMenuItem mnuEditSourceFile;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
private System.Windows.Forms.ToolStripMenuItem mnuPerfTracker;
private System.Windows.Forms.ToolStripMenuItem mnuPerfTrackerFullscreen;
private System.Windows.Forms.ToolStripMenuItem mnuPerfTrackerCompact;
private System.Windows.Forms.ToolStripMenuItem mnuPerfTrackerTextOnly;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4;
private System.Windows.Forms.ToolStripMenuItem mnuPerfTrackerDisabled;
}
}

View file

@ -508,6 +508,16 @@ namespace Mesen.GUI.Debugger.Controls
mnuSwitchView.Text = IsSourceView ? "Switch to Disassembly View" : "Switch to Source View";
AddressTypeInfo addressInfo = Viewer.GetAddressInfo(Viewer.CodeViewer.SelectedLine);
if(addressInfo.Address >= 0) {
int relAddress = InteropEmu.DebugGetRelativeAddress((uint)addressInfo.Address, addressInfo.Type);
mnuPerfTracker.Text = "Performance Tracker ($" + relAddress.ToString("X4") + ")";
mnuPerfTracker.Enabled = true;
} else {
mnuPerfTracker.Text = "Performance Tracker";
mnuPerfTracker.Enabled = false;
}
string word = Viewer.CodeViewer.GetWordUnderLocation(mouseLocation);
Ld65DbgImporter.SymbolInfo symbol = null;
CodeLabel codeLabel = null;
@ -615,5 +625,40 @@ namespace Mesen.GUI.Debugger.Controls
return false;
}
}
private void SetPerformanceTracker(PerfTrackerMode mode)
{
AddressTypeInfo addressInfo = Viewer.GetAddressInfo(Viewer.CodeViewer.SelectedLine);
InteropEmu.DebugSetPerformanceTracker(addressInfo.Address, addressInfo.Type, mode);
}
private void mnuPerfTrackerFullscreen_Click(object sender, EventArgs e)
{
SetPerformanceTracker(PerfTrackerMode.Fullscreen);
}
private void mnuPerfTrackerCompact_Click(object sender, EventArgs e)
{
SetPerformanceTracker(PerfTrackerMode.Compact);
}
private void mnuPerfTrackerTextOnly_Click(object sender, EventArgs e)
{
SetPerformanceTracker(PerfTrackerMode.TextOnly);
}
private void mnuPerfTrackerDisabled_Click(object sender, EventArgs e)
{
SetPerformanceTracker(PerfTrackerMode.Disabled);
}
private void mnuPerfTracker_DropDownOpening(object sender, EventArgs e)
{
PerfTrackerMode mode = InteropEmu.DebugGetPerformanceTrackerMode();
mnuPerfTrackerFullscreen.Checked = mode == PerfTrackerMode.Fullscreen;
mnuPerfTrackerCompact.Checked = mode == PerfTrackerMode.Compact;
mnuPerfTrackerTextOnly.Checked = mode == PerfTrackerMode.TextOnly;
mnuPerfTrackerDisabled.Checked = mode == PerfTrackerMode.Disabled;
}
}
}

View file

@ -1260,6 +1260,7 @@
<Compile Include="RuntimeChecker.cs" />
<Compile Include="SingleInstance.cs" />
<Compile Include="TestRunner.cs" />
<None Include="Resources\PerfTracker.png" />
<None Include="Resources\Zoom2x.png" />
<None Include="Resources\Expand.png" />
<None Include="Resources\Collapse.png" />

View file

@ -252,6 +252,9 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void DebugSetMemoryValue(DebugMemoryType type, UInt32 address, byte value);
[DllImport(DLLPath)] public static extern void DebugSetInputOverride(Int32 port, Int32 state);
[DllImport(DLLPath)] public static extern PerfTrackerMode DebugGetPerformanceTrackerMode();
[DllImport(DLLPath)] public static extern void DebugSetPerformanceTracker(Int32 address, AddressType type, PerfTrackerMode mode);
[DllImport(DLLPath)] public static extern void DebugSetScriptTimeout(UInt32 timeout);
[DllImport(DLLPath)] public static extern Int32 DebugLoadScript([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string name, [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]string content, Int32 scriptId = -1);
[DllImport(DLLPath)] public static extern void DebugRemoveScript(Int32 scriptId);
@ -2415,6 +2418,14 @@ namespace Mesen.GUI
}
}
public enum PerfTrackerMode
{
Disabled = 0,
Fullscreen = 1,
Compact = 2,
TextOnly = 3
}
public enum InteropMemoryOperationType
{
Read = 0,

View file

@ -700,6 +700,16 @@ namespace Mesen.GUI.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap PerfTracker {
get {
object obj = ResourceManager.GetObject("PerfTracker", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View file

@ -442,4 +442,7 @@
<data name="Zoom2x" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Zoom2x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="PerfTracker" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\PerfTracker.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

Binary file not shown.

After

Width:  |  Height:  |  Size: 611 B

View file

@ -8,6 +8,7 @@
#include "../Core/Profiler.h"
#include "../Core/Assembler.h"
#include "../Core/TraceLogger.h"
#include "../Core/PerformanceTracker.h"
#include "../Core/LuaScriptingContext.h"
enum class ConsoleId;
@ -137,6 +138,9 @@ extern "C"
DllExport int32_t __stdcall DebugFindSubEntryPoint(uint16_t relativeAddress) { return GetDebugger()->FindSubEntryPoint(relativeAddress); }
DllExport PerfTrackerMode __stdcall DebugGetPerformanceTrackerMode() { return GetDebugger()->GetPerformanceTracker()->GetMode(); }
DllExport void __stdcall DebugSetPerformanceTracker(uint32_t address, AddressType type, PerfTrackerMode mode) { GetDebugger()->GetPerformanceTracker()->Initialize(address, type, mode); }
DllExport void __stdcall DebugSetInputOverride(uint32_t port, uint32_t state) { GetDebugger()->SetInputOverride(port, state); }
DllExport int32_t __stdcall DebugLoadScript(char* name, char* content, int32_t scriptId) { return GetDebugger()->LoadScript(name, content, scriptId); }