1 using Mesen.GUI.Config;
2 using Mesen.GUI.Forms;
3 using System;
4 using System.Collections.Generic;
5 using System.ComponentModel;
6 using System.Data;
7 using System.Drawing;
8 using System.Linq;
9 using System.Text;
10 using System.Threading.Tasks;
11 using System.Windows.Forms;
12 
13 namespace Mesen.GUI.Debugger
14 {
15 	public partial class frmEventViewer : BaseForm
16 	{
17 		private DateTime _lastUpdate = DateTime.MinValue;
18 		private InteropEmu.NotificationListener _notifListener;
19 		private bool _inListViewTab = false;
20 		private bool _refreshing = false;
21 		private bool _isZoomed = false;
22 		private bool _isCompact = false;
23 		private Size _originalSize;
24 		private Size _previousPictureSize;
25 
frmEventViewer()26 		public frmEventViewer()
27 		{
28 			InitializeComponent();
29 		}
30 
OnLoad(EventArgs e)31 		protected override void OnLoad(EventArgs e)
32 		{
33 			base.OnLoad(e);
34 
35 			if(!this.DesignMode) {
36 				this.mnuRefreshOnBreak.Checked = ConfigManager.Config.DebugInfo.EventViewerRefreshOnBreak;
37 				this.chkShowPpuRegisterWrites.Checked = ConfigManager.Config.DebugInfo.EventViewerShowPpuRegisterWrites;
38 				this.chkShowPpuRegisterReads.Checked = ConfigManager.Config.DebugInfo.EventViewerShowPpuRegisterReads;
39 				this.chkShowIrq.Checked = ConfigManager.Config.DebugInfo.EventViewerShowIrq;
40 				this.chkShowNmi.Checked = ConfigManager.Config.DebugInfo.EventViewerShowNmi;
41 				this.chkShowSpriteZero.Checked = ConfigManager.Config.DebugInfo.EventViewerShowSpriteZeroHit;
42 				this.chkShowMapperRegisterWrites.Checked = ConfigManager.Config.DebugInfo.EventViewerShowMapperRegisterWrites;
43 				this.chkShowMapperRegisterReads.Checked = ConfigManager.Config.DebugInfo.EventViewerShowMapperRegisterReads;
44 				this.chkBreakpoints.Checked = ConfigManager.Config.DebugInfo.EventViewerShowMarkedBreakpoints;
45 				this.chkShowPreviousFrameEvents.Checked = ConfigManager.Config.DebugInfo.EventViewerShowPreviousFrameEvents;
46 
47 				string toggleViewTooltip = "Toggle Compact/Normal View";
48 				if(ConfigManager.Config.DebugInfo.Shortcuts.PpuViewer_ToggleView != Keys.None) {
49 					toggleViewTooltip += " (" + DebuggerShortcutsConfig.GetShortcutDisplay(ConfigManager.Config.DebugInfo.Shortcuts.PpuViewer_ToggleView) + ")";
50 				}
51 				this.toolTip.SetToolTip(this.btnToggleView, toggleViewTooltip);
52 
53 				string toggleZoomTooltip = "Toggle 2x Zoom";
54 				if(ConfigManager.Config.DebugInfo.Shortcuts.PpuViewer_ToggleZoom != Keys.None) {
55 					toggleZoomTooltip += " (" + DebuggerShortcutsConfig.GetShortcutDisplay(ConfigManager.Config.DebugInfo.Shortcuts.PpuViewer_ToggleZoom) + ")";
56 				}
57 				this.toolTip.SetToolTip(this.chkToggleZoom, toggleZoomTooltip);
58 
59 				_previousPictureSize = ctrlEventViewerPpuView.Size;
60 
61 				this.GetData();
62 				this.RefreshViewer();
63 
64 				DebugWorkspaceManager.GetWorkspace();
65 
66 				if(!ConfigManager.Config.DebugInfo.EventViewerLocation.IsEmpty) {
67 					this.StartPosition = FormStartPosition.Manual;
68 					this.Location = ConfigManager.Config.DebugInfo.EventViewerLocation;
69 				}
70 
71 				this._notifListener = new InteropEmu.NotificationListener(ConfigManager.Config.DebugInfo.DebugConsoleId);
72 				this._notifListener.OnNotification += this._notifListener_OnNotification;
73 			}
74 		}
75 
OnFormClosing(FormClosingEventArgs e)76 		protected override void OnFormClosing(FormClosingEventArgs e)
77 		{
78 			base.OnFormClosing(e);
79 			this._notifListener.OnNotification -= this._notifListener_OnNotification;
80 			ConfigManager.Config.DebugInfo.EventViewerLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
81 		}
82 
ProcessCmdKey(ref Message msg, Keys keyData)83 		protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
84 		{
85 			if(keyData == ConfigManager.Config.DebugInfo.Shortcuts.PpuViewer_ToggleZoom) {
86 				ToggleZoom();
87 				return true;
88 			} else if(keyData == ConfigManager.Config.DebugInfo.Shortcuts.PpuViewer_ToggleView) {
89 				ToggleView();
90 				return true;
91 			}
92 			return base.ProcessCmdKey(ref msg, keyData);
93 		}
94 
_notifListener_OnNotification(InteropEmu.NotificationEventArgs e)95 		private void _notifListener_OnNotification(InteropEmu.NotificationEventArgs e)
96 		{
97 			switch(e.NotificationType) {
98 				case InteropEmu.ConsoleNotificationType.CodeBreak:
99 				case InteropEmu.ConsoleNotificationType.GamePaused:
100 					if(ConfigManager.Config.DebugInfo.EventViewerRefreshOnBreak) {
101 						this.GetData();
102 						this.BeginInvoke((MethodInvoker)(() => this.RefreshViewer()));
103 					}
104 					break;
105 
106 				case InteropEmu.ConsoleNotificationType.EventViewerDisplayFrame:
107 					if(!_refreshing && (DateTime.Now - _lastUpdate).Milliseconds >= 32) {
108 						//Update at ~30 fps at most
109 						this.GetData();
110 						this.BeginInvoke((MethodInvoker)(() => this.RefreshViewer()));
111 						_lastUpdate = DateTime.Now;
112 					}
113 					break;
114 			}
115 		}
116 
GetData()117 		private void GetData()
118 		{
119 			if(_inListViewTab) {
120 				ctrlEventViewerListView.GetData();
121 			} else {
122 				ctrlEventViewerPpuView.GetData();
123 			}
124 		}
125 
RefreshViewer()126 		private void RefreshViewer()
127 		{
128 			_refreshing = true;
129 			ctrlEventViewerPpuView.RefreshViewer();
130 			_refreshing = false;
131 		}
132 
mnuClose_Click(object sender, EventArgs e)133 		private void mnuClose_Click(object sender, EventArgs e)
134 		{
135 			this.Close();
136 		}
137 
tabMain_SelectedIndexChanged(object sender, EventArgs e)138 		private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
139 		{
140 			_inListViewTab = tabMain.SelectedTab == tpgListView;
141 			GetData();
142 		}
143 
mnuRefreshOnBreak_Click(object sender, EventArgs e)144 		private void mnuRefreshOnBreak_Click(object sender, EventArgs e)
145 		{
146 			ConfigManager.Config.DebugInfo.EventViewerRefreshOnBreak = this.mnuRefreshOnBreak.Checked;
147 			ConfigManager.ApplyChanges();
148 		}
149 
chkShowPpuRegisterWrites_Click(object sender, EventArgs e)150 		private void chkShowPpuRegisterWrites_Click(object sender, EventArgs e)
151 		{
152 			ConfigManager.Config.DebugInfo.EventViewerShowPpuRegisterWrites = this.chkShowPpuRegisterWrites.Checked;
153 			ConfigManager.ApplyChanges();
154 			this.RefreshViewer();
155 		}
156 
chkShowPpuRegisterReads_Click(object sender, EventArgs e)157 		private void chkShowPpuRegisterReads_Click(object sender, EventArgs e)
158 		{
159 			ConfigManager.Config.DebugInfo.EventViewerShowPpuRegisterReads = this.chkShowPpuRegisterReads.Checked;
160 			ConfigManager.ApplyChanges();
161 			this.RefreshViewer();
162 		}
163 
chkShowIrq_Click(object sender, EventArgs e)164 		private void chkShowIrq_Click(object sender, EventArgs e)
165 		{
166 			ConfigManager.Config.DebugInfo.EventViewerShowIrq = this.chkShowIrq.Checked;
167 			ConfigManager.ApplyChanges();
168 			this.RefreshViewer();
169 		}
170 
chkShowNmi_Click(object sender, EventArgs e)171 		private void chkShowNmi_Click(object sender, EventArgs e)
172 		{
173 			ConfigManager.Config.DebugInfo.EventViewerShowNmi = this.chkShowNmi.Checked;
174 			ConfigManager.ApplyChanges();
175 			this.RefreshViewer();
176 		}
177 
chkShowSpriteZero_Click(object sender, EventArgs e)178 		private void chkShowSpriteZero_Click(object sender, EventArgs e)
179 		{
180 			ConfigManager.Config.DebugInfo.EventViewerShowSpriteZeroHit = chkShowSpriteZero.Checked;
181 			ConfigManager.ApplyChanges();
182 			this.RefreshViewer();
183 		}
184 
chkShowMapperRegisterWrites_Click(object sender, EventArgs e)185 		private void chkShowMapperRegisterWrites_Click(object sender, EventArgs e)
186 		{
187 			ConfigManager.Config.DebugInfo.EventViewerShowMapperRegisterWrites = chkShowMapperRegisterWrites.Checked;
188 			ConfigManager.ApplyChanges();
189 			this.RefreshViewer();
190 		}
191 
chkShowMapperRegisterReads_Click(object sender, EventArgs e)192 		private void chkShowMapperRegisterReads_Click(object sender, EventArgs e)
193 		{
194 			ConfigManager.Config.DebugInfo.EventViewerShowMapperRegisterReads = chkShowMapperRegisterReads.Checked;
195 			ConfigManager.ApplyChanges();
196 			this.RefreshViewer();
197 		}
198 
chkBreakpoints_Click(object sender, EventArgs e)199 		private void chkBreakpoints_Click(object sender, EventArgs e)
200 		{
201 			ConfigManager.Config.DebugInfo.EventViewerShowMarkedBreakpoints = chkBreakpoints.Checked;
202 			ConfigManager.ApplyChanges();
203 			this.RefreshViewer();
204 		}
205 
chkShowPreviousFrameEvents_Click(object sender, EventArgs e)206 		private void chkShowPreviousFrameEvents_Click(object sender, EventArgs e)
207 		{
208 			ConfigManager.Config.DebugInfo.EventViewerShowPreviousFrameEvents = chkShowPreviousFrameEvents.Checked;
209 			ConfigManager.ApplyChanges();
210 			if(InteropEmu.DebugIsExecutionStopped()) {
211 				this.GetData();
212 				this.RefreshViewer();
213 			}
214 		}
215 
mnuConfigureColors_Click(object sender, EventArgs e)216 		private void mnuConfigureColors_Click(object sender, EventArgs e)
217 		{
218 			if(frmEventViewerColors.Instance != null) {
219 				frmEventViewerColors.Instance.BringToFront();
220 			} else {
221 				frmEventViewerColors frm = new frmEventViewerColors();
222 				frm.Show(this, this);
223 				frm.FormClosed += (s, evt) => {
224 					this.GetData();
225 					this.RefreshViewer();
226 				};
227 			}
228 		}
229 
ctrlEventViewerPpuView_OnPictureResized(object sender, EventArgs e)230 		private void ctrlEventViewerPpuView_OnPictureResized(object sender, EventArgs e)
231 		{
232 			Size picSize = ctrlEventViewerPpuView.GetCompactSize(false);
233 			this.Size += (picSize - _previousPictureSize);
234 			_originalSize += (picSize - _previousPictureSize);
235 			ctrlEventViewerPpuView.Size += (picSize - _previousPictureSize);
236 			_previousPictureSize = picSize;
237 		}
238 
ToggleView()239 		private void ToggleView()
240 		{
241 			if(!_isCompact) {
242 				_isCompact = true;
243 				_originalSize = this.Size;
244 
245 				this.ClientSize = ctrlEventViewerPpuView.GetCompactSize(false) + new Size(3, menuStrip1.Height + 3);
246 
247 				this.Controls.Add(ctrlEventViewerPpuView);
248 				ctrlEventViewerPpuView.BringToFront();
249 				ctrlEventViewerPpuView.Dock = DockStyle.Fill;
250 
251 				tabMain.Visible = false;
252 			} else {
253 				_isCompact = false;
254 				this.Size = _originalSize;
255 				ctrlEventViewerPpuView.Dock = DockStyle.None;
256 				ctrlEventViewerPpuView.Size = ctrlEventViewerPpuView.GetCompactSize(false);
257 				tabMain.Visible = true;
258 				tpgPpuView.Controls.Add(ctrlEventViewerPpuView);
259 			}
260 
261 			btnToggleView.Image = _isCompact ? Properties.Resources.Expand : Properties.Resources.Collapse;
262 			RefreshViewer();
263 		}
264 
ToggleZoom()265 		private void ToggleZoom()
266 		{
267 			ICompactControl ctrl = ctrlEventViewerPpuView;
268 
269 			if(!_isZoomed) {
270 				Size pictureSize = ctrl.GetCompactSize(false);
271 				ctrl.ScaleImage(2);
272 				_isZoomed = true;
273 			} else {
274 				Size pictureSize = ctrl.GetCompactSize(false);
275 				Size halfSize = new Size(pictureSize.Width / 2, pictureSize.Height / 2);
276 				ctrl.ScaleImage(0.5);
277 				_isZoomed = false;
278 			}
279 			chkToggleZoom.Checked = _isZoomed;
280 			RefreshViewer();
281 		}
282 
btnToggleView_Click(object sender, EventArgs e)283 		private void btnToggleView_Click(object sender, EventArgs e)
284 		{
285 			ToggleView();
286 		}
287 
chkToggleZoom_Click(object sender, EventArgs e)288 		private void chkToggleZoom_Click(object sender, EventArgs e)
289 		{
290 			ToggleZoom();
291 		}
292 	}
293 }
294