Debugger: Added refresh speed options for PPU viewers

This commit is contained in:
Sour 2019-10-06 18:28:04 -04:00
parent d52caf964e
commit 99846954af
15 changed files with 501 additions and 250 deletions

View file

@ -16,6 +16,9 @@ namespace Mesen.GUI.Config
public int ImageScale = 1;
public bool RefreshOnBreakPause = true;
public bool AutoRefresh = true;
public RefreshSpeed AutoRefreshSpeed = RefreshSpeed.Normal;
public bool ShowPpuRegisterWrites = true;
public bool ShowPpuRegisterReads = true;
public bool ShowCpuRegisterWrites = true;

View file

@ -26,6 +26,8 @@ namespace Mesen.GUI.Config
public int RefreshScanline = 240;
public int RefreshCycle = 0;
public RefreshSpeed AutoRefreshSpeed = RefreshSpeed.Low;
public SpriteViewerConfig()
{
}

View file

@ -31,6 +31,7 @@ namespace Mesen.GUI.Config
public int SelectedPalette = 0;
public bool AutoRefresh = true;
public RefreshSpeed AutoRefreshSpeed = RefreshSpeed.Low;
public int RefreshScanline = 240;
public int RefreshCycle = 0;

View file

@ -23,6 +23,8 @@ namespace Mesen.GUI.Config
public bool ShowScrollOverlay = false;
public bool ShowTileGrid = false;
public RefreshSpeed AutoRefreshSpeed = RefreshSpeed.Low;
public bool AutoRefresh = true;
public int RefreshScanline = 240;
public int RefreshCycle = 0;

View file

@ -32,8 +32,15 @@
this.mnuFile = new System.Windows.Forms.ToolStripMenuItem();
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
this.mnuView = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRefreshOnBreakPause = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshSpeed = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshLow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshNormal = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshHigh = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRefreshOnBreakPause = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
this.mnuZoomIn = new System.Windows.Forms.ToolStripMenuItem();
this.mnuZoomOut = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMain.SuspendLayout();
@ -77,14 +84,69 @@
// mnuView
//
this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuRefreshOnBreakPause,
this.mnuRefresh,
this.mnuAutoRefreshSpeed,
this.toolStripMenuItem1,
this.mnuAutoRefresh,
this.mnuRefreshOnBreakPause,
this.toolStripMenuItem2,
this.mnuZoomIn,
this.mnuZoomOut});
this.mnuView.Name = "mnuView";
this.mnuView.Size = new System.Drawing.Size(44, 20);
this.mnuView.Text = "View";
//
// mnuRefresh
//
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Refresh;
this.mnuRefresh.Name = "mnuRefresh";
this.mnuRefresh.Size = new System.Drawing.Size(198, 22);
this.mnuRefresh.Text = "Refresh";
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(195, 6);
//
// mnuAutoRefresh
//
this.mnuAutoRefresh.Checked = true;
this.mnuAutoRefresh.CheckOnClick = true;
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
this.mnuAutoRefresh.Size = new System.Drawing.Size(198, 22);
this.mnuAutoRefresh.Text = "Auto-refresh";
//
// mnuAutoRefreshSpeed
//
this.mnuAutoRefreshSpeed.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAutoRefreshLow,
this.mnuAutoRefreshNormal,
this.mnuAutoRefreshHigh});
this.mnuAutoRefreshSpeed.Image = global::Mesen.GUI.Properties.Resources.Speed;
this.mnuAutoRefreshSpeed.Name = "mnuAutoRefreshSpeed";
this.mnuAutoRefreshSpeed.Size = new System.Drawing.Size(198, 22);
this.mnuAutoRefreshSpeed.Text = "Auto-refresh Speed";
//
// mnuAutoRefreshLow
//
this.mnuAutoRefreshLow.Name = "mnuAutoRefreshLow";
this.mnuAutoRefreshLow.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshLow.Text = "Low (15 FPS)";
//
// mnuAutoRefreshNormal
//
this.mnuAutoRefreshNormal.Name = "mnuAutoRefreshNormal";
this.mnuAutoRefreshNormal.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshNormal.Text = "Normal (30 FPS)";
//
// mnuAutoRefreshHigh
//
this.mnuAutoRefreshHigh.Name = "mnuAutoRefreshHigh";
this.mnuAutoRefreshHigh.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshHigh.Text = "High (60 FPS)";
//
// mnuRefreshOnBreakPause
//
this.mnuRefreshOnBreakPause.CheckOnClick = true;
@ -93,10 +155,10 @@
this.mnuRefreshOnBreakPause.Text = "Refresh on break/pause";
this.mnuRefreshOnBreakPause.Click += new System.EventHandler(this.mnuRefreshOnBreakPause_Click);
//
// toolStripMenuItem1
// toolStripMenuItem2
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(195, 6);
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(195, 6);
//
// mnuZoomIn
//
@ -139,5 +201,12 @@
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem mnuZoomIn;
private System.Windows.Forms.ToolStripMenuItem mnuZoomOut;
private System.Windows.Forms.ToolStripMenuItem mnuRefresh;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefresh;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshSpeed;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshLow;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshNormal;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshHigh;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
}
}

View file

@ -1,4 +1,5 @@
using Mesen.GUI.Config;
using Mesen.GUI.Debugger.Controls;
using Mesen.GUI.Forms;
using System;
using System.Collections.Generic;
@ -12,10 +13,12 @@ using System.Windows.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmEventViewer : BaseForm
public partial class frmEventViewer : BaseForm, IRefresh
{
private NotificationListener _notifListener;
private DateTime _lastUpdate = DateTime.MinValue;
private WindowRefreshManager _refreshManager;
public ctrlScanlineCycleSelect ScanlineCycleSelect { get { return null; } }
public frmEventViewer()
{
@ -41,17 +44,28 @@ namespace Mesen.GUI.Debugger
_notifListener = new NotificationListener();
_notifListener.OnNotification += OnNotificationReceived;
_refreshManager = new WindowRefreshManager(this);
_refreshManager.AutoRefresh = config.AutoRefresh;
_refreshManager.AutoRefreshSpeed = config.AutoRefreshSpeed;
mnuAutoRefreshLow.Click += (s, evt) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.Low;
mnuAutoRefreshNormal.Click += (s, evt) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.Normal;
mnuAutoRefreshHigh.Click += (s, evt) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.High;
mnuAutoRefreshSpeed.DropDownOpening += (s, evt) => UpdateRefreshSpeedMenu();
}
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
_notifListener?.Dispose();
_refreshManager?.Dispose();
EventViewerConfig config = ConfigManager.Config.Debug.EventViewer;
config.WindowSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size;
config.WindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
config.ImageScale = ctrlPpuView.ImageScale;
config.AutoRefresh = _refreshManager.AutoRefresh;
config.AutoRefreshSpeed = _refreshManager.AutoRefreshSpeed;
base.OnFormClosed(e);
}
@ -66,6 +80,16 @@ namespace Mesen.GUI.Debugger
mnuClose.Click += (s, e) => this.Close();
}
public void RefreshData()
{
ctrlPpuView.RefreshData();
}
public void RefreshViewer()
{
ctrlPpuView.RefreshViewer();
}
private void OnNotificationReceived(NotificationEventArgs e)
{
switch(e.NotificationType) {
@ -77,17 +101,6 @@ namespace Mesen.GUI.Debugger
}));
}
break;
case ConsoleNotificationType.EventViewerRefresh:
if((DateTime.Now - _lastUpdate).Milliseconds > 10) {
_lastUpdate = DateTime.Now;
ctrlPpuView.RefreshData();
this.BeginInvoke((Action)(() => {
ctrlPpuView.RefreshViewer();
}));
}
break;
}
}
@ -96,5 +109,18 @@ namespace Mesen.GUI.Debugger
ConfigManager.Config.Debug.EventViewer.RefreshOnBreakPause = mnuRefreshOnBreakPause.Checked;
ConfigManager.ApplyChanges();
}
private void mnuRefresh_Click(object sender, EventArgs e)
{
RefreshData();
RefreshViewer();
}
private void UpdateRefreshSpeedMenu()
{
mnuAutoRefreshLow.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.Low;
mnuAutoRefreshNormal.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.Normal;
mnuAutoRefreshHigh.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.High;
}
}
}

View file

@ -0,0 +1,91 @@
using Mesen.GUI.Config;
using Mesen.GUI.Debugger.Controls;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Debugger
{
public class WindowRefreshManager : IDisposable
{
private IRefresh _window;
private NotificationListener _notifListener;
private Stopwatch _timer;
private long _lastUpdate = 0;
private long _minDelay = 0;
public bool AutoRefresh { get; set; }
public RefreshSpeed AutoRefreshSpeed { get; set; }
public WindowRefreshManager(IRefresh window)
{
_window = window;
_notifListener = new NotificationListener();
_notifListener.OnNotification += OnNotificationReceived;
_timer = Stopwatch.StartNew();
}
public void Dispose()
{
_notifListener.Dispose();
}
private void RefreshContent()
{
_lastUpdate = _timer.ElapsedTicks;
_window.RefreshData();
((Form)_window).BeginInvoke((Action)(() => {
_window.RefreshViewer();
//Limit FPS to 3x time it takes for a single update (rough estimate), and cap based on requested fps.
int divider;
switch(this.AutoRefreshSpeed) {
default:
case RefreshSpeed.Low: divider = 20; break;
case RefreshSpeed.Normal: divider = 40; break;
case RefreshSpeed.High: divider = 80; break;
}
_minDelay = Math.Max(Stopwatch.Frequency / divider, (long)((_timer.ElapsedTicks - _lastUpdate) * 2));
}));
}
private void OnNotificationReceived(NotificationEventArgs e)
{
switch(e.NotificationType) {
case ConsoleNotificationType.CodeBreak:
RefreshContent();
break;
case ConsoleNotificationType.EventViewerRefresh:
if(_window.ScanlineCycleSelect == null && (_timer.ElapsedTicks - _lastUpdate) > _minDelay) {
RefreshContent();
}
break;
case ConsoleNotificationType.ViewerRefresh:
if(_window.ScanlineCycleSelect != null && this.AutoRefresh && e.Parameter.ToInt32() == _window.ScanlineCycleSelect.ViewerId && (_timer.ElapsedTicks - _lastUpdate) > _minDelay) {
RefreshContent();
}
break;
case ConsoleNotificationType.GameLoaded:
//Configuration is lost when debugger is restarted (when switching game or power cycling)
_window.ScanlineCycleSelect?.RefreshSettings();
break;
}
}
}
public interface IRefresh
{
void RefreshData();
void RefreshViewer();
ctrlScanlineCycleSelect ScanlineCycleSelect { get; }
}
}

View file

@ -1,13 +1,15 @@
using Mesen.GUI.Forms;
using Mesen.GUI.Debugger.Controls;
using Mesen.GUI.Forms;
using System;
using System.Windows.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmPaletteViewer : BaseForm
public partial class frmPaletteViewer : BaseForm, IRefresh
{
private NotificationListener _notifListener;
private DateTime _lastUpdate = DateTime.MinValue;
private WindowRefreshManager _refreshManager;
public ctrlScanlineCycleSelect ScanlineCycleSelect { get { return this.ctrlScanlineCycleSelect; } }
public frmPaletteViewer()
{
@ -21,9 +23,8 @@ namespace Mesen.GUI.Debugger
return;
}
_notifListener = new NotificationListener();
_notifListener.OnNotification += OnNotificationReceived;
_refreshManager = new WindowRefreshManager(this);
_refreshManager.AutoRefresh = true;
ctrlScanlineCycleSelect.Initialize(241, 0);
ctrlPaletteViewer.RefreshData();
@ -46,38 +47,19 @@ namespace Mesen.GUI.Debugger
protected override void OnFormClosed(FormClosedEventArgs e)
{
_notifListener?.Dispose();
_refreshManager?.Dispose();
base.OnFormClosed(e);
}
private void RefreshContent()
public void RefreshData()
{
_lastUpdate = DateTime.Now;
ctrlPaletteViewer.RefreshData();
this.BeginInvoke((Action)(() => {
ctrlPaletteViewer.RefreshViewer();
UpdateFields();
}));
}
private void OnNotificationReceived(NotificationEventArgs e)
public void RefreshViewer()
{
switch(e.NotificationType) {
case ConsoleNotificationType.CodeBreak:
RefreshContent();
break;
case ConsoleNotificationType.ViewerRefresh:
if(e.Parameter.ToInt32() == ctrlScanlineCycleSelect.ViewerId && (DateTime.Now - _lastUpdate).Milliseconds > 10) {
RefreshContent();
}
break;
case ConsoleNotificationType.GameLoaded:
//Configuration is lost when debugger is restarted (when switching game or power cycling)
ctrlScanlineCycleSelect.RefreshSettings();
break;
}
ctrlPaletteViewer.RefreshViewer();
UpdateFields();
}
private void ctrlPaletteViewer_SelectionChanged()

View file

@ -33,17 +33,21 @@
this.ctrlSpriteList = new Mesen.GUI.Debugger.PpuViewer.ctrlSpriteList();
this.ctrlMesenMenuStrip1 = new Mesen.GUI.Controls.ctrlMesenMenuStrip();
this.mnuFile = new System.Windows.Forms.ToolStripMenuItem();
this.mnuCopyToClipboard = new System.Windows.Forms.ToolStripMenuItem();
this.mnuSaveAsPng = 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.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshSpeed = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshLow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshNormal = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshHigh = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuZoomIn = new System.Windows.Forms.ToolStripMenuItem();
this.mnuZoomOut = new System.Windows.Forms.ToolStripMenuItem();
this.mnuCopyToClipboard = new System.Windows.Forms.ToolStripMenuItem();
this.mnuSaveAsPng = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
((System.ComponentModel.ISupportInitialize)(this.ctrlSplitContainer)).BeginInit();
this.ctrlSplitContainer.Panel1.SuspendLayout();
this.ctrlSplitContainer.Panel2.SuspendLayout();
@ -129,69 +133,6 @@
this.mnuFile.Size = new System.Drawing.Size(37, 20);
this.mnuFile.Text = "File";
//
// mnuClose
//
this.mnuClose.Image = global::Mesen.GUI.Properties.Resources.Exit;
this.mnuClose.Name = "mnuClose";
this.mnuClose.Size = new System.Drawing.Size(169, 22);
this.mnuClose.Text = "Close";
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
//
// mnuView
//
this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAutoRefresh,
this.toolStripMenuItem2,
this.mnuRefresh,
this.toolStripMenuItem1,
this.mnuZoomIn,
this.mnuZoomOut});
this.mnuView.Name = "mnuView";
this.mnuView.Size = new System.Drawing.Size(44, 20);
this.mnuView.Text = "View";
//
// mnuAutoRefresh
//
this.mnuAutoRefresh.Checked = true;
this.mnuAutoRefresh.CheckOnClick = true;
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
this.mnuAutoRefresh.Size = new System.Drawing.Size(141, 22);
this.mnuAutoRefresh.Text = "Auto-refresh";
this.mnuAutoRefresh.CheckedChanged += new System.EventHandler(this.mnuAutoRefresh_CheckedChanged);
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(138, 6);
//
// mnuRefresh
//
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Refresh;
this.mnuRefresh.Name = "mnuRefresh";
this.mnuRefresh.Size = new System.Drawing.Size(141, 22);
this.mnuRefresh.Text = "Refresh";
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(138, 6);
//
// mnuZoomIn
//
this.mnuZoomIn.Name = "mnuZoomIn";
this.mnuZoomIn.Size = new System.Drawing.Size(141, 22);
this.mnuZoomIn.Text = "Zoom In";
this.mnuZoomIn.Click += new System.EventHandler(this.mnuZoomIn_Click);
//
// mnuZoomOut
//
this.mnuZoomOut.Name = "mnuZoomOut";
this.mnuZoomOut.Size = new System.Drawing.Size(141, 22);
this.mnuZoomOut.Text = "Zoom Out";
this.mnuZoomOut.Click += new System.EventHandler(this.mnuZoomOut_Click);
//
// mnuCopyToClipboard
//
this.mnuCopyToClipboard.Image = global::Mesen.GUI.Properties.Resources.Copy;
@ -211,6 +152,99 @@
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
this.toolStripMenuItem3.Size = new System.Drawing.Size(166, 6);
//
// mnuClose
//
this.mnuClose.Image = global::Mesen.GUI.Properties.Resources.Exit;
this.mnuClose.Name = "mnuClose";
this.mnuClose.Size = new System.Drawing.Size(169, 22);
this.mnuClose.Text = "Close";
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
//
// mnuView
//
this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAutoRefresh,
this.mnuAutoRefreshSpeed,
this.toolStripMenuItem2,
this.mnuRefresh,
this.toolStripMenuItem1,
this.mnuZoomIn,
this.mnuZoomOut});
this.mnuView.Name = "mnuView";
this.mnuView.Size = new System.Drawing.Size(44, 20);
this.mnuView.Text = "View";
//
// mnuAutoRefresh
//
this.mnuAutoRefresh.Checked = true;
this.mnuAutoRefresh.CheckOnClick = true;
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
this.mnuAutoRefresh.Size = new System.Drawing.Size(176, 22);
this.mnuAutoRefresh.Text = "Auto-refresh";
this.mnuAutoRefresh.CheckedChanged += new System.EventHandler(this.mnuAutoRefresh_CheckedChanged);
//
// mnuAutoRefreshSpeed
//
this.mnuAutoRefreshSpeed.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAutoRefreshLow,
this.mnuAutoRefreshNormal,
this.mnuAutoRefreshHigh});
this.mnuAutoRefreshSpeed.Image = global::Mesen.GUI.Properties.Resources.Speed;
this.mnuAutoRefreshSpeed.Name = "mnuAutoRefreshSpeed";
this.mnuAutoRefreshSpeed.Size = new System.Drawing.Size(176, 22);
this.mnuAutoRefreshSpeed.Text = "Auto-refresh Speed";
//
// mnuAutoRefreshLow
//
this.mnuAutoRefreshLow.Name = "mnuAutoRefreshLow";
this.mnuAutoRefreshLow.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshLow.Text = "Low (15 FPS)";
//
// mnuAutoRefreshNormal
//
this.mnuAutoRefreshNormal.Name = "mnuAutoRefreshNormal";
this.mnuAutoRefreshNormal.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshNormal.Text = "Normal (30 FPS)";
//
// mnuAutoRefreshHigh
//
this.mnuAutoRefreshHigh.Name = "mnuAutoRefreshHigh";
this.mnuAutoRefreshHigh.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshHigh.Text = "High (60 FPS)";
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(173, 6);
//
// mnuRefresh
//
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Refresh;
this.mnuRefresh.Name = "mnuRefresh";
this.mnuRefresh.Size = new System.Drawing.Size(176, 22);
this.mnuRefresh.Text = "Refresh";
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(173, 6);
//
// mnuZoomIn
//
this.mnuZoomIn.Name = "mnuZoomIn";
this.mnuZoomIn.Size = new System.Drawing.Size(176, 22);
this.mnuZoomIn.Text = "Zoom In";
this.mnuZoomIn.Click += new System.EventHandler(this.mnuZoomIn_Click);
//
// mnuZoomOut
//
this.mnuZoomOut.Name = "mnuZoomOut";
this.mnuZoomOut.Size = new System.Drawing.Size(176, 22);
this.mnuZoomOut.Text = "Zoom Out";
this.mnuZoomOut.Click += new System.EventHandler(this.mnuZoomOut_Click);
//
// frmSpriteViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -254,5 +288,9 @@
private System.Windows.Forms.ToolStripMenuItem mnuCopyToClipboard;
private System.Windows.Forms.ToolStripMenuItem mnuSaveAsPng;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshSpeed;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshLow;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshNormal;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshHigh;
}
}

View file

@ -1,4 +1,5 @@
using Mesen.GUI.Config;
using Mesen.GUI.Debugger.Controls;
using Mesen.GUI.Debugger.PpuViewer;
using Mesen.GUI.Forms;
using System;
@ -15,18 +16,18 @@ using System.Windows.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmSpriteViewer : BaseForm
public partial class frmSpriteViewer : BaseForm, IRefresh
{
private NotificationListener _notifListener;
private PpuState _state;
private byte[] _vram;
private byte[] _cgram;
private byte[] _oamRam;
private byte[] _previewData;
private Bitmap _previewImage;
private DateTime _lastUpdate = DateTime.MinValue;
private bool _autoRefresh = true;
private GetSpritePreviewOptions _options = new GetSpritePreviewOptions();
private WindowRefreshManager _refreshManager;
public ctrlScanlineCycleSelect ScanlineCycleSelect { get { return this.ctrlScanlineCycleSelect; } }
public frmSpriteViewer()
{
@ -40,9 +41,6 @@ namespace Mesen.GUI.Debugger
return;
}
_notifListener = new NotificationListener();
_notifListener.OnNotification += OnNotificationReceived;
_previewData = new byte[256 * 240 * 4];
_previewImage = new Bitmap(256, 240, PixelFormat.Format32bppPArgb);
ctrlImagePanel.ImageSize = new Size(256, 240);
@ -57,6 +55,14 @@ namespace Mesen.GUI.Debugger
this.Location = config.WindowLocation;
}
_refreshManager = new WindowRefreshManager(this);
_refreshManager.AutoRefresh = config.AutoRefresh;
_refreshManager.AutoRefreshSpeed = config.AutoRefreshSpeed;
mnuAutoRefreshLow.Click += (s, evt) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.Low;
mnuAutoRefreshNormal.Click += (s, evt) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.Normal;
mnuAutoRefreshHigh.Click += (s, evt) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.High;
mnuAutoRefreshSpeed.DropDownOpening += (s, evt) => UpdateRefreshSpeedMenu();
mnuAutoRefresh.Checked = config.AutoRefresh;
ctrlImagePanel.ImageScale = config.ImageScale;
ctrlSplitContainer.SplitterDistance = config.SplitterDistance;
@ -82,12 +88,13 @@ namespace Mesen.GUI.Debugger
protected override void OnFormClosed(FormClosedEventArgs e)
{
_notifListener?.Dispose();
_refreshManager?.Dispose();
SpriteViewerConfig config = ConfigManager.Config.Debug.SpriteViewer;
config.WindowSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size;
config.WindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
config.AutoRefresh = mnuAutoRefresh.Checked;
config.AutoRefreshSpeed = _refreshManager.AutoRefreshSpeed;
config.HideOffscreenSprites = ctrlSpriteList.HideOffscreenSprites;
config.RefreshScanline = ctrlScanlineCycleSelect.Scanline;
config.RefreshCycle = ctrlScanlineCycleSelect.Cycle;
@ -97,36 +104,7 @@ namespace Mesen.GUI.Debugger
base.OnFormClosed(e);
}
private void RefreshContent()
{
_lastUpdate = DateTime.Now;
RefreshData();
this.BeginInvoke((Action)(() => {
this.RefreshViewer();
}));
}
private void OnNotificationReceived(NotificationEventArgs e)
{
switch(e.NotificationType) {
case ConsoleNotificationType.CodeBreak:
RefreshContent();
break;
case ConsoleNotificationType.ViewerRefresh:
if(_autoRefresh && e.Parameter.ToInt32() == ctrlScanlineCycleSelect.ViewerId && (DateTime.Now - _lastUpdate).Milliseconds > 10) {
RefreshContent();
}
break;
case ConsoleNotificationType.GameLoaded:
//Configuration is lost when debugger is restarted (when switching game or power cycling)
ctrlScanlineCycleSelect.RefreshSettings();
break;
}
}
private void RefreshData()
public void RefreshData()
{
_state = DebugApi.GetState().Ppu;
_vram = DebugApi.GetMemoryState(SnesMemoryType.VideoRam);
@ -134,7 +112,7 @@ namespace Mesen.GUI.Debugger
_cgram = DebugApi.GetMemoryState(SnesMemoryType.CGRam);
}
private void RefreshViewer()
public void RefreshViewer()
{
ctrlSpriteList.SetData(_oamRam, _state.OamMode);
@ -152,6 +130,8 @@ namespace Mesen.GUI.Debugger
} else {
ctrlImagePanel.Selection = Rectangle.Empty;
}
ctrlImagePanel.Refresh();
}
private void mnuRefresh_Click(object sender, EventArgs e)
@ -212,7 +192,7 @@ namespace Mesen.GUI.Debugger
private void mnuAutoRefresh_CheckedChanged(object sender, EventArgs e)
{
_autoRefresh = mnuAutoRefresh.Checked;
_refreshManager.AutoRefresh = mnuAutoRefresh.Checked;
}
private void ctrlSpriteList_SpriteSelected(SpriteInfo sprite)
@ -224,5 +204,12 @@ namespace Mesen.GUI.Debugger
SelectSprite(sprite);
RefreshViewer();
}
private void UpdateRefreshSpeedMenu()
{
mnuAutoRefreshLow.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.Low;
mnuAutoRefreshNormal.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.Normal;
mnuAutoRefreshHigh.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.High;
}
}
}

View file

@ -69,6 +69,10 @@
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuZoomIn = new System.Windows.Forms.ToolStripMenuItem();
this.mnuZoomOut = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshSpeed = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshLow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshNormal = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshHigh = new System.Windows.Forms.ToolStripMenuItem();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.ctrlPaletteViewer)).BeginInit();
@ -550,6 +554,7 @@
//
this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAutoRefresh,
this.mnuAutoRefreshSpeed,
this.toolStripMenuItem2,
this.mnuRefresh,
this.toolStripMenuItem1,
@ -565,41 +570,70 @@
this.mnuAutoRefresh.CheckOnClick = true;
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
this.mnuAutoRefresh.Size = new System.Drawing.Size(141, 22);
this.mnuAutoRefresh.Size = new System.Drawing.Size(176, 22);
this.mnuAutoRefresh.Text = "Auto-refresh";
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(138, 6);
this.toolStripMenuItem2.Size = new System.Drawing.Size(173, 6);
//
// mnuRefresh
//
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Refresh;
this.mnuRefresh.Name = "mnuRefresh";
this.mnuRefresh.Size = new System.Drawing.Size(141, 22);
this.mnuRefresh.Size = new System.Drawing.Size(176, 22);
this.mnuRefresh.Text = "Refresh";
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(138, 6);
this.toolStripMenuItem1.Size = new System.Drawing.Size(173, 6);
//
// mnuZoomIn
//
this.mnuZoomIn.Name = "mnuZoomIn";
this.mnuZoomIn.Size = new System.Drawing.Size(141, 22);
this.mnuZoomIn.Size = new System.Drawing.Size(176, 22);
this.mnuZoomIn.Text = "Zoom In";
this.mnuZoomIn.Click += new System.EventHandler(this.mnuZoomIn_Click);
//
// mnuZoomOut
//
this.mnuZoomOut.Name = "mnuZoomOut";
this.mnuZoomOut.Size = new System.Drawing.Size(141, 22);
this.mnuZoomOut.Size = new System.Drawing.Size(176, 22);
this.mnuZoomOut.Text = "Zoom Out";
this.mnuZoomOut.Click += new System.EventHandler(this.mnuZoomOut_Click);
//
// mnuAutoRefreshSpeed
//
this.mnuAutoRefreshSpeed.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAutoRefreshLow,
this.mnuAutoRefreshNormal,
this.mnuAutoRefreshHigh});
this.mnuAutoRefreshSpeed.Image = global::Mesen.GUI.Properties.Resources.Speed;
this.mnuAutoRefreshSpeed.Name = "mnuAutoRefreshSpeed";
this.mnuAutoRefreshSpeed.Size = new System.Drawing.Size(176, 22);
this.mnuAutoRefreshSpeed.Text = "Auto-refresh Speed";
//
// mnuAutoRefreshLow
//
this.mnuAutoRefreshLow.Name = "mnuAutoRefreshLow";
this.mnuAutoRefreshLow.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshLow.Text = "Low (15 FPS)";
//
// mnuAutoRefreshNormal
//
this.mnuAutoRefreshNormal.Name = "mnuAutoRefreshNormal";
this.mnuAutoRefreshNormal.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshNormal.Text = "Normal (30 FPS)";
//
// mnuAutoRefreshHigh
//
this.mnuAutoRefreshHigh.Name = "mnuAutoRefreshHigh";
this.mnuAutoRefreshHigh.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshHigh.Text = "High (60 FPS)";
//
// frmTileViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -669,5 +703,9 @@
private System.Windows.Forms.ToolStripMenuItem mnuCopyToClipboard;
private System.Windows.Forms.ToolStripMenuItem mnuSaveAsPng;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshSpeed;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshLow;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshNormal;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshHigh;
}
}

View file

@ -1,4 +1,5 @@
using Mesen.GUI.Config;
using Mesen.GUI.Debugger.Controls;
using Mesen.GUI.Forms;
using System;
using System.Collections.Generic;
@ -14,11 +15,10 @@ using System.Windows.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmTileViewer : BaseForm
public partial class frmTileViewer : BaseForm, IRefresh
{
private int[,] _layerBpp = new int[8, 4] { { 2,2,2,2 }, { 4,4,2,0 }, { 4,4,0,0 }, { 8,4,0,0 }, { 8,2,0,0 }, { 4,2,0,0 }, { 4,0,0,0 }, { 8,0,0,0 } };
private NotificationListener _notifListener;
private GetTileViewOptions _options;
private byte[] _tileData;
private byte[] _cgram;
@ -26,11 +26,12 @@ namespace Mesen.GUI.Debugger
private Bitmap _tileImage;
private SnesMemoryType _memoryType = SnesMemoryType.VideoRam;
private int _addressOffset = 0;
private DateTime _lastUpdate = DateTime.MinValue;
private bool _autoRefresh = true;
private DebugState _state;
private int _selectedTile = 0;
private WindowRefreshManager _refreshManager;
public ctrlScanlineCycleSelect ScanlineCycleSelect { get { return this.ctrlScanlineCycleSelect; } }
public frmTileViewer()
{
InitializeComponent();
@ -43,9 +44,6 @@ namespace Mesen.GUI.Debugger
return;
}
_notifListener = new NotificationListener();
_notifListener.OnNotification += OnNotificationReceived;
_tileData = new byte[512 * 512 * 4];
_tileImage = new Bitmap(512, 512, PixelFormat.Format32bppPArgb);
ctrlImagePanel.Image = _tileImage;
@ -86,7 +84,14 @@ namespace Mesen.GUI.Debugger
_options.Width = config.ColumnCount;
ctrlImagePanel.GridSizeX = config.ShowTileGrid ? 8 : 0;
ctrlImagePanel.GridSizeY = config.ShowTileGrid ? 8 : 0;
_autoRefresh = config.AutoRefresh;
_refreshManager = new WindowRefreshManager(this);
_refreshManager.AutoRefresh = config.AutoRefresh;
_refreshManager.AutoRefreshSpeed = config.AutoRefreshSpeed;
mnuAutoRefreshLow.Click += (s, e) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.Low;
mnuAutoRefreshNormal.Click += (s, e) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.Normal;
mnuAutoRefreshHigh.Click += (s, e) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.High;
mnuAutoRefreshSpeed.DropDownOpening += (s, e) => UpdateRefreshSpeedMenu();
RefreshData();
RefreshViewer();
@ -131,12 +136,13 @@ namespace Mesen.GUI.Debugger
protected override void OnFormClosed(FormClosedEventArgs e)
{
_notifListener?.Dispose();
_refreshManager?.Dispose();
TileViewerConfig config = ConfigManager.Config.Debug.TileViewer;
config.WindowSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size;
config.WindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
config.AutoRefresh = mnuAutoRefresh.Checked;
config.AutoRefreshSpeed = _refreshManager.AutoRefreshSpeed;
config.ShowTileGrid = chkShowTileGrid.Checked;
config.RefreshScanline = ctrlScanlineCycleSelect.Scanline;
config.RefreshCycle = ctrlScanlineCycleSelect.Cycle;
@ -154,35 +160,6 @@ namespace Mesen.GUI.Debugger
base.OnFormClosed(e);
}
private void RefreshContent()
{
_lastUpdate = DateTime.Now;
RefreshData();
this.BeginInvoke((Action)(() => {
this.RefreshViewer();
}));
}
private void OnNotificationReceived(NotificationEventArgs e)
{
switch(e.NotificationType) {
case ConsoleNotificationType.CodeBreak:
RefreshContent();
break;
case ConsoleNotificationType.ViewerRefresh:
if(_autoRefresh && e.Parameter.ToInt32() == ctrlScanlineCycleSelect.ViewerId && (DateTime.Now - _lastUpdate).Milliseconds > 10) {
RefreshContent();
}
break;
case ConsoleNotificationType.GameLoaded:
//Configuration is lost when debugger is restarted (when switching game or power cycling)
ctrlScanlineCycleSelect.RefreshSettings();
break;
}
}
private int GetBytesPerTile()
{
switch(_options.Format) {
@ -197,7 +174,7 @@ namespace Mesen.GUI.Debugger
}
}
private void RefreshData()
public void RefreshData()
{
_state = DebugApi.GetState();
_cgram = DebugApi.GetMemoryState(SnesMemoryType.CGRam);
@ -210,7 +187,7 @@ namespace Mesen.GUI.Debugger
ctrlPaletteViewer.RefreshData();
}
private void RefreshViewer()
public void RefreshViewer()
{
if(_tileSource == null) {
return;
@ -251,7 +228,7 @@ namespace Mesen.GUI.Debugger
btnPresetBg4.Enabled = _layerBpp[_state.Ppu.BgMode, 3] > 0;
UpdateMapSize();
ctrlImagePanel.Invalidate();
ctrlImagePanel.Refresh();
ctrlPaletteViewer.RefreshViewer();
}
@ -405,7 +382,7 @@ namespace Mesen.GUI.Debugger
private void mnuAutoRefresh_CheckedChanged(object sender, EventArgs e)
{
_autoRefresh = mnuAutoRefresh.Checked;
_refreshManager.AutoRefresh = mnuAutoRefresh.Checked;
}
private void GoToBgLayer(int layer)
@ -462,5 +439,12 @@ namespace Mesen.GUI.Debugger
RefreshViewer();
}
private void UpdateRefreshSpeedMenu()
{
mnuAutoRefreshLow.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.Low;
mnuAutoRefreshNormal.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.Normal;
mnuAutoRefreshHigh.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.High;
}
}
}

View file

@ -81,6 +81,10 @@
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuZoomIn = new System.Windows.Forms.ToolStripMenuItem();
this.mnuZoomOut = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshSpeed = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshLow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshNormal = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshHigh = new System.Windows.Forms.ToolStripMenuItem();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.grpTileInfo.SuspendLayout();
@ -632,6 +636,7 @@
//
this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAutoRefresh,
this.mnuAutoRefreshSpeed,
this.toolStripMenuItem2,
this.mnuRefresh,
this.toolStripMenuItem1,
@ -647,42 +652,71 @@
this.mnuAutoRefresh.CheckOnClick = true;
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
this.mnuAutoRefresh.Size = new System.Drawing.Size(141, 22);
this.mnuAutoRefresh.Size = new System.Drawing.Size(176, 22);
this.mnuAutoRefresh.Text = "Auto-refresh";
this.mnuAutoRefresh.CheckedChanged += new System.EventHandler(this.mnuAutoRefresh_CheckedChanged);
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(138, 6);
this.toolStripMenuItem2.Size = new System.Drawing.Size(173, 6);
//
// mnuRefresh
//
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Refresh;
this.mnuRefresh.Name = "mnuRefresh";
this.mnuRefresh.Size = new System.Drawing.Size(141, 22);
this.mnuRefresh.Size = new System.Drawing.Size(176, 22);
this.mnuRefresh.Text = "Refresh";
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(138, 6);
this.toolStripMenuItem1.Size = new System.Drawing.Size(173, 6);
//
// mnuZoomIn
//
this.mnuZoomIn.Name = "mnuZoomIn";
this.mnuZoomIn.Size = new System.Drawing.Size(141, 22);
this.mnuZoomIn.Size = new System.Drawing.Size(176, 22);
this.mnuZoomIn.Text = "Zoom In";
this.mnuZoomIn.Click += new System.EventHandler(this.mnuZoomIn_Click);
//
// mnuZoomOut
//
this.mnuZoomOut.Name = "mnuZoomOut";
this.mnuZoomOut.Size = new System.Drawing.Size(141, 22);
this.mnuZoomOut.Size = new System.Drawing.Size(176, 22);
this.mnuZoomOut.Text = "Zoom Out";
this.mnuZoomOut.Click += new System.EventHandler(this.mnuZoomOut_Click);
//
// mnuAutoRefreshSpeed
//
this.mnuAutoRefreshSpeed.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAutoRefreshLow,
this.mnuAutoRefreshNormal,
this.mnuAutoRefreshHigh});
this.mnuAutoRefreshSpeed.Image = global::Mesen.GUI.Properties.Resources.Speed;
this.mnuAutoRefreshSpeed.Name = "mnuAutoRefreshSpeed";
this.mnuAutoRefreshSpeed.Size = new System.Drawing.Size(176, 22);
this.mnuAutoRefreshSpeed.Text = "Auto-refresh Speed";
//
// mnuAutoRefreshLow
//
this.mnuAutoRefreshLow.Name = "mnuAutoRefreshLow";
this.mnuAutoRefreshLow.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshLow.Text = "Low (15 FPS)";
//
// mnuAutoRefreshNormal
//
this.mnuAutoRefreshNormal.Name = "mnuAutoRefreshNormal";
this.mnuAutoRefreshNormal.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshNormal.Text = "Normal (30 FPS)";
//
// mnuAutoRefreshHigh
//
this.mnuAutoRefreshHigh.Name = "mnuAutoRefreshHigh";
this.mnuAutoRefreshHigh.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshHigh.Text = "High (60 FPS)";
//
// frmTilemapViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
@ -770,5 +804,9 @@
private System.Windows.Forms.ToolStripMenuItem mnuCopyToClipboard;
private System.Windows.Forms.ToolStripMenuItem mnuSaveAsPng;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshSpeed;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshLow;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshNormal;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshHigh;
}
}

View file

@ -1,4 +1,5 @@
using Mesen.GUI.Config;
using Mesen.GUI.Debugger.Controls;
using Mesen.GUI.Forms;
using System;
using System.Collections.Generic;
@ -14,11 +15,10 @@ using System.Windows.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmTilemapViewer : BaseForm
public partial class frmTilemapViewer : BaseForm, IRefresh
{
private int[,] _layerBpp = new int[8, 4] { { 2,2,2,2 }, { 4,4,2,0 }, { 4,4,0,0 }, { 8,4,0,0 }, { 8,2,0,0 }, { 4,2,0,0 }, { 4,0,0,0 }, { 8,0,0,0 } };
private NotificationListener _notifListener;
private GetTilemapOptions _options;
private PpuState _state;
private byte[] _cgram;
@ -28,7 +28,7 @@ namespace Mesen.GUI.Debugger
private int _selectedRow = 0;
private int _selectedColumn = 0;
private DateTime _lastUpdate = DateTime.MinValue;
private bool _autoRefresh = false;
private WindowRefreshManager _refreshManager;
public frmTilemapViewer()
{
@ -42,9 +42,6 @@ namespace Mesen.GUI.Debugger
return;
}
_notifListener = new NotificationListener();
_notifListener.OnNotification += OnNotificationReceived;
_tilemapData = new byte[1024 * 1024 * 4];
_tilemapImage = new Bitmap(1024, 1024, PixelFormat.Format32bppPArgb);
ctrlImagePanel.Image = _tilemapImage;
@ -64,7 +61,14 @@ namespace Mesen.GUI.Debugger
ctrlImagePanel.ImageScale = config.ImageScale;
ctrlScanlineCycleSelect.Initialize(config.RefreshScanline, config.RefreshCycle);
_autoRefresh = config.AutoRefresh;
_refreshManager = new WindowRefreshManager(this);
_refreshManager.AutoRefresh = config.AutoRefresh;
_refreshManager.AutoRefreshSpeed = config.AutoRefreshSpeed;
mnuAutoRefreshLow.Click += (s, evt) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.Low;
mnuAutoRefreshNormal.Click += (s, evt) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.Normal;
mnuAutoRefreshHigh.Click += (s, evt) => _refreshManager.AutoRefreshSpeed = RefreshSpeed.High;
mnuAutoRefreshSpeed.DropDownOpening += (s, evt) => UpdateRefreshSpeedMenu();
RefreshData();
RefreshViewer();
@ -85,12 +89,13 @@ namespace Mesen.GUI.Debugger
protected override void OnFormClosed(FormClosedEventArgs e)
{
_notifListener?.Dispose();
_refreshManager?.Dispose();
TilemapViewerConfig config = ConfigManager.Config.Debug.TilemapViewer;
config.WindowSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size;
config.WindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
config.AutoRefresh = mnuAutoRefresh.Checked;
config.AutoRefreshSpeed = _refreshManager.AutoRefreshSpeed;
config.ShowTileGrid = chkShowTileGrid.Checked;
config.ShowScrollOverlay = chkShowScrollOverlay.Checked;
config.RefreshScanline = ctrlScanlineCycleSelect.Scanline;
@ -100,36 +105,7 @@ namespace Mesen.GUI.Debugger
base.OnFormClosed(e);
}
private void RefreshContent()
{
_lastUpdate = DateTime.Now;
RefreshData();
this.BeginInvoke((Action)(() => {
this.RefreshViewer();
}));
}
private void OnNotificationReceived(NotificationEventArgs e)
{
switch(e.NotificationType) {
case ConsoleNotificationType.CodeBreak:
RefreshContent();
break;
case ConsoleNotificationType.ViewerRefresh:
if(_autoRefresh && e.Parameter.ToInt32() == ctrlScanlineCycleSelect.ViewerId && (DateTime.Now - _lastUpdate).Milliseconds > 10) {
RefreshContent();
}
break;
case ConsoleNotificationType.GameLoaded:
//Configuration is lost when debugger is restarted (when switching game or power cycling)
ctrlScanlineCycleSelect.RefreshSettings();
break;
}
}
private void RefreshData()
public void RefreshData()
{
_state = DebugApi.GetState().Ppu;
_vram = DebugApi.GetMemoryState(SnesMemoryType.VideoRam);
@ -156,6 +132,11 @@ namespace Mesen.GUI.Debugger
get { return _state.Layers[_options.Layer].LargeTiles; }
}
public ctrlScanlineCycleSelect ScanlineCycleSelect
{
get { return this.ctrlScanlineCycleSelect; }
}
private int GetWidth()
{
if(_state.BgMode == 7) {
@ -194,7 +175,7 @@ namespace Mesen.GUI.Debugger
return height;
}
private void RefreshViewer()
public void RefreshViewer()
{
if(_layerBpp[_state.BgMode, _options.Layer] == 0) {
_options.Layer = 0;
@ -240,6 +221,7 @@ namespace Mesen.GUI.Debugger
} else {
ctrlImagePanel.Overlay = Rectangle.Empty;
}
ctrlImagePanel.Refresh();
UpdateFields();
}
@ -368,7 +350,14 @@ namespace Mesen.GUI.Debugger
private void mnuAutoRefresh_CheckedChanged(object sender, EventArgs e)
{
_autoRefresh = mnuAutoRefresh.Checked;
_refreshManager.AutoRefresh = mnuAutoRefresh.Checked;
}
private void UpdateRefreshSpeedMenu()
{
mnuAutoRefreshLow.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.Low;
mnuAutoRefreshNormal.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.Normal;
mnuAutoRefreshHigh.Checked = _refreshManager.AutoRefreshSpeed == RefreshSpeed.High;
}
}
}

View file

@ -339,6 +339,7 @@
<DependentUpon>frmSpriteViewer.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\PpuViewer\SpriteInfo.cs" />
<Compile Include="Debugger\PpuViewer\WindowRefreshManager.cs" />
<Compile Include="Debugger\Scripts\FastColoredTextBox\AutocompleteItem.cs" />
<Compile Include="Debugger\Scripts\FastColoredTextBox\AutocompleteMenu.cs">
<SubType>UserControl</SubType>