1 using System; 2 using System.Collections.Generic; 3 using System.Drawing; 4 using System.Drawing.Imaging; 5 using System.IO; 6 using System.Linq; 7 using System.Text; 8 using System.Threading.Tasks; 9 using System.Xml; 10 using System.Xml.Serialization; 11 using Mesen.GUI.Debugger; 12 using Mesen.GUI.Controls; 13 14 namespace Mesen.GUI.Config 15 { 16 public enum ByteCodePosition 17 { 18 Hidden, 19 Left, 20 Below 21 } 22 23 public enum PrgAddressPosition 24 { 25 Hidden, 26 Replace, 27 Below, 28 Inline 29 } 30 31 public class DebugViewInfo 32 { 33 public bool ShowSourceAsComments = false; 34 public ByteCodePosition ByteCodePosition = ByteCodePosition.Hidden; 35 public PrgAddressPosition PrgAddressPosition = PrgAddressPosition.Hidden; 36 public int TextZoom = 100; 37 public bool UsingSourceView = false; 38 } 39 40 public class DebugWorkspace 41 { 42 public List<Breakpoint> Breakpoints = new List<Breakpoint>(); 43 public List<string> WatchValues = new List<string>(); 44 public List<CodeLabel> Labels = new List<CodeLabel>(); 45 public List<string> TblMappings = null; 46 private string _filePath; 47 GetWorkspace()48 public static DebugWorkspace GetWorkspace() 49 { 50 RomInfo info = InteropEmu.GetRomInfo(); 51 return Deserialize(Path.Combine(ConfigManager.DebuggerFolder, info.GetRomName() + ".Workspace.xml")); 52 } 53 Deserialize(string path)54 private static DebugWorkspace Deserialize(string path) 55 { 56 DebugWorkspace config = new DebugWorkspace(); 57 58 if(File.Exists(path)) { 59 try { 60 XmlSerializer xmlSerializer = new XmlSerializer(typeof(DebugWorkspace)); 61 using(TextReader textReader = new StreamReader(path)) { 62 config = (DebugWorkspace)xmlSerializer.Deserialize(textReader); 63 } 64 } catch { } 65 } 66 67 config._filePath = path; 68 69 return config; 70 } 71 Save()72 public void Save() 73 { 74 try { 75 XmlWriterSettings ws = new XmlWriterSettings(); 76 ws.NewLineHandling = NewLineHandling.Entitize; 77 ws.Indent = true; 78 79 XmlSerializer xmlSerializer = new XmlSerializer(typeof(DebugWorkspace)); 80 using(XmlWriter xmlWriter = XmlWriter.Create(_filePath, ws)) { 81 xmlSerializer.Serialize(xmlWriter, this); 82 } 83 } catch { 84 } 85 } 86 } 87 88 public enum StatusFlagFormat 89 { 90 Hexadecimal = 0, 91 Text = 1, 92 CompactText = 2 93 } 94 95 public class TraceLoggerOptions 96 { 97 public bool ShowByteCode; 98 public bool ShowRegisters; 99 public bool ShowCpuCycles; 100 public bool ShowPpuCycles; 101 public bool ShowPpuScanline; 102 public bool ShowPpuFrames; 103 public bool ShowExtraInfo; 104 public bool IndentCode; 105 public bool ShowEffectiveAddresses; 106 public bool ShowMemoryValues; 107 public bool UseLabels; 108 public bool ExtendZeroPage; 109 public bool UseWindowsEol = !Program.IsMono; 110 111 public StatusFlagFormat StatusFormat; 112 113 public bool OverrideFormat; 114 public string Format; 115 } 116 117 public class DebugInfo 118 { 119 private const int MaxRecentScripts = 10; 120 121 public DebugViewInfo LeftView; 122 public DebugViewInfo RightView; 123 124 public InteropEmu.ConsoleId DebugConsoleId = InteropEmu.ConsoleId.Master; 125 126 public string FontFamily = BaseControl.MonospaceFontFamily; 127 public FontStyle FontStyle = FontStyle.Regular; 128 public float FontSize = BaseControl.DefaultFontSize; 129 130 public bool ShowOnlyDisassembledCode = true; 131 public bool DisplayOpCodesInLowerCase = false; 132 public bool ShowEffectiveAddresses = true; 133 134 public bool AutoCreateJumpLabels = false; 135 public bool ShowJumpLabels = false; 136 137 public bool DisassembleVerifiedData = false; 138 public bool DisassembleUnidentifiedData = false; 139 140 public bool ShowVerifiedData = false; 141 public bool ShowUnidentifiedData = false; 142 143 public bool ShowCommentsInLabelList = false; 144 145 public bool ShowBreakNotifications = true; 146 public bool ShowInstructionProgression = true; 147 public bool ShowSelectionLength = false; 148 149 public bool AlwaysScrollToCenter = false; 150 public bool SplitView = false; 151 public bool VerticalLayout = false; 152 public WatchFormatStyle WatchFormat = WatchFormatStyle.Hex; 153 public bool ShowBreakpointLabels = true; 154 155 public Point EventViewerLocation; 156 public bool EventViewerRefreshOnBreak = true; 157 public bool EventViewerShowPpuRegisterWrites = true; 158 public bool EventViewerShowPpuRegisterReads = true; 159 public bool EventViewerShowMapperRegisterWrites = true; 160 public bool EventViewerShowMapperRegisterReads = true; 161 public bool EventViewerShowNmi = true; 162 public bool EventViewerShowIrq = true; 163 public bool EventViewerShowSpriteZeroHit = true; 164 public bool EventViewerShowMarkedBreakpoints = true; 165 public bool EventViewerShowPreviousFrameEvents = true; 166 167 public XmlColor EventViewerMapperRegisterWriteColor = ColorTranslator.FromHtml("#007597"); 168 public XmlColor EventViewerMapperRegisterReadColor = ColorTranslator.FromHtml("#C92929"); 169 public XmlColor EventViewerNmiColor = ColorTranslator.FromHtml("#ABADAC"); 170 public XmlColor EventViewerIrqColor = ColorTranslator.FromHtml("#F9FEAC"); 171 public XmlColor EventViewerSpriteZeroHitColor = ColorTranslator.FromHtml("#9F93C6"); 172 public XmlColor EventViewerBreakpointColor = ColorTranslator.FromHtml("#1898E4"); 173 public XmlColor[] EventViewerPpuRegisterWriteColors = new XmlColor[8] { 174 ColorTranslator.FromHtml("#FF5E5E"), ColorTranslator.FromHtml("#8E33FF"), Color.Red, ColorTranslator.FromHtml("#FF84E0"), 175 ColorTranslator.FromHtml("#FAFF39"), ColorTranslator.FromHtml("#2EFF28"), ColorTranslator.FromHtml("#3D2DFF"), ColorTranslator.FromHtml("#FF060D") 176 }; 177 public XmlColor[] EventViewerPpuRegisterReadColors = new XmlColor[8] { 178 Color.Red, Color.Red, ColorTranslator.FromHtml("#FF8224"), Color.Red, ColorTranslator.FromHtml("#24A672"), Color.Red, Color.Red, ColorTranslator.FromHtml("#6AF0FF") 179 }; 180 181 public bool CopyAddresses = false; 182 public bool CopyByteCode = false; 183 public bool CopyComments = false; 184 185 public Point? PpuWindowLocation = null; 186 187 public Point? PpuNametableViewerLocation = null; 188 public Point? PpuChrViewerLocation = null; 189 public Point? PpuSpriteViewerLocation = null; 190 public Point? PpuPaletteViewerLocation = null; 191 192 public bool PpuAutoRefresh = true; 193 public RefreshSpeed PpuAutoRefreshSpeed = RefreshSpeed.Normal; 194 public bool PpuRefreshOnBreak = true; 195 public bool PpuShowInformationOverlay = true; 196 public bool PpuPartialDraw = false; 197 public bool PpuShowPreviousFrame = false; 198 public bool HidePauseIcon = false; 199 public bool ShowPpuScrollOverlay = true; 200 public bool ShowAttributeColorsOnly = false; 201 public bool ShowTileGrid = false; 202 public bool ShowAttributeGrid = false; 203 public bool HighlightChrTile = false; 204 public bool NtViewerUseGrayscalePalette = false; 205 public bool NtViewerHighlightTileUpdates = false; 206 public bool NtViewerHighlightAttributeUpdates = false; 207 public bool NtViewerIgnoreRedundantWrites = false; 208 public bool SpriteViewerDisplaySpriteOutlines = false; 209 210 public int ChrViewerSelectedPalette = 0; 211 public CdlHighlightType ChrViewerHighlightType = CdlHighlightType.None; 212 public bool ChrViewerUseAutoPalette = true; 213 public bool ChrViewerUseLargeSprites = false; 214 public bool ChrViewerShowSingleColorTilesInGrayscale = false; 215 216 public int PpuDisplayCycle = 0; 217 public int PpuDisplayScanline = 241; 218 219 public bool ShowCodePreview = true; 220 public bool ShowOpCodeTooltips = true; 221 public bool OnlyShowTooltipsOnShift = false; 222 223 public bool ShowToolbar = true; 224 225 public bool ShowCpuMemoryMapping = true; 226 public bool ShowPpuMemoryMapping = true; 227 228 public bool ShowRightPanel = true; 229 public bool ShowBottomPanel = true; 230 public int LeftPanelWidth = 930; 231 public int TopPanelHeight = 450; 232 233 public XmlColor CodeVerifiedDataColor = Color.FromArgb(255, 252, 236); 234 public XmlColor CodeUnidentifiedDataColor = Color.FromArgb(255, 242, 242); 235 public XmlColor CodeUnexecutedCodeColor = Color.FromArgb(225, 244, 228); 236 237 public XmlColor CodeExecBreakpointColor = Color.FromArgb(140, 40, 40); 238 public XmlColor CodeWriteBreakpointColor = Color.FromArgb(40, 120, 80); 239 public XmlColor CodeReadBreakpointColor = Color.FromArgb(40, 40, 200); 240 public XmlColor CodeActiveStatementColor = Color.Yellow; 241 public XmlColor CodeEffectiveAddressColor = Color.SteelBlue; 242 243 public bool RamHighDensityTextMode = false; 244 public bool RamEnablePerByteNavigation = false; 245 public bool RamByteEditingMode = false; 246 public bool RamAutoRefresh = true; 247 public RefreshSpeed RamAutoRefreshSpeed = RefreshSpeed.Normal; 248 public bool RamIgnoreRedundantWrites = false; 249 public bool RamHighlightCurrentRowColumn = true; 250 public int RamColumnCount = 2; 251 252 public string RamFontFamily = BaseControl.MonospaceFontFamily; 253 public FontStyle RamFontStyle = FontStyle.Regular; 254 public float RamFontSize = BaseControl.DefaultFontSize; 255 public int RamTextZoom = 100; 256 257 public bool RamShowCharacters = true; 258 public bool RamShowLabelInfo = true; 259 public bool RamHighlightExecution = true; 260 public bool RamHighlightWrites = true; 261 public bool RamHighlightReads = true; 262 public int RamFadeSpeed = 300; 263 public bool RamHideUnusedBytes = false; 264 public bool RamHideReadBytes = false; 265 public bool RamHideWrittenBytes = false; 266 public bool RamHideExecutedBytes = false; 267 public bool RamHighlightBreakpoints = false; 268 public bool RamHighlightLabelledBytes = false; 269 public bool RamHighlightChrDrawnBytes = false; 270 public bool RamHighlightChrReadBytes = false; 271 public bool RamHighlightCodeBytes = false; 272 public bool RamHighlightDataBytes = false; 273 public bool RamHighlightDmcDataBytes = false; 274 public XmlColor RamReadColor = Color.Blue; 275 public XmlColor RamWriteColor = Color.Red; 276 public XmlColor RamExecColor = Color.Green; 277 public XmlColor RamLabelledByteColor = Color.LightPink; 278 public XmlColor RamCodeByteColor = Color.DarkSeaGreen; 279 public XmlColor RamDataByteColor = Color.LightSteelBlue; 280 public XmlColor RamDmcDataByteColor = Color.Gold; 281 public XmlColor RamChrDrawnByteColor = Color.DarkSeaGreen; 282 public XmlColor RamChrReadByteColor = Color.LightSteelBlue; 283 public DebugMemoryType RamMemoryType = DebugMemoryType.CpuMemory; 284 285 public Size MemoryViewerSize = new Size(0, 0); 286 public Point MemoryViewerLocation; 287 public Point? ApuViewerLocation; 288 289 public Size ProfilerSize = new Size(0, 0); 290 public Point ProfilerLocation; 291 292 public Size WatchWindowSize = new Size(0, 0); 293 public Point WatchWindowLocation; 294 295 public Point WindowLocation; 296 public int WindowWidth = -1; 297 public int WindowHeight = -1; 298 299 public int BreakInCount = 1; 300 public BreakInMetric BreakInMetric = BreakInMetric.CpuCycles; 301 302 public int BreakOnValue = 241; 303 304 public bool FindOccurrencesMatchCase = false; 305 public bool FindOccurrencesMatchWholeWord = false; 306 public string FindOccurrencesLastSearch = string.Empty; 307 308 public bool AutoLoadDbgFiles = true; 309 public bool AutoLoadCdlFiles = false; 310 public bool DisableDefaultLabels = false; 311 312 public bool RefreshWhileRunning = false; 313 public bool ShowMemoryValuesInCodeWindow = true; 314 315 public bool BreakOnOpen = true; 316 public bool BreakOnReset = true; 317 public bool BreakOnUnofficialOpcodes = true; 318 public bool BreakOnBrk = false; 319 public bool BreakOnDebuggerFocus = false; 320 public bool BreakOnCrash = false; 321 public bool BreakOnDecayedOamRead = false; 322 public bool BreakOnUninitMemoryRead = false; 323 public bool BreakOnInit = true; 324 public bool BreakOnPlay = false; 325 public bool BreakOnFirstCycle = true; 326 327 public bool BringToFrontOnPause = false; 328 public bool BringToFrontOnBreak = true; 329 330 public TraceLoggerOptions TraceLoggerOptions; 331 public bool TraceAutoRefresh = true; 332 public int TraceLineCount = 1000; 333 public Size TraceLoggerSize = new Size(0, 0); 334 public Point TraceLoggerLocation; 335 336 public string TraceFontFamily = BaseControl.MonospaceFontFamily; 337 public FontStyle TraceFontStyle = FontStyle.Regular; 338 public float TraceFontSize = BaseControl.DefaultFontSize; 339 public int TraceTextZoom = 100; 340 341 public Size ScriptWindowSize = new Size(0, 0); 342 public Point ScriptWindowLocation; 343 public int ScriptCodeWindowHeight = 0; 344 public List<string> RecentScripts = new List<string>(); 345 public bool SaveScriptBeforeRun = true; 346 public ScriptStartupBehavior ScriptStartupBehavior = ScriptStartupBehavior.ShowTutorial; 347 public bool AutoLoadLastScript = true; 348 public string ScriptFontFamily = BaseControl.MonospaceFontFamily; 349 public FontStyle ScriptFontStyle = FontStyle.Regular; 350 public float ScriptFontSize = BaseControl.DefaultFontSize; 351 public int ScriptZoom = 100; 352 public UInt32 ScriptTimeout = 1000; 353 354 public bool AssemblerCodeHighlighting = true; 355 public XmlColor AssemblerOpcodeColor = Color.FromArgb(22, 37, 37); 356 public XmlColor AssemblerLabelDefinitionColor = Color.Blue; 357 public XmlColor AssemblerImmediateColor = Color.Chocolate; 358 public XmlColor AssemblerAddressColor = Color.DarkRed; 359 public XmlColor AssemblerCommentColor = Color.Green; 360 public Size AssemblerSize = new Size(0, 0); 361 public Point AssemblerLocation; 362 public string AssemblerFontFamily = BaseControl.MonospaceFontFamily; 363 public FontStyle AssemblerFontStyle = FontStyle.Regular; 364 public float AssemblerFontSize = BaseControl.DefaultFontSize; 365 public int AssemblerZoom = 100; 366 367 public Point? TextHookerWindowLocation = null; 368 public bool TextHookerAutoRefresh = true; 369 public bool TextHookerRefreshOnBreak = true; 370 public int TextHookerDisplayCycle = 0; 371 public int TextHookerDisplayScanline = 241; 372 public List<CharMap> TextHookerCharMappings = new List<CharMap>(); 373 public bool TextHookerAdjustViewportScrolling = true; 374 public bool TextHookerIgnoreMirroredNametables = true; 375 public bool TextHookerAutoCopyToClipboard = false; 376 377 public string ExternalEditorPath; 378 public string ExternalEditorArguments; 379 380 public DebuggerShortcutsConfig Shortcuts = new DebuggerShortcutsConfig(); 381 public DebugImportConfig ImportConfig = new DebugImportConfig(); 382 DebugInfo()383 public DebugInfo() 384 { 385 LeftView = new DebugViewInfo(); 386 RightView = new DebugViewInfo(); 387 TraceLoggerOptions = new TraceLoggerOptions() { 388 ShowByteCode = true, 389 ShowCpuCycles = false, 390 ShowEffectiveAddresses = true, 391 ShowExtraInfo = true, 392 ShowPpuFrames = false, 393 ShowPpuCycles = true, 394 ShowPpuScanline = true, 395 ShowRegisters = true, 396 UseLabels = false, 397 StatusFormat = StatusFlagFormat.Hexadecimal 398 }; 399 400 if(ExternalEditorPath == null || ExternalEditorArguments == null) { 401 ExternalEditorPath = ""; 402 ExternalEditorArguments = ""; 403 404 //Setup a default editor when possible 405 if(Program.IsMono) { 406 string geditPath = "/usr/bin/gedit"; 407 string katePath = "/usr/bin/kate"; 408 if(File.Exists(geditPath)) { 409 ExternalEditorPath = geditPath; 410 ExternalEditorArguments = "+%L %F"; 411 } else if(File.Exists(katePath)) { 412 ExternalEditorPath = katePath; 413 ExternalEditorArguments = "%F -l %L"; 414 } 415 } else { 416 string notepadPath32 = "C:\\Program Files (x86)\\Notepad++\\notepad++.exe"; 417 string notepadPath64 = "C:\\Program Files\\Notepad++\\notepad++.exe"; 418 if(File.Exists(notepadPath32)) { 419 ExternalEditorPath = notepadPath32; 420 ExternalEditorArguments = "%F -n%L"; 421 } else if(File.Exists(notepadPath64)) { 422 ExternalEditorPath = notepadPath64; 423 ExternalEditorArguments = "%F -n%L"; 424 } 425 } 426 } 427 } 428 ApplyConfig()429 static public void ApplyConfig() 430 { 431 InteropEmu.SetFlag(EmulationFlags.BreakOnCrash, ConfigManager.Config.DebugInfo.BreakOnCrash); 432 InteropEmu.DebugSetScriptTimeout(ConfigManager.Config.DebugInfo.ScriptTimeout); 433 } 434 AddRecentScript(string scriptFile)435 public void AddRecentScript(string scriptFile) 436 { 437 string existingItem = RecentScripts.Where((file) => file == scriptFile).FirstOrDefault(); 438 if(existingItem != null) { 439 RecentScripts.Remove(existingItem); 440 } 441 442 RecentScripts.Insert(0, scriptFile); 443 if(RecentScripts.Count > DebugInfo.MaxRecentScripts) { 444 RecentScripts.RemoveAt(DebugInfo.MaxRecentScripts); 445 } 446 ConfigManager.ApplyChanges(); 447 } 448 } 449 450 public class DebugImportConfig 451 { 452 public bool ResetLabelsOnImport = true; 453 454 public bool DbgImportRamLabels = true; 455 public bool DbgImportWorkRamLabels = true; 456 public bool DbgImportSaveRamLabels = true; 457 public bool DbgImportPrgRomLabels = true; 458 public bool DbgImportComments = true; 459 460 public bool MlbImportInternalRamLabels = true; 461 public bool MlbImportWorkRamLabels = true; 462 public bool MlbImportSaveRamLabels = true; 463 public bool MlbImportRegisterLabels = true; 464 public bool MlbImportPrgRomLabels = true; 465 public bool MlbImportComments = true; 466 } 467 468 public enum ScriptStartupBehavior 469 { 470 ShowTutorial = 0, 471 ShowBlankWindow = 1, 472 LoadLastScript = 2 473 } 474 475 public enum RefreshSpeed 476 { 477 Low = 0, 478 Normal = 1, 479 High = 2 480 } 481 482 public enum BreakInMetric 483 { 484 CpuCycles, 485 CpuInstructions, 486 PpuCycles, 487 Scanlines, 488 Frames 489 } 490 491 public class XmlColor 492 { 493 private Color _color = Color.Black; 494 XmlColor()495 public XmlColor() { } XmlColor(Color c)496 public XmlColor(Color c) { _color = c; } 497 498 [XmlIgnore] 499 public Color Color 500 { 501 get { return _color; } 502 set { _color = value; } 503 } 504 operator Color(XmlColor x)505 public static implicit operator Color(XmlColor x) 506 { 507 return x.Color; 508 } 509 operator XmlColor(Color c)510 public static implicit operator XmlColor(Color c) 511 { 512 return new XmlColor(c); 513 } 514 515 [XmlAttribute] 516 public string ColorString 517 { 518 get { return ColorTranslator.ToHtml(_color); } 519 set 520 { 521 try { 522 _color = ColorTranslator.FromHtml(value); 523 } catch(Exception) { 524 _color = Color.Black; 525 } 526 } 527 } 528 } 529 530 public class CharMap 531 { 532 [XmlAttribute] 533 public string Key; 534 [XmlAttribute] 535 public string Value; 536 } 537 } 538