diff --git a/BizHawk.Client.Common/tools/RamSearchEngine.cs b/BizHawk.Client.Common/tools/RamSearchEngine.cs index a109c9d076..7cb68482b7 100644 --- a/BizHawk.Client.Common/tools/RamSearchEngine.cs +++ b/BizHawk.Client.Common/tools/RamSearchEngine.cs @@ -314,7 +314,7 @@ namespace BizHawk.Client.Common } } - public void RemoveRange(List addresses) + public void RemoveRange(IEnumerable addresses) { _watchList = _watchList.Where(x => !addresses.Contains(x.Address)).ToList(); } diff --git a/BizHawk.Client.EmuHawk/tools/ToolHelpers.cs b/BizHawk.Client.EmuHawk/tools/ToolHelpers.cs index 20b61e5c4a..7f57b8cd6e 100644 --- a/BizHawk.Client.EmuHawk/tools/ToolHelpers.cs +++ b/BizHawk.Client.EmuHawk/tools/ToolHelpers.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Text; using System.Windows.Forms; using BizHawk.Client.Common; @@ -156,37 +155,22 @@ namespace BizHawk.Client.EmuHawk GlobalWin.Sound.StartSound(); } - public static ToolStripMenuItem[] GenerateMemoryDomainMenuItems(Action SetCallback, string SelectedDomain = "", int? maxSize = null) + public static IEnumerable GenerateMemoryDomainMenuItems(Action setCallback, string selectedDomain = "", int? maxSize = null) { var items = new List(); - if (Global.Emulator.MemoryDomains.Any()) + foreach (var domain in Global.Emulator.MemoryDomains) { - int counter = 0; - foreach (var domain in Global.Emulator.MemoryDomains) - { - string temp = domain.ToString(); - var item = new ToolStripMenuItem { Text = temp }; + string name = domain.Name; - int index = counter; - item.Click += (o, ev) => SetCallback(index); - - if (temp == SelectedDomain) - { - item.Checked = true; - } - - if (maxSize.HasValue && domain.Size > maxSize.Value) - { - item.Enabled = false; - } - - items.Add(item); - counter++; - } + var item = new ToolStripMenuItem { Text = name }; + item.Click += (o, ev) => setCallback(name); + item.Checked = name == selectedDomain; + item.Enabled = !(maxSize.HasValue && domain.Size > maxSize.Value); + items.Add(item); } - return items.ToArray(); + return items; } public static void PopulateMemoryDomainDropdown(ref ComboBox dropdown, MemoryDomain startDomain) @@ -226,7 +210,7 @@ namespace BizHawk.Client.EmuHawk if (!watch.IsSeparator) { Global.CheatList.Add( - new Cheat(watch, watch.Value.Value, compare: null, enabled: true) + new Cheat(watch, watch.Value ?? 0) ); } } diff --git a/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs b/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs index e447b220b9..8a527be1c3 100644 --- a/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs +++ b/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs @@ -521,16 +521,13 @@ namespace BizHawk.Client.EmuHawk MemDomainLabel.Text = Global.Emulator.SystemId + " " + Searches.Domain.Name; } - private void SetMemoryDomain(int pos) + private void SetMemoryDomain(string name) { - if (pos < Global.Emulator.MemoryDomains.Count) //Sanity check - { - Settings.Domain = Global.Emulator.MemoryDomains[pos]; - SetDomainLabel(); - SetReboot(true); - SpecificAddressBox.MaxLength = IntHelpers.GetNumDigits(Settings.Domain.Size); - DoDomainSizeCheck(); - } + Settings.Domain = Global.Emulator.MemoryDomains[name]; + SetDomainLabel(); + SetReboot(true); + SpecificAddressBox.MaxLength = IntHelpers.GetNumDigits(Settings.Domain.Size); + DoDomainSizeCheck(); } private void DoDomainSizeCheck() @@ -1021,7 +1018,7 @@ namespace BizHawk.Client.EmuHawk private void MemoryDomainsSubMenu_DropDownOpened(object sender, EventArgs e) { MemoryDomainsSubMenu.DropDownItems.Clear(); - MemoryDomainsSubMenu.DropDownItems.AddRange(ToolHelpers.GenerateMemoryDomainMenuItems(SetMemoryDomain, Searches.Domain.Name, MaxSupportedSize)); + MemoryDomainsSubMenu.DropDownItems.AddRange(ToolHelpers.GenerateMemoryDomainMenuItems(SetMemoryDomain, Searches.Domain.Name, MaxSupportedSize).ToArray()); } private void SizeSubMenu_DropDownOpened(object sender, EventArgs e) diff --git a/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs b/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs index dece560261..ec1724f2bc 100644 --- a/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs +++ b/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs @@ -13,7 +13,7 @@ namespace BizHawk.Client.EmuHawk { public partial class RamWatch : Form, IToolForm { - private readonly Dictionary DefaultColumnWidths = new Dictionary + private readonly Dictionary _defaultColumnWidths = new Dictionary { { WatchList.ADDRESS, 60 }, { WatchList.VALUE, 59 }, @@ -24,143 +24,24 @@ namespace BizHawk.Client.EmuHawk { WatchList.NOTES, 128 }, }; - private int defaultWidth; - private int defaultHeight; - private readonly WatchList Watches = new WatchList(Global.Emulator.MemoryDomains.MainMemory); + private int _defaultWidth; + private int _defaultHeight; private string _sortedColumn = String.Empty; - private bool _sortReverse = false; + private bool _sortReverse; - public bool UpdateBefore { get { return true; } } + private readonly WatchList Watches = new WatchList(Global.Emulator.MemoryDomains.MainMemory); - public RamWatch() - { - InitializeComponent(); - WatchListView.QueryItemText += WatchListView_QueryItemText; - WatchListView.QueryItemBkColor += WatchListView_QueryItemBkColor; - WatchListView.VirtualMode = true; - Closing += (o, e) => - { - if (AskSave()) - { - SaveConfigSettings(); - } - else - { - e.Cancel = true; - } - }; - _sortedColumn = String.Empty; - _sortReverse = false; - - TopMost = Global.Config.RamWatchAlwaysOnTop; - } - - public void UpdateValues() - { - if ((!IsHandleCreated || IsDisposed) && !Global.Config.DisplayRamWatch) - { - return; - } - - if (Watches.Any()) - { - Watches.UpdateValues(); - - if (Global.Config.DisplayRamWatch) - { - for (int x = 0; x < Watches.Count; x++) - { - bool alert = Watches[x].IsSeparator ? false : Global.CheatList.IsActive(Watches[x].Domain, Watches[x].Address.Value); - GlobalWin.OSD.AddGUIText( - Watches[x].ToString(), - Global.Config.DispRamWatchx, - (Global.Config.DispRamWatchy + (x * 14)), - alert, - Color.Black, - Color.White, - 0 - ); - } - } - - - if (!IsHandleCreated || IsDisposed) return; - - WatchListView.BlazingFast = true; - WatchListView.Refresh(); - WatchListView.BlazingFast = false; - } - } - - public void Restart() - { - if ((!IsHandleCreated || IsDisposed) && !Global.Config.DisplayRamWatch) - { - return; - } - - if (!String.IsNullOrWhiteSpace(Watches.CurrentFileName)) - { - Watches.Reload(); - } - else - { - NewWatchList(true); - } - } + #region API public void AddWatch(Watch watch) { Watches.Add(watch); - DisplayWatches(); + WatchListView.ItemCount = Watches.ItemCount; UpdateValues(); UpdateWatchCount(); Changes(); } - public void LoadWatchFile(FileInfo file, bool append) - { - if (file != null) - { - bool result = true; - if (Watches.Changes) - { - result = AskSave(); - } - - if (result) - { - Watches.Load(file.FullName, append); - DisplayWatches(); - UpdateMessageLabel(); - UpdateWatchCount(); - Global.Config.RecentWatches.Add(Watches.CurrentFileName); - SetMemoryDomain(GetDomainPos(Watches.Domain.ToString())); - } - } - } - - private int GetDomainPos(string name) - { - //Attempts to find the memory domain by name, if it fails, it defaults to index 0 - for (int i = 0; i < Global.Emulator.MemoryDomains.Count; i++) - { - if (Global.Emulator.MemoryDomains[i].Name == name) - { - return i; - } - } - return 0; - } - - public List AddressList - { - get - { - return Watches.Where(x => !x.IsSeparator).Select(x => x.Address.Value).ToList(); - } - } - public bool AskSave() { if (Global.Config.SupressAskSave) //User has elected to not be nagged @@ -191,13 +72,494 @@ namespace BizHawk.Client.EmuHawk return true; } - public void SaveConfigSettings() + public IEnumerable AddressList { - SaveColumnInfo(); - Global.Config.RamWatchWndx = Location.X; - Global.Config.RamWatchWndy = Location.Y; - Global.Config.RamWatchWidth = Right - Left; - Global.Config.RamWatchHeight = Bottom - Top; + get + { + return Watches.Where(x => !x.IsSeparator).Select(x => x.Address ?? 0).ToList(); + } + } + + public void LoadFileFromRecent(string path) + { + bool ask_result = true; + if (Watches.Changes) + { + ask_result = AskSave(); + } + + if (ask_result) + { + bool load_result = Watches.Load(path, append: false); + if (!load_result) + { + ToolHelpers.HandleLoadError(Global.Config.RecentWatches, path); + } + else + { + Global.Config.RecentWatches.Add(path); + WatchListView.ItemCount = Watches.ItemCount; + UpdateWatchCount(); + UpdateMessageLabel(); + Watches.Changes = false; + } + } + } + + public void LoadWatchFile(FileInfo file, bool append) + { + if (file != null) + { + bool result = true; + if (Watches.Changes) + { + result = AskSave(); + } + + if (result) + { + Watches.Load(file.FullName, append); + WatchListView.ItemCount = Watches.ItemCount; + UpdateMessageLabel(); + UpdateWatchCount(); + Global.Config.RecentWatches.Add(Watches.CurrentFileName); + SetMemoryDomain(Watches.Domain.ToString()); + } + } + } + + public RamWatch() + { + InitializeComponent(); + WatchListView.QueryItemText += WatchListView_QueryItemText; + WatchListView.QueryItemBkColor += WatchListView_QueryItemBkColor; + WatchListView.VirtualMode = true; + Closing += (o, e) => + { + if (AskSave()) + { + SaveConfigSettings(); + } + else + { + e.Cancel = true; + } + }; + _sortedColumn = String.Empty; + _sortReverse = false; + + TopMost = Global.Config.RamWatchAlwaysOnTop; + } + + public void Restart() + { + if ((!IsHandleCreated || IsDisposed) && !Global.Config.DisplayRamWatch) + { + return; + } + + if (!String.IsNullOrWhiteSpace(Watches.CurrentFileName)) + { + Watches.Reload(); + } + else + { + NewWatchList(true); + } + } + + public bool UpdateBefore { get { return true; } } + + public void UpdateValues() + { + if ((!IsHandleCreated || IsDisposed) && !Global.Config.DisplayRamWatch) + { + return; + } + + if (Watches.Any()) + { + Watches.UpdateValues(); + + if (Global.Config.DisplayRamWatch) + { + for (int x = 0; x < Watches.Count; x++) + { + bool alert = !Watches[x].IsSeparator && Global.CheatList.IsActive(Watches[x].Domain, (Watches[x].Address ?? 0)); + GlobalWin.OSD.AddGUIText( + Watches[x].ToString(), + Global.Config.DispRamWatchx, + (Global.Config.DispRamWatchy + (x * 14)), + alert, + Color.Black, + Color.White, + 0 + ); + } + } + + + if (!IsHandleCreated || IsDisposed) return; + + WatchListView.BlazingFast = true; + WatchListView.Refresh(); + WatchListView.BlazingFast = false; + } + } + + #endregion + + #region Private Methods + + private void AddNewWatch() + { + WatchEditor we = new WatchEditor + { + InitialLocation = GetPromptPoint() + }; + we.SetWatch(Watches.Domain); + GlobalWin.Sound.StopSound(); + we.ShowDialog(); + GlobalWin.Sound.StartSound(); + + if (we.DialogResult == DialogResult.OK) + { + Watches.Add(we.Watches[0]); + Changes(); + UpdateWatchCount(); + WatchListView.ItemCount = Watches.ItemCount; + } + } + + private void Changes() + { + Watches.Changes = true; + UpdateMessageLabel(); + } + + private void ColumnPositions() + { + List> Columns = + Global.Config.RamWatchColumnIndexes + .Where(x => WatchListView.Columns.ContainsKey(x.Key)) + .OrderBy(x => x.Value).ToList(); + + for (int i = 0; i < Columns.Count; i++) + { + if (WatchListView.Columns.ContainsKey(Columns[i].Key)) + { + WatchListView.Columns[Columns[i].Key].DisplayIndex = i; + } + } + } + + private void CopyWatchesToClipBoard() + { + var indexes = WatchListView.SelectedIndices; + + if (indexes.Count > 0) + { + StringBuilder sb = new StringBuilder(); + foreach (int index in indexes) + { + foreach (ColumnHeader column in WatchListView.Columns) + { + sb.Append(GetColumnValue(column.Name, index)).Append('\t'); + } + sb.Remove(sb.Length - 1, 1); + sb.AppendLine(); + } + + if (sb.Length > 0) + { + Clipboard.SetDataObject(sb.ToString()); + } + } + } + + private void EditWatch(bool duplicate = false) + { + var indexes = WatchListView.SelectedIndices; + + if (indexes.Count > 0) + { + WatchEditor we = new WatchEditor + { + InitialLocation = GetPromptPoint(), + }; + + if (!SelectedWatches.Any()) + { + return; + } + + we.SetWatch(Watches.Domain, SelectedWatches, duplicate ? WatchEditor.Mode.Duplicate : WatchEditor.Mode.Edit); + GlobalWin.Sound.StopSound(); + var result = we.ShowDialog(); + if (result == DialogResult.OK) + { + Changes(); + if (duplicate) + { + Watches.AddRange(we.Watches); + WatchListView.ItemCount = Watches.ItemCount; + } + else + { + for (int i = 0; i < we.Watches.Count; i++) + { + Watches[indexes[i]] = we.Watches[i]; + } + } + } + + GlobalWin.Sound.StartSound(); + UpdateValues(); + } + } + + private string GetColumnValue(string name, int index) + { + switch (name) + { + default: + return String.Empty; + case WatchList.ADDRESS: + return Watches[index].AddressString; + case WatchList.VALUE: + return Watches[index].ValueString; + case WatchList.PREV: + return Watches[index].PreviousStr; + case WatchList.CHANGES: + return Watches[index].ChangeCount.ToString(); + case WatchList.DIFF: + return Watches[index].Diff; + case WatchList.DOMAIN: + return Watches[index].Domain.Name; + case WatchList.NOTES: + return Watches[index].Notes; + } + } + + private int GetColumnWidth(string columnName) + { + var width = Global.Config.RamWatchColumnWidths[columnName]; + if (width == -1) + { + width = _defaultColumnWidths[columnName]; + } + + return width; + } + + private Point GetPromptPoint() + { + return PointToScreen(new Point(WatchListView.Location.X, WatchListView.Location.Y)); + } + + private void InsertSeparator() + { + var indexes = WatchListView.SelectedIndices; + if (indexes.Count > 0) + { + Watches.Insert(indexes[0], SeparatorWatch.Instance); + } + else + { + Watches.Add(SeparatorWatch.Instance); + } + WatchListView.ItemCount = Watches.ItemCount; + Changes(); + UpdateWatchCount(); + } + + private void LoadColumnInfo() + { + WatchListView.Columns.Clear(); + ToolHelpers.AddColumn(WatchListView, WatchList.ADDRESS, true, GetColumnWidth(WatchList.ADDRESS)); + ToolHelpers.AddColumn(WatchListView, WatchList.VALUE, true, GetColumnWidth(WatchList.VALUE)); + ToolHelpers.AddColumn(WatchListView, WatchList.PREV, Global.Config.RamWatchShowPrevColumn, GetColumnWidth(WatchList.PREV)); + ToolHelpers.AddColumn(WatchListView, WatchList.CHANGES, Global.Config.RamWatchShowChangeColumn, GetColumnWidth(WatchList.CHANGES)); + ToolHelpers.AddColumn(WatchListView, WatchList.DIFF, Global.Config.RamWatchShowDiffColumn, GetColumnWidth(WatchList.DIFF)); + ToolHelpers.AddColumn(WatchListView, WatchList.DOMAIN, Global.Config.RamWatchShowDomainColumn, GetColumnWidth(WatchList.DOMAIN)); + ToolHelpers.AddColumn(WatchListView, WatchList.NOTES, true, GetColumnWidth(WatchList.NOTES)); + + ColumnPositions(); + } + + private void LoadConfigSettings() + { + //Size and Positioning + _defaultWidth = Size.Width; //Save these first so that the user can restore to its original size + _defaultHeight = Size.Height; + + if (Global.Config.RamWatchSaveWindowPosition && Global.Config.RamWatchWndx >= 0 && Global.Config.RamWatchWndy >= 0) + { + Location = new Point(Global.Config.RamWatchWndx, Global.Config.RamWatchWndy); + } + + if (Global.Config.RamWatchWidth >= 0 && Global.Config.RamWatchHeight >= 0) + { + Size = new Size(Global.Config.RamWatchWidth, Global.Config.RamWatchHeight); + } + + LoadColumnInfo(); + } + + private void MoveDown() + { + var indexes = WatchListView.SelectedIndices; + if (indexes.Count == 0) + { + return; + } + + foreach (int index in indexes) + { + var watch = Watches[index]; + + if (index < Watches.Count - 1) + { + Watches.Remove(Watches[index]); + Watches.Insert(index + 1, watch); + } + + //Note: here it will get flagged many times redundantly potentially, + //but this avoids it being flagged falsely when the user did not select an index + Changes(); + } + + var indices = new List(); + for (int i = 0; i < indexes.Count; i++) + { + indices.Add(indexes[i] + 1); + } + + WatchListView.SelectedIndices.Clear(); + foreach (int t in indices) + { + WatchListView.SelectItem(t, true); + } + + WatchListView.ItemCount = Watches.ItemCount; + } + + private void MoveUp() + { + ListView.SelectedIndexCollection indexes = WatchListView.SelectedIndices; + if (indexes.Count == 0 || indexes[0] == 0) + { + return; + } + + foreach (int index in indexes) + { + var watch = Watches[index]; + Watches.Remove(Watches[index]); + Watches.Insert(index - 1, watch); + + //Note: here it will get flagged many times redundantly potentially, + //but this avoids it being flagged falsely when the user did not select an index + Changes(); + } + + var indices = new List(); + for (int i = 0; i < indexes.Count; i++) + { + indices.Add(indexes[i] - 1); + } + + WatchListView.SelectedIndices.Clear(); + foreach (int t in indices) + { + WatchListView.SelectItem(t, true); + } + + WatchListView.ItemCount = Watches.ItemCount; + } + + private void NewWatchList(bool suppressAsk) + { + bool result = true; + if (Watches.Changes) + { + result = AskSave(); + } + + if (result || suppressAsk) + { + Watches.Clear(); + WatchListView.ItemCount = Watches.ItemCount; + UpdateWatchCount(); + UpdateMessageLabel(); + _sortReverse = false; + _sortedColumn = String.Empty; + } + } + + private void OrderColumn(int index) + { + var column = WatchListView.Columns[index]; + if (column.Name != _sortedColumn) + { + _sortReverse = false; + } + + Watches.OrderWatches(column.Name, _sortReverse); + + _sortedColumn = column.Name; + _sortReverse ^= true; + WatchListView.Refresh(); + } + + private void PokeAddress() + { + if (SelectedWatches.Any()) + { + RamPoke poke = new RamPoke + { + InitialLocation = GetPromptPoint() + }; + + if (SelectedWatches.Any()) + { + poke.SetWatch(SelectedWatches); + } + + GlobalWin.Sound.StopSound(); + var result = poke.ShowDialog(); + if (result == DialogResult.OK) + { + UpdateValues(); + } + GlobalWin.Sound.StartSound(); + } + } + + private void RemoveWatch() + { + var indexes = WatchListView.SelectedIndices; + if (indexes.Count > 0) + { + foreach (int index in indexes) + { + Watches.Remove(Watches[indexes[0]]); //index[0] used since each iteration will make this the correct list index + } + indexes.Clear(); + WatchListView.ItemCount = Watches.ItemCount; + } + UpdateValues(); + UpdateWatchCount(); + } + + private void SaveAs() + { + bool result = Watches.SaveAs(ToolHelpers.GetWatchSaveFileFromUser(Watches.CurrentFileName)); + if (result) + { + UpdateMessageLabel(saved: true); + Global.Config.RecentWatches.Add(Watches.CurrentFileName); + } } private void SaveColumnInfo() @@ -245,15 +607,70 @@ namespace BizHawk.Client.EmuHawk } } - private int GetColumnWidth(string columnName) + private void SaveConfigSettings() { - var width = Global.Config.RamWatchColumnWidths[columnName]; - if (width == -1) + SaveColumnInfo(); + Global.Config.RamWatchWndx = Location.X; + Global.Config.RamWatchWndy = Location.Y; + Global.Config.RamWatchWidth = Right - Left; + Global.Config.RamWatchHeight = Bottom - Top; + } + + private void SelectAll() + { + for (int i = 0; i < Watches.Count; i++) { - width = DefaultColumnWidths[columnName]; + WatchListView.SelectItem(i, true); + } + } + + private List SelectedWatches + { + get + { + var selected = new List(); + ListView.SelectedIndexCollection indices = WatchListView.SelectedIndices; + if (indices.Count > 0) + { + selected.AddRange(from int index in indices where !Watches[index].IsSeparator select Watches[index]); + } + return selected; + } + } + + private void SetMemoryDomain(string name) + { + Watches.Domain = Global.Emulator.MemoryDomains[name]; + SetPlatformAndMemoryDomainLabel(); + Update(); + } + + private void SetPlatformAndMemoryDomainLabel() + { + MemDomainLabel.Text = Global.Emulator.SystemId + " " + Watches.Domain.Name; + } + + private void UpdateMessageLabel(bool saved = false) + { + string message = String.Empty; + if (!String.IsNullOrWhiteSpace(Watches.CurrentFileName)) + { + if (saved) + { + message = Path.GetFileName(Watches.CurrentFileName) + " saved."; + } + else + { + message = Path.GetFileName(Watches.CurrentFileName) + (Watches.Changes ? " *" : String.Empty); + } } - return width; + MessageLabel.Text = message; + } + + private void UpdateWatchCount() + { + WatchCountLabel.Text = Watches.WatchCount.ToString() + (Watches.WatchCount == 1 ? " watch" : " watches"); } private void WatchListView_QueryItemBkColor(int index, int column, ref Color color) @@ -269,7 +686,7 @@ namespace BizHawk.Client.EmuHawk { color = BackColor; } - else if (Global.CheatList.IsActive(Watches.Domain, Watches[index].Address.Value)) + else if (Global.CheatList.IsActive(Watches.Domain, Watches[index].Address ?? 0)) { color = Color.LightCyan; } @@ -315,443 +732,7 @@ namespace BizHawk.Client.EmuHawk } } - private void DisplayWatches() - { - WatchListView.ItemCount = Watches.ItemCount; - } - - private void UpdateWatchCount() - { - WatchCountLabel.Text = Watches.WatchCount.ToString() + (Watches.WatchCount == 1 ? " watch" : " watches"); - } - - private void SetPlatformAndMemoryDomainLabel() - { - MemDomainLabel.Text = Global.Emulator.SystemId + " " + Watches.Domain.Name; - } - - private void NewWatchList(bool suppressAsk) - { - bool result = true; - if (Watches.Changes) - { - result = AskSave(); - } - - if (result || suppressAsk) - { - Watches.Clear(); - DisplayWatches(); - UpdateWatchCount(); - UpdateMessageLabel(); - _sortReverse = false; - _sortedColumn = String.Empty; - } - } - - public void LoadFileFromRecent(string path) - { - bool ask_result = true; - if (Watches.Changes) - { - ask_result = AskSave(); - } - - if (ask_result) - { - bool load_result = Watches.Load(path, append: false); - if (!load_result) - { - ToolHelpers.HandleLoadError(Global.Config.RecentWatches, path); - } - else - { - Global.Config.RecentWatches.Add(path); - DisplayWatches(); - UpdateWatchCount(); - UpdateMessageLabel(); - Watches.Changes = false; - } - } - } - - private void UpdateMessageLabel(bool saved = false) - { - string message = String.Empty; - if (!String.IsNullOrWhiteSpace(Watches.CurrentFileName)) - { - if (saved) - { - message = Path.GetFileName(Watches.CurrentFileName) + " saved."; - } - else - { - message = Path.GetFileName(Watches.CurrentFileName) + (Watches.Changes ? " *" : String.Empty); - } - } - - MessageLabel.Text = message; - } - - private void SetMemoryDomain(int pos) - { - if (pos < Global.Emulator.MemoryDomains.Count) //Sanity check - { - Watches.Domain = Global.Emulator.MemoryDomains[pos]; - } - - SetPlatformAndMemoryDomainLabel(); - Update(); - } - - private void SelectAll() - { - for (int i = 0; i < Watches.Count; i++) - { - WatchListView.SelectItem(i, true); - } - } - - private void Changes() - { - Watches.Changes = true; - UpdateMessageLabel(); - } - - private void MoveUp() - { - ListView.SelectedIndexCollection indexes = WatchListView.SelectedIndices; - if (indexes.Count == 0 || indexes[0] == 0) - { - return; - } - - foreach (int index in indexes) - { - var watch = Watches[index]; - Watches.Remove(Watches[index]); - Watches.Insert(index - 1, watch); - - //Note: here it will get flagged many times redundantly potentially, - //but this avoids it being flagged falsely when the user did not select an index - Changes(); - } - - var indices = new List(); - for (int i = 0; i < indexes.Count; i++) - { - indices.Add(indexes[i] - 1); - } - - WatchListView.SelectedIndices.Clear(); - foreach (int t in indices) - { - WatchListView.SelectItem(t, true); - } - - DisplayWatches(); - } - - private void MoveDown() - { - var indexes = WatchListView.SelectedIndices; - if (indexes.Count == 0) - { - return; - } - - foreach (int index in indexes) - { - var watch = Watches[index]; - - if (index < Watches.Count - 1) - { - Watches.Remove(Watches[index]); - Watches.Insert(index + 1, watch); - } - - //Note: here it will get flagged many times redundantly potentially, - //but this avoids it being flagged falsely when the user did not select an index - Changes(); - } - - var indices = new List(); - for (int i = 0; i < indexes.Count; i++) - { - indices.Add(indexes[i] + 1); - } - - WatchListView.SelectedIndices.Clear(); - foreach (int t in indices) - { - WatchListView.SelectItem(t, true); - } - - DisplayWatches(); - } - - private void InsertSeparator() - { - var indexes = WatchListView.SelectedIndices; - if (indexes.Count > 0) - { - Watches.Insert(indexes[0], SeparatorWatch.Instance); - } - else - { - Watches.Add(SeparatorWatch.Instance); - } - DisplayWatches(); - Changes(); - UpdateWatchCount(); - } - - private Point GetPromptPoint() - { - return PointToScreen(new Point(WatchListView.Location.X, WatchListView.Location.Y)); - } - - private void AddNewWatch() - { - WatchEditor we = new WatchEditor - { - InitialLocation = GetPromptPoint() - }; - we.SetWatch(Watches.Domain); - GlobalWin.Sound.StopSound(); - we.ShowDialog(); - GlobalWin.Sound.StartSound(); - - if (we.DialogResult == DialogResult.OK) - { - Watches.Add(we.Watches[0]); - Changes(); - UpdateWatchCount(); - DisplayWatches(); - } - } - - private void EditWatch(bool duplicate = false) - { - var indexes = WatchListView.SelectedIndices; - - if (indexes.Count > 0) - { - WatchEditor we = new WatchEditor - { - InitialLocation = GetPromptPoint(), - }; - - if (!SelectedWatches.Any()) - { - return; - } - - we.SetWatch(Watches.Domain, SelectedWatches, duplicate ? WatchEditor.Mode.Duplicate : WatchEditor.Mode.Edit); - GlobalWin.Sound.StopSound(); - var result = we.ShowDialog(); - if (result == DialogResult.OK) - { - Changes(); - if (duplicate) - { - Watches.AddRange(we.Watches); - DisplayWatches(); - } - else - { - for (int i = 0; i < we.Watches.Count; i++) - { - Watches[indexes[i]] = we.Watches[i]; - } - } - } - - GlobalWin.Sound.StartSound(); - UpdateValues(); - } - } - - private void PokeAddress() - { - if (SelectedWatches.Any()) - { - RamPoke poke = new RamPoke - { - InitialLocation = GetPromptPoint() - }; - - if (SelectedWatches.Any()) - { - poke.SetWatch(SelectedWatches); - } - - GlobalWin.Sound.StopSound(); - var result = poke.ShowDialog(); - if (result == DialogResult.OK) - { - UpdateValues(); - } - GlobalWin.Sound.StartSound(); - } - } - - private List SelectedWatches - { - get - { - var selected = new List(); - ListView.SelectedIndexCollection indices = WatchListView.SelectedIndices; - if (indices.Count > 0) - { - foreach (int index in indices) - { - if (!Watches[index].IsSeparator) - { - selected.Add(Watches[index]); - } - } - } - return selected; - } - } - - private void ColumnPositions() - { - List> Columns = - Global.Config.RamWatchColumnIndexes - .Where(x => WatchListView.Columns.ContainsKey(x.Key)) - .OrderBy(x => x.Value).ToList(); - - for (int i = 0; i < Columns.Count; i++) - { - if (WatchListView.Columns.ContainsKey(Columns[i].Key)) - { - WatchListView.Columns[Columns[i].Key].DisplayIndex = i; - } - } - } - - private void LoadConfigSettings() - { - //Size and Positioning - defaultWidth = Size.Width; //Save these first so that the user can restore to its original size - defaultHeight = Size.Height; - - if (Global.Config.RamWatchSaveWindowPosition && Global.Config.RamWatchWndx >= 0 && Global.Config.RamWatchWndy >= 0) - { - Location = new Point(Global.Config.RamWatchWndx, Global.Config.RamWatchWndy); - } - - if (Global.Config.RamWatchWidth >= 0 && Global.Config.RamWatchHeight >= 0) - { - Size = new Size(Global.Config.RamWatchWidth, Global.Config.RamWatchHeight); - } - - LoadColumnInfo(); - } - - private void LoadColumnInfo() - { - WatchListView.Columns.Clear(); - ToolHelpers.AddColumn(WatchListView, WatchList.ADDRESS, true, GetColumnWidth(WatchList.ADDRESS)); - ToolHelpers.AddColumn(WatchListView, WatchList.VALUE, true, GetColumnWidth(WatchList.VALUE)); - ToolHelpers.AddColumn(WatchListView, WatchList.PREV, Global.Config.RamWatchShowPrevColumn, GetColumnWidth(WatchList.PREV)); - ToolHelpers.AddColumn(WatchListView, WatchList.CHANGES, Global.Config.RamWatchShowChangeColumn, GetColumnWidth(WatchList.CHANGES)); - ToolHelpers.AddColumn(WatchListView, WatchList.DIFF, Global.Config.RamWatchShowDiffColumn, GetColumnWidth(WatchList.DIFF)); - ToolHelpers.AddColumn(WatchListView, WatchList.DOMAIN, Global.Config.RamWatchShowDomainColumn, GetColumnWidth(WatchList.DOMAIN)); - ToolHelpers.AddColumn(WatchListView, WatchList.NOTES, true, GetColumnWidth(WatchList.NOTES)); - - ColumnPositions(); - } - - private void RemoveWatch() - { - var indexes = WatchListView.SelectedIndices; - if (indexes.Count > 0) - { - foreach (int index in indexes) - { - Watches.Remove(Watches[indexes[0]]); //index[0] used since each iteration will make this the correct list index - } - indexes.Clear(); - DisplayWatches(); - } - UpdateValues(); - UpdateWatchCount(); - } - - private string GetColumnValue(string name, int index) - { - switch (name) - { - default: - return String.Empty; - case WatchList.ADDRESS: - return Watches[index].AddressString; - case WatchList.VALUE: - return Watches[index].ValueString; - case WatchList.PREV: - return Watches[index].PreviousStr; - case WatchList.CHANGES: - return Watches[index].ChangeCount.ToString(); - case WatchList.DIFF: - return Watches[index].Diff; - case WatchList.DOMAIN: - return Watches[index].Domain.Name; - case WatchList.NOTES: - return Watches[index].Notes; - } - } - - private void CopyWatchesToClipBoard() - { - var indexes = WatchListView.SelectedIndices; - - if (indexes.Count > 0) - { - StringBuilder sb = new StringBuilder(); - foreach (int index in indexes) - { - foreach (ColumnHeader column in WatchListView.Columns) - { - sb.Append(GetColumnValue(column.Name, index)).Append('\t'); - } - sb.Remove(sb.Length - 1, 1); - sb.AppendLine(); - } - - if (sb.Length > 0) - { - Clipboard.SetDataObject(sb.ToString()); - } - } - } - - private void OrderColumn(int index) - { - var column = WatchListView.Columns[index]; - if (column.Name != _sortedColumn) - { - _sortReverse = false; - } - - Watches.OrderWatches(column.Name, _sortReverse); - - _sortedColumn = column.Name; - _sortReverse ^= true; - WatchListView.Refresh(); - } - - private void SaveAs() - { - bool result = Watches.SaveAs(ToolHelpers.GetWatchSaveFileFromUser(Watches.CurrentFileName)); - if (result) - { - UpdateMessageLabel(saved: true); - Global.Config.RecentWatches.Add(Watches.CurrentFileName); - } - } + #endregion #region Winform Events @@ -776,7 +757,7 @@ namespace BizHawk.Client.EmuHawk if (Path.GetExtension(filePaths[0]) == (".wch")) { Watches.Load(filePaths[0], append:false); - DisplayWatches(); + WatchListView.ItemCount = Watches.ItemCount; } } @@ -874,7 +855,7 @@ namespace BizHawk.Client.EmuHawk private void memoryDomainsToolStripMenuItem_DropDownOpened(object sender, EventArgs e) { memoryDomainsToolStripMenuItem.DropDownItems.Clear(); - memoryDomainsToolStripMenuItem.DropDownItems.AddRange(ToolHelpers.GenerateMemoryDomainMenuItems(SetMemoryDomain, Watches.Domain.Name)); + memoryDomainsToolStripMenuItem.DropDownItems.AddRange(ToolHelpers.GenerateMemoryDomainMenuItems(SetMemoryDomain, Watches.Domain.Name).ToArray()); } private void newWatchToolStripMenuItem_Click(object sender, EventArgs e) @@ -909,7 +890,7 @@ namespace BizHawk.Client.EmuHawk { if (!watch.IsSeparator) { - if (!Global.CheatList.IsActive(watch.Domain, watch.Address.Value)) + if (!Global.CheatList.IsActive(watch.Domain, watch.Address ?? 0)) { allCheats = false; } @@ -1062,7 +1043,7 @@ namespace BizHawk.Client.EmuHawk private void restoreWindowSizeToolStripMenuItem_Click(object sender, EventArgs e) { - Size = new Size(defaultWidth, defaultHeight); + Size = new Size(_defaultWidth, _defaultHeight); Global.Config.RamWatchColumnIndexes = new Dictionary { @@ -1082,13 +1063,13 @@ namespace BizHawk.Client.EmuHawk Global.Config.RamWatchShowPrevColumn = false; Global.Config.RamWatchShowDiffColumn = false; - WatchListView.Columns[WatchList.ADDRESS].Width = DefaultColumnWidths[WatchList.ADDRESS]; - WatchListView.Columns[WatchList.VALUE].Width = DefaultColumnWidths[WatchList.VALUE]; + WatchListView.Columns[WatchList.ADDRESS].Width = _defaultColumnWidths[WatchList.ADDRESS]; + WatchListView.Columns[WatchList.VALUE].Width = _defaultColumnWidths[WatchList.VALUE]; //WatchListView.Columns[WatchList.PREV].Width = DefaultColumnWidths[WatchList.PREV]; - WatchListView.Columns[WatchList.CHANGES].Width = DefaultColumnWidths[WatchList.CHANGES]; + WatchListView.Columns[WatchList.CHANGES].Width = _defaultColumnWidths[WatchList.CHANGES]; //WatchListView.Columns[WatchList.DIFF].Width = DefaultColumnWidths[WatchList.DIFF]; - WatchListView.Columns[WatchList.DOMAIN].Width = DefaultColumnWidths[WatchList.DOMAIN]; - WatchListView.Columns[WatchList.NOTES].Width = DefaultColumnWidths[WatchList.NOTES]; + WatchListView.Columns[WatchList.DOMAIN].Width = _defaultColumnWidths[WatchList.DOMAIN]; + WatchListView.Columns[WatchList.NOTES].Width = _defaultColumnWidths[WatchList.NOTES]; Global.Config.DisplayRamWatch = false; Global.Config.RamWatchSaveWindowPosition = true; @@ -1120,7 +1101,7 @@ namespace BizHawk.Client.EmuHawk { if (!Watches[i].IsSeparator) { - if (!Global.CheatList.IsActive(Watches[i].Domain, Watches[i].Address.Value)) + if (!Global.CheatList.IsActive(Watches[i].Domain, Watches[i].Address ?? 0)) { allCheats = false; } @@ -1162,11 +1143,11 @@ namespace BizHawk.Client.EmuHawk if (selected.Select(x => x.Domain).Distinct().Count() > 1) { - ToolHelpers.ViewInHexEditor(selected[0].Domain, new List { selected.First().Address.Value }); + ToolHelpers.ViewInHexEditor(selected[0].Domain, new List { selected.First().Address ?? 0 }); } else { - ToolHelpers.ViewInHexEditor(selected[0].Domain, selected.Select(x => x.Address.Value)); + ToolHelpers.ViewInHexEditor(selected[0].Domain, selected.Select(x => x.Address ?? 0)); } } }