1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Data; 5 using System.Drawing; 6 using System.IO; 7 using System.Linq; 8 using System.Text; 9 using System.Threading.Tasks; 10 using System.Windows.Forms; 11 using Mesen.GUI.Config; 12 using Mesen.GUI.Forms; 13 using Mesen.GUI.Controls; 14 using Be.Windows.Forms; 15 using Mesen.GUI.Debugger.Controls; 16 17 namespace Mesen.GUI.Debugger 18 { 19 public partial class frmMemoryViewer : BaseForm 20 { 21 private InteropEmu.NotificationListener _notifListener; 22 private DebugMemoryType _memoryType = DebugMemoryType.CpuMemory; 23 private DebugWorkspace _previousWorkspace; 24 private bool _updating = false; 25 private DateTime _lastUpdate = DateTime.MinValue; 26 private TabPage _selectedTab; 27 private bool _formClosed; 28 frmMemoryViewer()29 public frmMemoryViewer() 30 { 31 InitializeComponent(); 32 } 33 OnLoad(EventArgs e)34 protected override void OnLoad(EventArgs e) 35 { 36 base.OnLoad(e); 37 38 DebugWorkspaceManager.AutoLoadDbgFiles(true); 39 40 this._selectedTab = this.tabMain.SelectedTab; 41 42 DebugInfo config = ConfigManager.Config.DebugInfo; 43 44 this.mnuAutoRefresh.Checked = config.RamAutoRefresh; 45 this.mnuHighDensityMode.Checked = config.RamHighDensityTextMode; 46 this.mnuByteEditingMode.Checked = config.RamByteEditingMode; 47 this.mnuEnablePerByteNavigation.Checked = config.RamEnablePerByteNavigation; 48 UpdateRefreshSpeedMenu(); 49 50 this.mnuIgnoreRedundantWrites.Checked = config.RamIgnoreRedundantWrites; 51 this.UpdateFlags(); 52 53 this.mnuHighlightCurrentRowColumn.Checked = config.RamHighlightCurrentRowColumn; 54 this.ctrlHexViewer.HighlightCurrentRowColumn = config.RamHighlightCurrentRowColumn; 55 56 this.mnuShowCharacters.Checked = config.RamShowCharacters; 57 this.mnuShowLabelInfoOnMouseOver.Checked = config.RamShowLabelInfo; 58 59 this.ctrlHexViewer.TextZoom = config.RamTextZoom; 60 this.ctrlHexViewer.BaseFont = new Font(config.RamFontFamily, config.RamFontSize, config.RamFontStyle); 61 62 this.ctrlMemoryAccessCounters.BaseFont = new Font(config.RamFontFamily, config.RamFontSize, config.RamFontStyle); 63 this.ctrlMemoryAccessCounters.TextZoom = config.RamTextZoom; 64 65 this.mnuHighlightExecution.Checked = config.RamHighlightExecution; 66 this.mnuHightlightReads.Checked = config.RamHighlightReads; 67 this.mnuHighlightWrites.Checked = config.RamHighlightWrites; 68 this.mnuHideUnusedBytes.Checked = config.RamHideUnusedBytes; 69 this.mnuHideReadBytes.Checked = config.RamHideReadBytes; 70 this.mnuHideWrittenBytes.Checked = config.RamHideWrittenBytes; 71 this.mnuHideExecutedBytes.Checked = config.RamHideExecutedBytes; 72 73 this.mnuHighlightLabelledBytes.Checked = config.RamHighlightLabelledBytes; 74 this.mnuHighlightBreakpoints.Checked = config.RamHighlightBreakpoints; 75 this.mnuHighlightChrDrawnBytes.Checked = config.RamHighlightChrDrawnBytes; 76 this.mnuHighlightChrReadBytes.Checked = config.RamHighlightChrReadBytes; 77 this.mnuHighlightCodeBytes.Checked = config.RamHighlightCodeBytes; 78 this.mnuHighlightDataBytes.Checked = config.RamHighlightDataBytes; 79 this.mnuHighlightDmcDataBytes.Checked = config.RamHighlightDmcDataBytes; 80 81 this.UpdateFadeOptions(); 82 83 this.InitTblMappings(); 84 85 this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked; 86 this.ctrlHexViewer.MemoryViewer = this; 87 88 UpdateImportButton(); 89 InitMemoryTypeDropdown(true); 90 91 _notifListener = new InteropEmu.NotificationListener(ConfigManager.Config.DebugInfo.DebugConsoleId); 92 _notifListener.OnNotification += _notifListener_OnNotification; 93 94 this.mnuShowCharacters.CheckedChanged += this.mnuShowCharacters_CheckedChanged; 95 this.mnuIgnoreRedundantWrites.CheckedChanged += mnuIgnoreRedundantWrites_CheckedChanged; 96 97 if(!ConfigManager.Config.DebugInfo.MemoryViewerSize.IsEmpty) { 98 this.StartPosition = FormStartPosition.Manual; 99 this.Size = ConfigManager.Config.DebugInfo.MemoryViewerSize; 100 this.Location = ConfigManager.Config.DebugInfo.MemoryViewerLocation; 101 } 102 103 this.InitShortcuts(); 104 } 105 OnFormClosing(FormClosingEventArgs e)106 protected override void OnFormClosing(FormClosingEventArgs e) 107 { 108 base.OnFormClosing(e); 109 UpdateConfig(); 110 ConfigManager.Config.DebugInfo.RamFontFamily = ctrlHexViewer.BaseFont.FontFamily.Name; 111 ConfigManager.Config.DebugInfo.RamFontStyle = ctrlHexViewer.BaseFont.Style; 112 ConfigManager.Config.DebugInfo.RamFontSize = ctrlHexViewer.BaseFont.Size; 113 ConfigManager.Config.DebugInfo.MemoryViewerSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size; 114 ConfigManager.Config.DebugInfo.MemoryViewerLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location; 115 ConfigManager.Config.DebugInfo.RamMemoryType = cboMemoryType.GetEnumValue<DebugMemoryType>(); 116 ConfigManager.ApplyChanges(); 117 DebugWorkspaceManager.SaveWorkspace(); 118 119 if(this._notifListener != null) { 120 this._notifListener.Dispose(); 121 this._notifListener = null; 122 } 123 124 _formClosed = true; 125 } 126 InitShortcuts()127 private void InitShortcuts() 128 { 129 mnuIncreaseFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.IncreaseFontSize)); 130 mnuDecreaseFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.DecreaseFontSize)); 131 mnuResetFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.ResetFontSize)); 132 133 mnuImport.InitShortcut(this, nameof(DebuggerShortcutsConfig.MemoryViewer_Import)); 134 mnuExport.InitShortcut(this, nameof(DebuggerShortcutsConfig.MemoryViewer_Export)); 135 136 mnuRefresh.InitShortcut(this, nameof(DebuggerShortcutsConfig.Refresh)); 137 138 mnuGoToAll.InitShortcut(this, nameof(DebuggerShortcutsConfig.GoToAll)); 139 mnuGoTo.InitShortcut(this, nameof(DebuggerShortcutsConfig.GoTo)); 140 mnuFind.InitShortcut(this, nameof(DebuggerShortcutsConfig.Find)); 141 mnuFindNext.InitShortcut(this, nameof(DebuggerShortcutsConfig.FindNext)); 142 mnuFindPrev.InitShortcut(this, nameof(DebuggerShortcutsConfig.FindPrev)); 143 } 144 InitMemoryTypeDropdown(bool forStartup)145 private void InitMemoryTypeDropdown(bool forStartup) 146 { 147 cboMemoryType.SelectedIndexChanged -= this.cboMemoryType_SelectedIndexChanged; 148 149 DebugMemoryType originalValue = forStartup ? ConfigManager.Config.DebugInfo.RamMemoryType : cboMemoryType.GetEnumValue<DebugMemoryType>(); 150 151 cboMemoryType.BeginUpdate(); 152 cboMemoryType.Items.Clear(); 153 154 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.CpuMemory)); 155 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.PpuMemory)); 156 cboMemoryType.Items.Add("-"); 157 158 if(InteropEmu.DebugGetMemorySize(DebugMemoryType.PrgRom) > 0) { 159 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.PrgRom)); 160 } 161 if(InteropEmu.DebugGetMemorySize(DebugMemoryType.WorkRam) > 0) { 162 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.WorkRam)); 163 } 164 if(InteropEmu.DebugGetMemorySize(DebugMemoryType.SaveRam) > 0) { 165 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.SaveRam)); 166 } 167 168 if(cboMemoryType.Items.Count > 3) { 169 cboMemoryType.Items.Add("-"); 170 } 171 172 if(InteropEmu.DebugGetMemorySize(DebugMemoryType.ChrRom) > 0) { 173 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.ChrRom)); 174 } 175 176 if(InteropEmu.DebugGetMemorySize(DebugMemoryType.ChrRam) > 0) { 177 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.ChrRam)); 178 } 179 180 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.NametableRam)); 181 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.PaletteMemory)); 182 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.SpriteMemory)); 183 cboMemoryType.Items.Add(ResourceHelper.GetEnumText(DebugMemoryType.SecondarySpriteMemory)); 184 185 cboMemoryType.SelectedIndex = 0; 186 cboMemoryType.SetEnumValue(originalValue); 187 cboMemoryType.SelectedIndexChanged += this.cboMemoryType_SelectedIndexChanged; 188 189 cboMemoryType.EndUpdate(); 190 UpdateMemoryType(); 191 } 192 UpdateFlags()193 private void UpdateFlags() 194 { 195 if(mnuIgnoreRedundantWrites.Checked) { 196 DebugWorkspaceManager.SetFlags(DebuggerFlags.IgnoreRedundantWrites); 197 } else { 198 DebugWorkspaceManager.ClearFlags(DebuggerFlags.IgnoreRedundantWrites); 199 } 200 } 201 ShowAddress(int address, DebugMemoryType memoryType)202 public void ShowAddress(int address, DebugMemoryType memoryType) 203 { 204 if(memoryType == DebugMemoryType.InternalRam) { 205 //There is no specific "tab" for the internal ram, show it in the cpu memory tab 206 memoryType = DebugMemoryType.CpuMemory; 207 } 208 209 tabMain.SelectedTab = tpgMemoryViewer; 210 cboMemoryType.SetEnumValue(memoryType); 211 ctrlHexViewer.GoToAddress(address); 212 } 213 GoToDestination(GoToDestination dest)214 public void GoToDestination(GoToDestination dest) 215 { 216 if(_memoryType == DebugMemoryType.CpuMemory && dest.CpuAddress >= 0) { 217 this.ShowAddress(dest.CpuAddress, DebugMemoryType.CpuMemory); 218 } else if(dest.AddressInfo != null) { 219 this.ShowAddress(dest.AddressInfo.Address, dest.AddressInfo.Type.ToMemoryType()); 220 } else if(dest.Label != null) { 221 int relAddress = dest.Label.GetRelativeAddress(); 222 if(_memoryType == DebugMemoryType.CpuMemory && relAddress >= 0) { 223 this.ShowAddress(relAddress, DebugMemoryType.CpuMemory); 224 } else { 225 this.ShowAddress((int)dest.Label.Address, dest.Label.AddressType.ToMemoryType()); 226 } 227 } else if(dest.CpuAddress >= 0) { 228 this.ShowAddress(dest.CpuAddress, DebugMemoryType.CpuMemory); 229 } 230 231 this.BringToFront(); 232 } 233 GoToAll()234 public void GoToAll() 235 { 236 using(frmGoToAll frm = new frmGoToAll(true, false)) { 237 if(frm.ShowDialog() == DialogResult.OK) { 238 GoToDestination(frm.Destination); 239 } 240 } 241 } 242 InitTblMappings()243 private void InitTblMappings() 244 { 245 DebugWorkspace workspace = DebugWorkspaceManager.GetWorkspace(); 246 if(workspace.TblMappings != null && workspace.TblMappings.Count > 0) { 247 var tblDict = TblLoader.ToDictionary(workspace.TblMappings.ToArray()); 248 if(tblDict != null) { 249 this.ctrlHexViewer.ByteCharConverter = new TblByteCharConverter(tblDict); 250 } 251 } else { 252 this.ctrlHexViewer.ByteCharConverter = null; 253 } 254 } 255 _notifListener_OnNotification(InteropEmu.NotificationEventArgs e)256 private void _notifListener_OnNotification(InteropEmu.NotificationEventArgs e) 257 { 258 switch(e.NotificationType) { 259 case InteropEmu.ConsoleNotificationType.CodeBreak: 260 this.BeginInvoke((MethodInvoker)(() => this.RefreshData())); 261 break; 262 263 case InteropEmu.ConsoleNotificationType.GameReset: 264 case InteropEmu.ConsoleNotificationType.GameLoaded: 265 this.BeginInvoke((Action)(() => { 266 if(_formClosed) { 267 return; 268 } 269 this.InitMemoryTypeDropdown(false); 270 ctrlMemoryAccessCounters.InitMemoryTypeDropdown(); 271 })); 272 this.UpdateFlags(); 273 break; 274 275 case InteropEmu.ConsoleNotificationType.PpuFrameDone: 276 int refreshDelay = 90; 277 switch(ConfigManager.Config.DebugInfo.RamAutoRefreshSpeed) { 278 case RefreshSpeed.Low: refreshDelay= 90; break; 279 case RefreshSpeed.Normal: refreshDelay = 32; break; 280 case RefreshSpeed.High: refreshDelay = 16; break; 281 } 282 283 DateTime now = DateTime.Now; 284 if(!_updating && ConfigManager.Config.DebugInfo.RamAutoRefresh && (now - _lastUpdate).Milliseconds >= refreshDelay) { 285 _lastUpdate = now; 286 _updating = true; 287 this.BeginInvoke((Action)(() => { 288 this.RefreshData(); 289 _updating = false; 290 })); 291 } 292 break; 293 } 294 } 295 cboMemoryType_SelectedIndexChanged(object sender, EventArgs e)296 private void cboMemoryType_SelectedIndexChanged(object sender, EventArgs e) 297 { 298 UpdateMemoryType(); 299 } 300 UpdateMemoryType()301 private void UpdateMemoryType() 302 { 303 this._memoryType = this.cboMemoryType.GetEnumValue<DebugMemoryType>(); 304 this.UpdateImportButton(); 305 this.RefreshData(); 306 } 307 UpdateByteColorProvider()308 private void UpdateByteColorProvider() 309 { 310 switch(this._memoryType) { 311 case DebugMemoryType.CpuMemory: 312 case DebugMemoryType.PrgRom: 313 case DebugMemoryType.WorkRam: 314 case DebugMemoryType.SaveRam: 315 case DebugMemoryType.InternalRam: 316 this.ctrlHexViewer.ByteColorProvider = new ByteColorProvider( 317 this._memoryType, 318 mnuHighlightExecution.Checked, 319 mnuHighlightWrites.Checked, 320 mnuHightlightReads.Checked, 321 ConfigManager.Config.DebugInfo.RamFadeSpeed, 322 mnuHideUnusedBytes.Checked, 323 mnuHideReadBytes.Checked, 324 mnuHideWrittenBytes.Checked, 325 mnuHideExecutedBytes.Checked, 326 mnuHighlightDmcDataBytes.Checked, 327 mnuHighlightDataBytes.Checked, 328 mnuHighlightCodeBytes.Checked, 329 mnuHighlightLabelledBytes.Checked, 330 mnuHighlightBreakpoints.Checked 331 ); 332 break; 333 334 case DebugMemoryType.PpuMemory: 335 case DebugMemoryType.ChrRom: 336 case DebugMemoryType.ChrRam: 337 case DebugMemoryType.PaletteMemory: 338 case DebugMemoryType.NametableRam: 339 this.ctrlHexViewer.ByteColorProvider = new ChrByteColorProvider( 340 this._memoryType, 341 mnuHighlightWrites.Checked, 342 mnuHightlightReads.Checked, 343 ConfigManager.Config.DebugInfo.RamFadeSpeed, 344 mnuHideUnusedBytes.Checked, 345 mnuHideReadBytes.Checked, 346 mnuHideWrittenBytes.Checked, 347 mnuHighlightChrDrawnBytes.Checked, 348 mnuHighlightChrReadBytes.Checked, 349 mnuHighlightBreakpoints.Checked 350 ); 351 break; 352 353 default: 354 this.ctrlHexViewer.ByteColorProvider = null; 355 break; 356 } 357 } 358 mnuRefresh_Click(object sender, EventArgs e)359 private void mnuRefresh_Click(object sender, EventArgs e) 360 { 361 this.RefreshData(); 362 } 363 RefreshData()364 private void RefreshData() 365 { 366 if(_formClosed) { 367 return; 368 } 369 370 if(DebugWorkspaceManager.GetWorkspace() != this._previousWorkspace) { 371 this.InitTblMappings(); 372 _previousWorkspace = DebugWorkspaceManager.GetWorkspace(); 373 } 374 375 if(this.tabMain.SelectedTab == this.tpgAccessCounters) { 376 this.ctrlMemoryAccessCounters.RefreshData(); 377 } else if(this.tabMain.SelectedTab == this.tpgMemoryViewer) { 378 this.UpdateByteColorProvider(); 379 this.ctrlHexViewer.RefreshData(_memoryType); 380 } 381 } 382 mnuFind_Click(object sender, EventArgs e)383 private void mnuFind_Click(object sender, EventArgs e) 384 { 385 this.ctrlHexViewer.OpenSearchBox(); 386 } 387 mnuFindNext_Click(object sender, EventArgs e)388 private void mnuFindNext_Click(object sender, EventArgs e) 389 { 390 this.ctrlHexViewer.FindNext(); 391 } 392 mnuFindPrev_Click(object sender, EventArgs e)393 private void mnuFindPrev_Click(object sender, EventArgs e) 394 { 395 this.ctrlHexViewer.FindPrevious(); 396 } 397 mnuGoTo_Click(object sender, EventArgs e)398 private void mnuGoTo_Click(object sender, EventArgs e) 399 { 400 if(_selectedTab == tpgMemoryViewer) { 401 this.ctrlHexViewer.GoToAddress(); 402 } else if(_selectedTab == tpgAccessCounters) { 403 this.ctrlMemoryAccessCounters.GoToAddress(); 404 } 405 } 406 mnuGoToAll_Click(object sender, EventArgs e)407 private void mnuGoToAll_Click(object sender, EventArgs e) 408 { 409 this.GoToAll(); 410 } 411 mnuIncreaseFontSize_Click(object sender, EventArgs e)412 private void mnuIncreaseFontSize_Click(object sender, EventArgs e) 413 { 414 this.ctrlHexViewer.TextZoom += 10; 415 this.ctrlMemoryAccessCounters.TextZoom += 10; 416 this.UpdateConfig(); 417 } 418 mnuDecreaseFontSize_Click(object sender, EventArgs e)419 private void mnuDecreaseFontSize_Click(object sender, EventArgs e) 420 { 421 this.ctrlHexViewer.TextZoom -= 10; 422 this.ctrlMemoryAccessCounters.TextZoom -= 10; 423 this.UpdateConfig(); 424 } 425 mnuResetFontSize_Click(object sender, EventArgs e)426 private void mnuResetFontSize_Click(object sender, EventArgs e) 427 { 428 this.ctrlHexViewer.TextZoom = 100; 429 this.ctrlMemoryAccessCounters.TextZoom = 100; 430 this.UpdateConfig(); 431 } 432 mnuClose_Click(object sender, EventArgs e)433 private void mnuClose_Click(object sender, EventArgs e) 434 { 435 this.Close(); 436 } 437 UpdateConfig()438 private void UpdateConfig() 439 { 440 ConfigManager.Config.DebugInfo.RamAutoRefresh = this.mnuAutoRefresh.Checked; 441 442 ConfigManager.Config.DebugInfo.RamIgnoreRedundantWrites = this.mnuIgnoreRedundantWrites.Checked; 443 ConfigManager.Config.DebugInfo.RamHighlightCurrentRowColumn = this.mnuHighlightCurrentRowColumn.Checked; 444 445 ConfigManager.Config.DebugInfo.RamShowCharacters = this.mnuShowCharacters.Checked; 446 ConfigManager.Config.DebugInfo.RamShowLabelInfo = this.mnuShowLabelInfoOnMouseOver.Checked; 447 448 ConfigManager.Config.DebugInfo.RamTextZoom = this.ctrlHexViewer.TextZoom; 449 ConfigManager.Config.DebugInfo.RamFontFamily = this.ctrlHexViewer.BaseFont.FontFamily.Name; 450 ConfigManager.Config.DebugInfo.RamFontSize = this.ctrlHexViewer.BaseFont.Size; 451 ConfigManager.Config.DebugInfo.RamFontStyle = this.ctrlHexViewer.BaseFont.Style; 452 453 ConfigManager.Config.DebugInfo.RamHighlightExecution = this.mnuHighlightExecution.Checked; 454 ConfigManager.Config.DebugInfo.RamHighlightReads = this.mnuHightlightReads.Checked; 455 ConfigManager.Config.DebugInfo.RamHighlightWrites = this.mnuHighlightWrites.Checked; 456 ConfigManager.Config.DebugInfo.RamHideUnusedBytes = this.mnuHideUnusedBytes.Checked; 457 ConfigManager.Config.DebugInfo.RamHideReadBytes = this.mnuHideReadBytes.Checked; 458 ConfigManager.Config.DebugInfo.RamHideWrittenBytes = this.mnuHideWrittenBytes.Checked; 459 ConfigManager.Config.DebugInfo.RamHideExecutedBytes = this.mnuHideExecutedBytes.Checked; 460 ConfigManager.Config.DebugInfo.RamHideExecutedBytes = this.mnuHideExecutedBytes.Checked; 461 462 ConfigManager.Config.DebugInfo.RamHighlightBreakpoints = this.mnuHighlightBreakpoints.Checked; 463 ConfigManager.Config.DebugInfo.RamHighlightLabelledBytes = this.mnuHighlightLabelledBytes.Checked; 464 ConfigManager.Config.DebugInfo.RamHighlightChrDrawnBytes = this.mnuHighlightChrDrawnBytes.Checked; 465 ConfigManager.Config.DebugInfo.RamHighlightChrReadBytes = this.mnuHighlightChrReadBytes.Checked; 466 ConfigManager.Config.DebugInfo.RamHighlightCodeBytes = this.mnuHighlightCodeBytes.Checked; 467 ConfigManager.Config.DebugInfo.RamHighlightDataBytes = this.mnuHighlightDataBytes.Checked; 468 ConfigManager.Config.DebugInfo.RamHighlightDmcDataBytes = this.mnuHighlightDmcDataBytes.Checked; 469 470 ConfigManager.ApplyChanges(); 471 } 472 mnuAutoRefresh_Click(object sender, EventArgs e)473 private void mnuAutoRefresh_Click(object sender, EventArgs e) 474 { 475 this.UpdateConfig(); 476 } 477 UpdateImportButton()478 private void UpdateImportButton() 479 { 480 switch(_memoryType) { 481 case DebugMemoryType.ChrRam: 482 case DebugMemoryType.InternalRam: 483 case DebugMemoryType.PaletteMemory: 484 case DebugMemoryType.NametableRam: 485 case DebugMemoryType.SecondarySpriteMemory: 486 case DebugMemoryType.SpriteMemory: 487 case DebugMemoryType.WorkRam: 488 case DebugMemoryType.SaveRam: 489 mnuImport.Enabled = true; 490 break; 491 492 default: 493 mnuImport.Enabled = false; 494 break; 495 } 496 } 497 mnuImport_Click(object sender, EventArgs e)498 private void mnuImport_Click(object sender, EventArgs e) 499 { 500 OpenFileDialog ofd = new OpenFileDialog(); 501 ofd.SetFilter("Memory dump files (*.dmp)|*.dmp|All files (*.*)|*.*"); 502 ofd.InitialDirectory = ConfigManager.DebuggerFolder; 503 if(ofd.ShowDialog() == DialogResult.OK) { 504 InteropEmu.DebugSetMemoryState(_memoryType, File.ReadAllBytes(ofd.FileName)); 505 RefreshData(); 506 } 507 } 508 mnuExport_Click(object sender, EventArgs e)509 private void mnuExport_Click(object sender, EventArgs e) 510 { 511 SaveFileDialog sfd = new SaveFileDialog(); 512 sfd.SetFilter("Memory dump files (*.dmp)|*.dmp|All files (*.*)|*.*"); 513 sfd.InitialDirectory = ConfigManager.DebuggerFolder; 514 sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + " - " + cboMemoryType.SelectedItem.ToString() + ".dmp"; 515 if(sfd.ShowDialog() == DialogResult.OK) { 516 File.WriteAllBytes(sfd.FileName, this.ctrlHexViewer.GetData()); 517 } 518 } 519 tabMain_SelectedIndexChanged(object sender, EventArgs e)520 private void tabMain_SelectedIndexChanged(object sender, EventArgs e) 521 { 522 _selectedTab = this.tabMain.SelectedTab; 523 this.RefreshData(); 524 } 525 ctrlHexViewer_RequiredWidthChanged(object sender, EventArgs e)526 private void ctrlHexViewer_RequiredWidthChanged(object sender, EventArgs e) 527 { 528 this.Size = new Size(this.ctrlHexViewer.RequiredWidth + 20, this.Height); 529 } 530 mnuLoadTblFile_Click(object sender, EventArgs e)531 private void mnuLoadTblFile_Click(object sender, EventArgs e) 532 { 533 OpenFileDialog ofd = new OpenFileDialog(); 534 ofd.SetFilter("TBL files (*.tbl)|*.tbl"); 535 if(ofd.ShowDialog() == DialogResult.OK) { 536 string[] fileContents = File.ReadAllLines(ofd.FileName); 537 var tblDict = TblLoader.ToDictionary(fileContents); 538 if(tblDict == null) { 539 MessageBox.Show("Could not load TBL file. The file selected file appears to be invalid.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 540 } else { 541 DebugWorkspaceManager.GetWorkspace().TblMappings = new List<string>(fileContents); 542 this.ctrlHexViewer.ByteCharConverter = new TblByteCharConverter(tblDict); 543 this.mnuShowCharacters.Checked = true; 544 } 545 } 546 } 547 mnuResetTblMappings_Click(object sender, EventArgs e)548 private void mnuResetTblMappings_Click(object sender, EventArgs e) 549 { 550 DebugWorkspaceManager.GetWorkspace().TblMappings = null; 551 this.ctrlHexViewer.ByteCharConverter = null; 552 } 553 mnuShowCharacters_CheckedChanged(object sender, EventArgs e)554 private void mnuShowCharacters_CheckedChanged(object sender, EventArgs e) 555 { 556 this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked; 557 this.UpdateConfig(); 558 } 559 mnuIgnoreRedundantWrites_CheckedChanged(object sender, EventArgs e)560 private void mnuIgnoreRedundantWrites_CheckedChanged(object sender, EventArgs e) 561 { 562 this.UpdateFlags(); 563 this.UpdateConfig(); 564 } 565 UpdateFadeOptions()566 private void UpdateFadeOptions() 567 { 568 int fadeSpeed = ConfigManager.Config.DebugInfo.RamFadeSpeed; 569 mnuFadeSlow.Checked = fadeSpeed == 600; 570 mnuFadeNormal.Checked = fadeSpeed == 300; 571 mnuFadeFast.Checked = fadeSpeed == 120; 572 mnuFadeNever.Checked = fadeSpeed == 0; 573 mnuCustomFadeSpeed.Checked = !mnuFadeSlow.Checked && !mnuFadeNormal.Checked && !mnuFadeFast.Checked && !mnuFadeSlow.Checked; 574 } 575 mnuFadeSpeed_Click(object sender, EventArgs e)576 private void mnuFadeSpeed_Click(object sender, EventArgs e) 577 { 578 if(sender == mnuFadeSlow) { 579 ConfigManager.Config.DebugInfo.RamFadeSpeed = 600; 580 } else if(sender == mnuFadeNormal) { 581 ConfigManager.Config.DebugInfo.RamFadeSpeed = 300; 582 } else if(sender == mnuFadeFast) { 583 ConfigManager.Config.DebugInfo.RamFadeSpeed = 120; 584 } else if(sender == mnuFadeNever) { 585 ConfigManager.Config.DebugInfo.RamFadeSpeed = 0; 586 } 587 ConfigManager.ApplyChanges(); 588 UpdateFadeOptions(); 589 } 590 mnuCustomFadeSpeed_Click(object sender, EventArgs e)591 private void mnuCustomFadeSpeed_Click(object sender, EventArgs e) 592 { 593 using(frmFadeSpeed frm = new frmFadeSpeed(ConfigManager.Config.DebugInfo.RamFadeSpeed)) { 594 if(frm.ShowDialog() == DialogResult.OK) { 595 ConfigManager.Config.DebugInfo.RamFadeSpeed = frm.FadeSpeed; 596 ConfigManager.ApplyChanges(); 597 UpdateFadeOptions(); 598 } 599 } 600 } 601 mnuColorProviderOptions_Click(object sender, EventArgs e)602 private void mnuColorProviderOptions_Click(object sender, EventArgs e) 603 { 604 this.UpdateConfig(); 605 this.UpdateByteColorProvider(); 606 } 607 mnuConfigureColors_Click(object sender, EventArgs e)608 private void mnuConfigureColors_Click(object sender, EventArgs e) 609 { 610 using(frmMemoryViewerColors frm = new frmMemoryViewerColors()) { 611 if(frm.ShowDialog(this, this) == DialogResult.OK) { 612 this.RefreshData(); 613 } 614 } 615 } 616 617 private frmCodeTooltip _tooltip = null; 618 private CodeLabel _lastLabelTooltip = null; 619 private int _lastLabelArrayOffset = -1; 620 private int _lastTooltipAddress = -1; ctrlHexViewer_ByteMouseHover(int address, Point position)621 private void ctrlHexViewer_ByteMouseHover(int address, Point position) 622 { 623 if(address < 0 || !mnuShowLabelInfoOnMouseOver.Checked) { 624 if(_tooltip != null) { 625 _tooltip.Close(); 626 _lastLabelTooltip = null; 627 _lastLabelArrayOffset = -1; 628 _lastTooltipAddress = -1; 629 } 630 return; 631 } 632 633 if(_lastTooltipAddress == address) { 634 return; 635 } 636 637 _lastTooltipAddress = address; 638 639 CodeLabel label = null; 640 int arrayOffset = 0; 641 switch(_memoryType) { 642 case DebugMemoryType.CpuMemory: 643 AddressTypeInfo info = new AddressTypeInfo(); 644 InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)address, info); 645 if(info.Address >= 0) { 646 label = LabelManager.GetLabel((UInt32)info.Address, info.Type); 647 if(label != null) { 648 arrayOffset = info.Address - (int)label.Address; 649 } 650 } 651 if(label == null) { 652 label = LabelManager.GetLabel((UInt32)address, AddressType.Register); 653 } 654 break; 655 656 case DebugMemoryType.InternalRam: 657 case DebugMemoryType.WorkRam: 658 case DebugMemoryType.SaveRam: 659 case DebugMemoryType.PrgRom: 660 label = LabelManager.GetLabel((UInt32)address, _memoryType.ToAddressType()); 661 if(label != null) { 662 arrayOffset = address - (int)label.Address; 663 } 664 break; 665 } 666 667 if(label != null) { 668 if(_lastLabelTooltip != label || _lastLabelArrayOffset != arrayOffset) { 669 if(_tooltip != null) { 670 _tooltip.Close(); 671 } 672 673 Dictionary<string, string> values = new Dictionary<string, string>(); 674 if(!string.IsNullOrWhiteSpace(label.Label)) { 675 values["Label"] = label.Label; 676 if(label.Length > 1) { 677 values["Label"] += "+" + arrayOffset.ToString(); 678 } 679 } 680 values["Address"] = "$" + (label.Address + arrayOffset).ToString("X4"); 681 values["Address Type"] = label.AddressType.ToString(); 682 if(!string.IsNullOrWhiteSpace(label.Comment)) { 683 values["Comment"] = label.Comment; 684 } 685 686 _tooltip = new frmCodeTooltip(this, values); 687 _tooltip.FormClosed += (s, evt) => { _tooltip = null; }; 688 _tooltip.SetFormLocation(new Point(position.X, position.Y), ctrlHexViewer); 689 _lastLabelTooltip = label; 690 _lastLabelArrayOffset = arrayOffset; 691 } 692 } else { 693 if(_tooltip != null) { 694 _tooltip.Close(); 695 _lastLabelTooltip = null; 696 _lastLabelArrayOffset = -1; 697 _lastTooltipAddress = -1; 698 } 699 } 700 } 701 mnuAutoRefreshSpeed_Click(object sender, EventArgs e)702 private void mnuAutoRefreshSpeed_Click(object sender, EventArgs e) 703 { 704 if(sender == mnuAutoRefreshLow) { 705 ConfigManager.Config.DebugInfo.RamAutoRefreshSpeed = RefreshSpeed.Low; 706 } else if(sender == mnuAutoRefreshNormal) { 707 ConfigManager.Config.DebugInfo.RamAutoRefreshSpeed = RefreshSpeed.Normal; 708 } else if(sender == mnuAutoRefreshHigh) { 709 ConfigManager.Config.DebugInfo.RamAutoRefreshSpeed = RefreshSpeed.High; 710 } 711 ConfigManager.ApplyChanges(); 712 713 UpdateRefreshSpeedMenu(); 714 } 715 UpdateRefreshSpeedMenu()716 private void UpdateRefreshSpeedMenu() 717 { 718 mnuAutoRefreshLow.Checked = ConfigManager.Config.DebugInfo.RamAutoRefreshSpeed == RefreshSpeed.Low; 719 mnuAutoRefreshNormal.Checked = ConfigManager.Config.DebugInfo.RamAutoRefreshSpeed == RefreshSpeed.Normal; 720 mnuAutoRefreshHigh.Checked = ConfigManager.Config.DebugInfo.RamAutoRefreshSpeed == RefreshSpeed.High; 721 } 722 mnuHighDensityMode_CheckedChanged(object sender, EventArgs e)723 private void mnuHighDensityMode_CheckedChanged(object sender, EventArgs e) 724 { 725 ConfigManager.Config.DebugInfo.RamHighDensityTextMode = mnuHighDensityMode.Checked; 726 ConfigManager.ApplyChanges(); 727 ctrlHexViewer.HighDensityMode = ConfigManager.Config.DebugInfo.RamHighDensityTextMode; 728 } 729 mnuEnablePerByteNavigation_CheckedChanged(object sender, EventArgs e)730 private void mnuEnablePerByteNavigation_CheckedChanged(object sender, EventArgs e) 731 { 732 ConfigManager.Config.DebugInfo.RamEnablePerByteNavigation = mnuEnablePerByteNavigation.Checked; 733 ConfigManager.ApplyChanges(); 734 ctrlHexViewer.EnablePerByteNavigation = ConfigManager.Config.DebugInfo.RamEnablePerByteNavigation; 735 } 736 mnuSelectFont_Click(object sender, EventArgs e)737 private void mnuSelectFont_Click(object sender, EventArgs e) 738 { 739 ctrlHexViewer.BaseFont = FontDialogHelper.SelectFont(ctrlHexViewer.BaseFont); 740 ctrlMemoryAccessCounters.BaseFont = ctrlHexViewer.BaseFont; 741 } 742 mnuByteEditingMode_CheckedChanged(object sender, EventArgs e)743 private void mnuByteEditingMode_CheckedChanged(object sender, EventArgs e) 744 { 745 ConfigManager.Config.DebugInfo.RamByteEditingMode = mnuByteEditingMode.Checked; 746 ConfigManager.ApplyChanges(); 747 ctrlHexViewer.ByteEditingMode = ConfigManager.Config.DebugInfo.RamByteEditingMode; 748 } 749 mnuHighlightCurrentRowColumn_CheckedChanged(object sender, EventArgs e)750 private void mnuHighlightCurrentRowColumn_CheckedChanged(object sender, EventArgs e) 751 { 752 ctrlHexViewer.HighlightCurrentRowColumn = mnuHighlightCurrentRowColumn.Checked; 753 } 754 } 755 } 756