From 3f801e22ff75b3ad88ff06d88b1431d893062080 Mon Sep 17 00:00:00 2001 From: Souryo Date: Sun, 5 Jun 2016 10:26:05 -0400 Subject: [PATCH] Debugger: Option to display the current frame as it is being drawn (pixel by pixel), instead of displaying when the full frame is done. --- Core/Debugger.cpp | 20 +++ Core/Debugger.h | 11 ++ Core/PPU.cpp | 8 ++ Core/PPU.h | 1 + GUI.NET/Config/DebugInfo.cs | 1 + GUI.NET/Debugger/frmDebugger.Designer.cs | 161 +++++++++++++---------- GUI.NET/Debugger/frmDebugger.cs | 8 ++ GUI.NET/InteropEmu.cs | 10 +- InteropDLL/DebugWrapper.cpp | 2 + 9 files changed, 150 insertions(+), 72 deletions(-) diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index e9dc8899..2babe277 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -30,6 +30,8 @@ Debugger::Debugger(shared_ptr console, shared_ptr cpu, shared_ptr< _stepOverAddr = -1; _stepCycleCount = -1; + _flags = 0; + _hasBreakpoint = false; _bpUpdateNeeded = false; _executionStopped = false; @@ -66,6 +68,21 @@ void Debugger::Resume() } } +void Debugger::SetFlags(uint32_t flags) +{ + _flags = flags; +} + +bool Debugger::CheckFlag(DebuggerFlags flag) +{ + return (_flags & (uint32_t)flag) == (uint32_t)flag; +} + +bool Debugger::IsEnabled() +{ + return Debugger::Instance != nullptr; +} + void Debugger::BreakIfDebugging() { if(Debugger::Instance != nullptr) { @@ -339,6 +356,9 @@ bool Debugger::SleepUntilResume() SoundMixer::StopAudio(); MessageManager::SendNotification(ConsoleNotificationType::CodeBreak); _stepOverAddr = -1; + if(CheckFlag(DebuggerFlags::PpuPartialDraw)) { + _ppu->DebugSendFrame(); + } while(stepCount == 0 && !_stopFlag && _suspendCount == 0) { std::this_thread::sleep_for(std::chrono::duration(10)); stepCount = _stepCount.load(); diff --git a/Core/Debugger.h b/Core/Debugger.h index 93743624..e8351a82 100644 --- a/Core/Debugger.h +++ b/Core/Debugger.h @@ -30,6 +30,11 @@ enum class DebugMemoryType ChrRam = 7, }; +enum class DebuggerFlags +{ + PpuPartialDraw = 1 +}; + class Debugger { private: @@ -68,6 +73,8 @@ private: uint16_t *_currentReadAddr; //Used to alter the executing address via "Set Next Statement" + uint32_t _flags; + string _romFilepath; string _outputCache; atomic _stepCount; @@ -93,6 +100,9 @@ public: Debugger(shared_ptr console, shared_ptr cpu, shared_ptr ppu, shared_ptr memoryManager, shared_ptr mapper); ~Debugger(); + void SetFlags(uint32_t flags); + bool CheckFlag(DebuggerFlags flag); + void SetBreakpoints(Breakpoint breakpoints[], uint32_t length); uint32_t GetMemoryState(DebugMemoryType type, uint8_t *buffer); @@ -138,5 +148,6 @@ public: static void ProcessVramOperation(MemoryOperationType type, uint16_t addr, uint8_t value); static void ProcessPpuCycle(); + static bool IsEnabled(); static void BreakIfDebugging(); }; \ No newline at end of file diff --git a/Core/PPU.cpp b/Core/PPU.cpp index 1385f963..a0aef813 100644 --- a/Core/PPU.cpp +++ b/Core/PPU.cpp @@ -804,6 +804,11 @@ void PPU::CopyOAMData() } } +void PPU::DebugSendFrame() +{ + VideoDecoder::GetInstance()->UpdateFrame(_currentOutputBuffer); +} + void PPU::SendFrame() { MessageManager::SendNotification(ConsoleNotificationType::PpuFrameDone, _currentOutputBuffer); @@ -813,6 +818,9 @@ void PPU::SendFrame() //Switch output buffer. VideoDecoder will decode the last frame while we build the new one. //If VideoDecoder isn't fast enough, UpdateFrame will block until it is ready to accept a new frame. _currentOutputBuffer = (_currentOutputBuffer == _outputBuffers[0]) ? _outputBuffers[1] : _outputBuffers[0]; + if(Debugger::IsEnabled()) { + memset(_currentOutputBuffer, 0, PPU::PixelCount * 2); + } } void PPU::BeginVBlank() diff --git a/Core/PPU.h b/Core/PPU.h index dd4c7cb4..1448d878 100644 --- a/Core/PPU.h +++ b/Core/PPU.h @@ -217,6 +217,7 @@ class PPU : public IMemoryHandler, public Snapshotable void Reset(); + void DebugSendFrame(); PPUDebugState GetState(); void GetMemoryRanges(MemoryRanges &ranges) diff --git a/GUI.NET/Config/DebugInfo.cs b/GUI.NET/Config/DebugInfo.cs index 36ba6b08..d6899bf5 100644 --- a/GUI.NET/Config/DebugInfo.cs +++ b/GUI.NET/Config/DebugInfo.cs @@ -26,6 +26,7 @@ namespace Mesen.GUI.Config public bool HexDisplay = true; public bool PpuAutoRefresh = true; + public bool PpuPartialDraw = false; public bool RamAutoRefresh = true; public int RamColumnCount = 2; diff --git a/GUI.NET/Debugger/frmDebugger.Designer.cs b/GUI.NET/Debugger/frmDebugger.Designer.cs index d3133ace..16e8ea8f 100644 --- a/GUI.NET/Debugger/frmDebugger.Designer.cs +++ b/GUI.NET/Debugger/frmDebugger.Designer.cs @@ -51,12 +51,6 @@ this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator(); this.mnuClose = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuView = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuSplitView = new System.Windows.Forms.ToolStripMenuItem(); - this.fontSizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuIncreaseFontSize = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuDecreaseFontSize = new System.Windows.Forms.ToolStripMenuItem(); - this.mnuResetFontSize = new System.Windows.Forms.ToolStripMenuItem(); this.debugToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.mnuContinue = new System.Windows.Forms.ToolStripMenuItem(); this.mnuBreak = new System.Windows.Forms.ToolStripMenuItem(); @@ -68,6 +62,7 @@ this.mnuDisableEnableBreakpoint = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator(); this.mnuRunOneFrame = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuRunPpuCycle = new System.Windows.Forms.ToolStripMenuItem(); this.searchToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.mnuFind = new System.Windows.Forms.ToolStripMenuItem(); this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem(); @@ -77,6 +72,14 @@ this.mnuGoToIrqHandler = new System.Windows.Forms.ToolStripMenuItem(); this.mnuGoToNmiHandler = new System.Windows.Forms.ToolStripMenuItem(); this.mnuGoToResetHandler = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuOptions = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuSplitView = new System.Windows.Forms.ToolStripMenuItem(); + this.fontSizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuIncreaseFontSize = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuDecreaseFontSize = new System.Windows.Forms.ToolStripMenuItem(); + this.mnuResetFontSize = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator(); + this.mnuPpuPartialDraw = new System.Windows.Forms.ToolStripMenuItem(); this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.mnuPpuViewer = new System.Windows.Forms.ToolStripMenuItem(); this.mnuMemoryViewer = new System.Windows.Forms.ToolStripMenuItem(); @@ -96,7 +99,6 @@ this.lblChrAnalysis = new System.Windows.Forms.ToolStripStatusLabel(); this.lblChrAnalysisResult = new System.Windows.Forms.ToolStripStatusLabel(); this.tmrCdlRatios = new System.Windows.Forms.Timer(this.components); - this.mnuRunPpuCycle = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit(); this.splitContainer.Panel1.SuspendLayout(); this.splitContainer.Panel2.SuspendLayout(); @@ -288,9 +290,9 @@ // this.menuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.fileToolStripMenuItem, - this.mnuView, this.debugToolStripMenuItem, this.searchToolStripMenuItem, + this.mnuOptions, this.toolsToolStripMenuItem}); this.menuStrip.Location = new System.Drawing.Point(0, 0); this.menuStrip.Name = "menuStrip"; @@ -319,60 +321,6 @@ this.mnuClose.Text = "Close"; this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click); // - // mnuView - // - this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuSplitView, - this.fontSizeToolStripMenuItem}); - this.mnuView.Name = "mnuView"; - this.mnuView.Size = new System.Drawing.Size(44, 20); - this.mnuView.Text = "View"; - // - // mnuSplitView - // - this.mnuSplitView.CheckOnClick = true; - this.mnuSplitView.Name = "mnuSplitView"; - this.mnuSplitView.Size = new System.Drawing.Size(125, 22); - this.mnuSplitView.Text = "Split View"; - this.mnuSplitView.Click += new System.EventHandler(this.mnuSplitView_Click); - // - // fontSizeToolStripMenuItem - // - this.fontSizeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.mnuIncreaseFontSize, - this.mnuDecreaseFontSize, - this.mnuResetFontSize}); - this.fontSizeToolStripMenuItem.Name = "fontSizeToolStripMenuItem"; - this.fontSizeToolStripMenuItem.Size = new System.Drawing.Size(125, 22); - this.fontSizeToolStripMenuItem.Text = "Text Size"; - // - // mnuIncreaseFontSize - // - this.mnuIncreaseFontSize.Name = "mnuIncreaseFontSize"; - this.mnuIncreaseFontSize.ShortcutKeyDisplayString = "Ctrl++"; - this.mnuIncreaseFontSize.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Oemplus))); - this.mnuIncreaseFontSize.Size = new System.Drawing.Size(197, 22); - this.mnuIncreaseFontSize.Text = "Increase"; - this.mnuIncreaseFontSize.Click += new System.EventHandler(this.mnuIncreaseFontSize_Click); - // - // mnuDecreaseFontSize - // - this.mnuDecreaseFontSize.Name = "mnuDecreaseFontSize"; - this.mnuDecreaseFontSize.ShortcutKeyDisplayString = "Ctrl+-"; - this.mnuDecreaseFontSize.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.OemMinus))); - this.mnuDecreaseFontSize.Size = new System.Drawing.Size(197, 22); - this.mnuDecreaseFontSize.Text = "Decrease"; - this.mnuDecreaseFontSize.Click += new System.EventHandler(this.mnuDecreaseFontSize_Click); - // - // mnuResetFontSize - // - this.mnuResetFontSize.Name = "mnuResetFontSize"; - this.mnuResetFontSize.ShortcutKeyDisplayString = "Ctrl+0"; - this.mnuResetFontSize.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D0))); - this.mnuResetFontSize.Size = new System.Drawing.Size(197, 22); - this.mnuResetFontSize.Text = "Reset to Default"; - this.mnuResetFontSize.Click += new System.EventHandler(this.mnuResetFontSize_Click); - // // debugToolStripMenuItem // this.debugToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -467,6 +415,14 @@ this.mnuRunOneFrame.Text = "Run one frame"; this.mnuRunOneFrame.Click += new System.EventHandler(this.mnuRunOneFrame_Click); // + // mnuRunPpuCycle + // + this.mnuRunPpuCycle.Name = "mnuRunPpuCycle"; + this.mnuRunPpuCycle.ShortcutKeys = System.Windows.Forms.Keys.F6; + this.mnuRunPpuCycle.Size = new System.Drawing.Size(258, 22); + this.mnuRunPpuCycle.Text = "Run one PPU cycle"; + this.mnuRunPpuCycle.Click += new System.EventHandler(this.mnuRunPpuCycle_Click); + // // searchToolStripMenuItem // this.searchToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -542,6 +498,75 @@ this.mnuGoToResetHandler.Text = "Reset Handler"; this.mnuGoToResetHandler.Click += new System.EventHandler(this.mnuGoToResetHandler_Click); // + // mnuOptions + // + this.mnuOptions.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mnuSplitView, + this.fontSizeToolStripMenuItem, + this.toolStripMenuItem5, + this.mnuPpuPartialDraw}); + this.mnuOptions.Name = "mnuOptions"; + this.mnuOptions.Size = new System.Drawing.Size(61, 20); + this.mnuOptions.Text = "Options"; + // + // mnuSplitView + // + this.mnuSplitView.CheckOnClick = true; + this.mnuSplitView.Name = "mnuSplitView"; + this.mnuSplitView.Size = new System.Drawing.Size(171, 22); + this.mnuSplitView.Text = "Split View"; + this.mnuSplitView.Click += new System.EventHandler(this.mnuSplitView_Click); + // + // fontSizeToolStripMenuItem + // + this.fontSizeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.mnuIncreaseFontSize, + this.mnuDecreaseFontSize, + this.mnuResetFontSize}); + this.fontSizeToolStripMenuItem.Name = "fontSizeToolStripMenuItem"; + this.fontSizeToolStripMenuItem.Size = new System.Drawing.Size(171, 22); + this.fontSizeToolStripMenuItem.Text = "Text Size"; + // + // mnuIncreaseFontSize + // + this.mnuIncreaseFontSize.Name = "mnuIncreaseFontSize"; + this.mnuIncreaseFontSize.ShortcutKeyDisplayString = "Ctrl++"; + this.mnuIncreaseFontSize.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Oemplus))); + this.mnuIncreaseFontSize.Size = new System.Drawing.Size(197, 22); + this.mnuIncreaseFontSize.Text = "Increase"; + this.mnuIncreaseFontSize.Click += new System.EventHandler(this.mnuIncreaseFontSize_Click); + // + // mnuDecreaseFontSize + // + this.mnuDecreaseFontSize.Name = "mnuDecreaseFontSize"; + this.mnuDecreaseFontSize.ShortcutKeyDisplayString = "Ctrl+-"; + this.mnuDecreaseFontSize.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.OemMinus))); + this.mnuDecreaseFontSize.Size = new System.Drawing.Size(197, 22); + this.mnuDecreaseFontSize.Text = "Decrease"; + this.mnuDecreaseFontSize.Click += new System.EventHandler(this.mnuDecreaseFontSize_Click); + // + // mnuResetFontSize + // + this.mnuResetFontSize.Name = "mnuResetFontSize"; + this.mnuResetFontSize.ShortcutKeyDisplayString = "Ctrl+0"; + this.mnuResetFontSize.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.D0))); + this.mnuResetFontSize.Size = new System.Drawing.Size(197, 22); + this.mnuResetFontSize.Text = "Reset to Default"; + this.mnuResetFontSize.Click += new System.EventHandler(this.mnuResetFontSize_Click); + // + // toolStripMenuItem5 + // + this.toolStripMenuItem5.Name = "toolStripMenuItem5"; + this.toolStripMenuItem5.Size = new System.Drawing.Size(168, 6); + // + // mnuPpuPartialDraw + // + this.mnuPpuPartialDraw.CheckOnClick = true; + this.mnuPpuPartialDraw.Name = "mnuPpuPartialDraw"; + this.mnuPpuPartialDraw.Size = new System.Drawing.Size(171, 22); + this.mnuPpuPartialDraw.Text = "Draw partial frame"; + this.mnuPpuPartialDraw.Click += new System.EventHandler(this.mnuPpuPartialDraw_Click); + // // toolsToolStripMenuItem // this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -689,14 +714,6 @@ this.tmrCdlRatios.Interval = 300; this.tmrCdlRatios.Tick += new System.EventHandler(this.tmrCdlRatios_Tick); // - // mnuRunPpuCycle - // - this.mnuRunPpuCycle.Name = "mnuRunPpuCycle"; - this.mnuRunPpuCycle.ShortcutKeys = System.Windows.Forms.Keys.F6; - this.mnuRunPpuCycle.Size = new System.Drawing.Size(258, 22); - this.mnuRunPpuCycle.Text = "Run one PPU cycle"; - this.mnuRunPpuCycle.Click += new System.EventHandler(this.mnuRunPpuCycle_Click); - // // frmDebugger // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -760,7 +777,7 @@ private ctrlConsoleStatus ctrlConsoleStatus; private System.Windows.Forms.ToolStripMenuItem mnuClose; private ctrlDebuggerCode ctrlDebuggerCodeSplit; - private System.Windows.Forms.ToolStripMenuItem mnuView; + private System.Windows.Forms.ToolStripMenuItem mnuOptions; private System.Windows.Forms.ToolStripMenuItem mnuSplitView; private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem mnuPpuViewer; @@ -796,5 +813,7 @@ private System.Windows.Forms.ToolStripMenuItem mnuGoToResetHandler; private System.Windows.Forms.ToolStripMenuItem mnuTraceLogger; private System.Windows.Forms.ToolStripMenuItem mnuRunPpuCycle; + private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5; + private System.Windows.Forms.ToolStripMenuItem mnuPpuPartialDraw; } } \ No newline at end of file diff --git a/GUI.NET/Debugger/frmDebugger.cs b/GUI.NET/Debugger/frmDebugger.cs index bd9a3dca..ec676947 100644 --- a/GUI.NET/Debugger/frmDebugger.cs +++ b/GUI.NET/Debugger/frmDebugger.cs @@ -26,6 +26,7 @@ namespace Mesen.GUI.Debugger if(!this.DesignMode) { this.mnuSplitView.Checked = ConfigManager.Config.DebugInfo.SplitView; + this.mnuPpuPartialDraw.Checked = ConfigManager.Config.DebugInfo.PpuPartialDraw; _lastCodeWindow = ctrlDebuggerCode; @@ -75,6 +76,7 @@ namespace Mesen.GUI.Debugger case InteropEmu.ConsoleNotificationType.CodeBreak: this.BeginInvoke((MethodInvoker)(() => UpdateDebugger())); BreakpointManager.SetBreakpoints(); + InteropEmu.DebugSetFlags(mnuPpuPartialDraw.Checked ? DebuggerFlags.PpuPartialDraw : DebuggerFlags.None); break; case InteropEmu.ConsoleNotificationType.GameReset: @@ -368,5 +370,11 @@ namespace Mesen.GUI.Debugger { InteropEmu.DebugPpuStep(1); } + + private void mnuPpuPartialDraw_Click(object sender, EventArgs e) + { + ConfigManager.Config.DebugInfo.PpuPartialDraw = mnuPpuPartialDraw.Checked; + ConfigManager.ApplyChanges(); + } } } diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 5c526327..a04f8fbb 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -130,6 +130,7 @@ namespace Mesen.GUI [DllImport(DLLPath)] public static extern void DebugInitialize(); [DllImport(DLLPath)] public static extern void DebugRelease(); + [DllImport(DLLPath)] public static extern void DebugSetFlags(DebuggerFlags flags); [DllImport(DLLPath)] public static extern void DebugGetState(ref DebugState state); [DllImport(DLLPath)] public static extern void DebugSetBreakpoints([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]InteropBreakpoint[] breakpoints, UInt32 length); [DllImport(DLLPath)] public static extern void DebugStep(UInt32 count); @@ -574,7 +575,14 @@ namespace Mesen.GUI InBackground = 0x40000000, } - + + [Flags] + public enum DebuggerFlags + { + None = 0, + PpuPartialDraw = 1 + } + public struct InteropBreakpoint { public BreakpointType Type; diff --git a/InteropDLL/DebugWrapper.cpp b/InteropDLL/DebugWrapper.cpp index 50fff65d..f9a15e9d 100644 --- a/InteropDLL/DebugWrapper.cpp +++ b/InteropDLL/DebugWrapper.cpp @@ -21,6 +21,8 @@ extern "C" Console::GetInstance()->StopDebugger(); } + DllExport void __stdcall DebugSetFlags(uint32_t flags) { GetDebugger()->SetFlags(flags); } + DllExport void __stdcall DebugGetState(DebugState *state) { GetDebugger()->GetState(state); } DllExport void __stdcall DebugSetBreakpoints(Breakpoint breakpoints[], uint32_t length) { GetDebugger()->SetBreakpoints(breakpoints, length); }