New Ram Watch - implement memory domains menu, using a new ToolHelpers class and a method that generates it (todo: refactor other tool dialogs to it this way), and some more features such as Separator, SelectAll, move up, move down, remove

This commit is contained in:
adelikat 2013-09-07 05:17:29 +00:00
parent 4fb575a2f6
commit a8234b6147
8 changed files with 1045 additions and 779 deletions

View File

@ -102,8 +102,8 @@
<Compile Include="Computers\Commodore64\Disk\VIC1541.PLA.cs" />
<Compile Include="Computers\Commodore64\Experimental\C64.cs" />
<Compile Include="Computers\Commodore64\Experimental\C64.Glue.cs" />
<Compile Include="Computers\Commodore64\Experimental\C64NTSC.cs" />
<Compile Include="Computers\Commodore64\Experimental\C64PAL.cs" />
<Compile Include="Computers\Commodore64\Experimental\C64Presets.NTSC.cs" />
<Compile Include="Computers\Commodore64\Experimental\C64Presets.PAL.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Cassette.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Cia.Interface.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Cia.Internal.cs" />
@ -125,12 +125,14 @@
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Sid.Settings.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Sid.SoundProvider.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Userport.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.Graphics.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.Interface.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.Internal.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.Registers.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.Settings.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.Sprite.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.State.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.Synth.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.Timing.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Internals\Vic.VideoProvider.cs" />
<Compile Include="Computers\Commodore64\Experimental\Chips\Presets.cs" />

View File

@ -539,6 +539,7 @@
<DependentUpon>NewRamWatch.cs</DependentUpon>
</Compile>
<Compile Include="tools\StateVisualizer.cs" />
<Compile Include="tools\ToolHelpers.cs" />
<Compile Include="tools\TraceLogger.cs">
<SubType>Form</SubType>
</Compile>

View File

@ -541,6 +541,7 @@
<DependentUpon>NewRamWatch.cs</DependentUpon>
</Compile>
<Compile Include="tools\StateVisualizer.cs" />
<Compile Include="tools\ToolHelpers.cs" />
<Compile Include="tools\TraceLogger.cs">
<SubType>Form</SubType>
</Compile>

File diff suppressed because it is too large Load Diff

View File

@ -171,21 +171,9 @@ namespace BizHawk.MultiClient
WatchCountLabel.Text = count.ToString() + (count == 1 ? " watch" : " watches");
}
private void SetMemoryDomain(int pos)
{
if (pos < Global.Emulator.MemoryDomains.Count) //Sanity check
{
Watches.Domain = Global.Emulator.MemoryDomains[pos];
}
SetPlatformAndMemoryDomainLabel();
Update();
}
private void SetPlatformAndMemoryDomainLabel()
{
string memoryDomain = Watches.Domain.ToString();
systemID = Global.Emulator.SystemId;
MemDomainLabel.Text = systemID + " " + memoryDomain;
MemDomainLabel.Text = Global.Emulator.SystemId + " " + Watches.Domain.Name;
}
private void NewWatchList(bool suppressAsk)
@ -246,6 +234,119 @@ namespace BizHawk.MultiClient
Global.Config.RamWatchHeight = Bottom - Top;
}
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);
}
void Changes()
{
Watches.Changes = true;
MessageLabel.Text = Path.GetFileName(Watches.CurrentFileName) + " *";
}
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();
}
List<int> indices = new List<int>();
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();
}
void MoveDown()
{
ListView.SelectedIndexCollection 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 potnetially,
//but this avoids it being flagged falsely when the user did not select an index
Changes();
}
List<int> indices = new List<int>();
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()
{
Changes();
ListView.SelectedIndexCollection indexes = WatchListView.SelectedIndices;
if (indexes.Count > 0)
{
if (indexes[0] > 0)
{
Watches.Insert(indexes[0], SeparatorWatch.Instance);
}
}
else
{
Watches.Add(SeparatorWatch.Instance);
}
DisplayWatches();
}
#region Winform Events
private void NewRamWatch_Load(object sender, EventArgs e)
@ -337,6 +438,79 @@ namespace BizHawk.MultiClient
}
}
/*************Watches***********************/
private void watchesToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
ListView.SelectedIndexCollection indexes = WatchListView.SelectedIndices;
if (indexes.Count > 0)
{
editWatchToolStripMenuItem.Enabled = true;
duplicateWatchToolStripMenuItem.Enabled = true;
removeWatchToolStripMenuItem.Enabled = true;
moveUpToolStripMenuItem.Enabled = true;
moveDownToolStripMenuItem.Enabled = true;
pokeAddressToolStripMenuItem.Enabled = true;
freezeAddressToolStripMenuItem.Enabled = true;
}
else
{
editWatchToolStripMenuItem.Enabled = false;
duplicateWatchToolStripMenuItem.Enabled = false;
removeWatchToolStripMenuItem.Enabled = false;
moveUpToolStripMenuItem.Enabled = false;
moveDownToolStripMenuItem.Enabled = false;
pokeAddressToolStripMenuItem.Enabled = false;
freezeAddressToolStripMenuItem.Enabled = false;
}
}
private void memoryDomainsToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{
memoryDomainsToolStripMenuItem.DropDownItems.Clear();
memoryDomainsToolStripMenuItem.DropDownItems.AddRange(ToolHelpers.GenerateMemoryDomainMenuItems(SetMemoryDomain, Watches.Domain.Name));
}
private void removeWatchToolStripMenuItem_Click(object sender, EventArgs e)
{
ListView.SelectedIndexCollection 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 void insertSeparatorToolStripMenuItem_Click(object sender, EventArgs e)
{
InsertSeparator();
}
private void clearChangeCountsToolStripMenuItem_Click(object sender, EventArgs e)
{
Watches.ClearChangeCounts();
}
private void moveUpToolStripMenuItem_Click(object sender, EventArgs e)
{
MoveUp();
}
private void moveDownToolStripMenuItem_Click(object sender, EventArgs e)
{
MoveDown();
}
private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
{
SelectAll();
}
/*************Options***********************/
private void optionsToolStripMenuItem_DropDownOpened(object sender, EventArgs e)
{

View File

@ -1328,7 +1328,7 @@ namespace BizHawk.MultiClient
private void SetMemoryDomainMenu()
{
memoryDomainsToolStripMenuItem.DropDownItems.Clear();
if (Global.Emulator.MemoryDomains.Count > 0)
if (Global.Emulator.MemoryDomains.Any())
{
for (int x = 0; x < Global.Emulator.MemoryDomains.Count; x++)
{

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace BizHawk.MultiClient
{
class ToolHelpers
{
public static ToolStripMenuItem[] GenerateMemoryDomainMenuItems(Action<int> SetCallback, string SelectedDomain = "")
{
var items = new List<ToolStripMenuItem>();
if (Global.Emulator.MemoryDomains.Any())
{
int counter = 0;
foreach (var domain in Global.Emulator.MemoryDomains)
{
string temp = domain.ToString();
var item = new ToolStripMenuItem { Text = temp };
int index = counter;
item.Click += (o, ev) => SetCallback(index);
if (temp == SelectedDomain)
{
item.Checked = true;
}
items.Add(item);
counter++;
}
}
return items.ToArray();
}
}
}

View File

@ -951,43 +951,43 @@ namespace BizHawk.MultiClient
}
}
public char SizeAsChar
{
get
{
switch (Size)
{
default:
case WatchSize.Separator:
return 'S';
case WatchSize.Byte:
return 'b';
case WatchSize.Word:
return 'w';
case WatchSize.DWord:
return 'd';
}
}
}
public char SizeAsChar
{
get
{
switch (Size)
{
default:
case WatchSize.Separator:
return 'S';
case WatchSize.Byte:
return 'b';
case WatchSize.Word:
return 'w';
case WatchSize.DWord:
return 'd';
}
}
}
public char TypeAsChar
{
get
{
switch (Type)
{
default:
case DisplayType.Separator:
return '_';
case DisplayType.Unsigned:
return 's';
case DisplayType.Signed:
return 'u';
case DisplayType.Hex:
return 'h';
}
}
}
public char TypeAsChar
{
get
{
switch (Type)
{
default:
case DisplayType.Separator:
return '_';
case DisplayType.Unsigned:
return 's';
case DisplayType.Signed:
return 'u';
case DisplayType.Hex:
return 'h';
}
}
}
public string AddressFormatStr
{
@ -1047,6 +1047,14 @@ namespace BizHawk.MultiClient
{
public SeparatorWatch() { }
public static SeparatorWatch Instance
{
get
{
return new SeparatorWatch();
}
}
public override int? Address
{
get { return null; }
@ -1235,6 +1243,11 @@ namespace BizHawk.MultiClient
return GetEnumerator();
}
public int Count
{
get { return _watchList.Count; }
}
public WatchEntryBase this[int index]
{
get
@ -1261,7 +1274,7 @@ namespace BizHawk.MultiClient
public string AddressFormatStr
{
get
get
{
if (_domain != null)
{
@ -1292,6 +1305,32 @@ namespace BizHawk.MultiClient
}
}
public void Add(WatchEntryBase watch)
{
_watchList.Add(watch);
Changes = true;
}
public void Remove(WatchEntryBase watch)
{
_watchList.Remove(watch);
Changes = true;
}
public void Insert(int index, WatchEntryBase watch)
{
_watchList.Insert(index, watch);
}
public void ClearChangeCounts()
{
var detailedWatches = _watchList.OfType<iWatchEntryDetails>().ToList();
foreach (var watch in detailedWatches)
{
watch.ClearChangeCount();
}
}
#region File handling logic - probably needs to be its own class
public string CurrentFileName { get { return _currentFilename; } set { _currentFilename = value; } }
@ -1299,8 +1338,8 @@ namespace BizHawk.MultiClient
public bool Save()
{
bool result = false;
if (!String.IsNullOrWhiteSpace(CurrentFileName))
bool result = false;
if (!String.IsNullOrWhiteSpace(CurrentFileName))
{
result = SaveFile();
}
@ -1309,12 +1348,12 @@ namespace BizHawk.MultiClient
result = SaveAs();
}
if (result)
{
Changes = false;
}
if (result)
{
Changes = false;
}
return result;
return result;
}
public bool Load(string path, bool details, bool append)
@ -1325,12 +1364,12 @@ namespace BizHawk.MultiClient
{
if (append)
{
Changes = true;
Changes = true;
}
else
{
CurrentFileName = path;
Changes = false;
CurrentFileName = path;
Changes = false;
}
}
@ -1339,48 +1378,48 @@ namespace BizHawk.MultiClient
private bool SaveFile()
{
if (String.IsNullOrWhiteSpace(CurrentFileName))
{
return false;
}
if (String.IsNullOrWhiteSpace(CurrentFileName))
{
return false;
}
using (StreamWriter sw = new StreamWriter(CurrentFileName))
{
StringBuilder sb = new StringBuilder();
sb
.Append("Domain ").AppendLine(_domain.Name)
.Append("SystemID ").AppendLine(Global.Emulator.SystemId);
using (StreamWriter sw = new StreamWriter(CurrentFileName))
{
StringBuilder sb = new StringBuilder();
sb
.Append("Domain ").AppendLine(_domain.Name)
.Append("SystemID ").AppendLine(Global.Emulator.SystemId);
foreach (WatchEntryBase w in _watchList)
{
sb
.Append(String.Format(AddressFormatStr, w.Address)).Append('\t')
.Append(w.SizeAsChar).Append('\t')
.Append(w.TypeAsChar).Append('\t')
.Append(w.BigEndian ? '1' : '0').Append('\t')
.Append(w.DomainName).Append('\t')
.Append(w is iWatchEntryDetails ? (w as iWatchEntryDetails).Notes : String.Empty)
.AppendLine();
}
foreach (WatchEntryBase w in _watchList)
{
sb
.Append(String.Format(AddressFormatStr, w.Address)).Append('\t')
.Append(w.SizeAsChar).Append('\t')
.Append(w.TypeAsChar).Append('\t')
.Append(w.BigEndian ? '1' : '0').Append('\t')
.Append(w.DomainName).Append('\t')
.Append(w is iWatchEntryDetails ? (w as iWatchEntryDetails).Notes : String.Empty)
.AppendLine();
}
sw.WriteLine(sb.ToString());
}
sw.WriteLine(sb.ToString());
}
return true;
return true;
}
public bool SaveAs()
{
var file = WatchCommon.GetSaveFileFromUser(CurrentFileName);
if (file != null)
{
CurrentFileName = file.FullName;
return SaveFile();
}
else
{
return false;
}
var file = WatchCommon.GetSaveFileFromUser(CurrentFileName);
if (file != null)
{
CurrentFileName = file.FullName;
return SaveFile();
}
else
{
return false;
}
}
private bool LoadFile(string path, bool details, bool append)
@ -1394,10 +1433,10 @@ namespace BizHawk.MultiClient
{
string line;
if (append == false)
{
Clear();
}
if (append == false)
{
Clear();
}
while ((line = sr.ReadLine()) != null)
{
@ -1530,52 +1569,52 @@ namespace BizHawk.MultiClient
return 0;
}
public static FileInfo GetFileFromUser(string currentFile)
{
var ofd = new OpenFileDialog();
if (currentFile.Length > 0)
ofd.FileName = Path.GetFileNameWithoutExtension(currentFile);
ofd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.WatchPath, null);
ofd.Filter = "Watch Files (*.wch)|*.wch|All Files|*.*";
ofd.RestoreDirectory = true;
public static FileInfo GetFileFromUser(string currentFile)
{
var ofd = new OpenFileDialog();
if (currentFile.Length > 0)
ofd.FileName = Path.GetFileNameWithoutExtension(currentFile);
ofd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.WatchPath, null);
ofd.Filter = "Watch Files (*.wch)|*.wch|All Files|*.*";
ofd.RestoreDirectory = true;
Global.Sound.StopSound();
var result = ofd.ShowDialog();
Global.Sound.StartSound();
if (result != DialogResult.OK)
return null;
var file = new FileInfo(ofd.FileName);
return file;
}
Global.Sound.StopSound();
var result = ofd.ShowDialog();
Global.Sound.StartSound();
if (result != DialogResult.OK)
return null;
var file = new FileInfo(ofd.FileName);
return file;
}
public static FileInfo GetSaveFileFromUser(string currentFile)
{
var sfd = new SaveFileDialog();
if (currentFile.Length > 0)
{
sfd.FileName = Path.GetFileNameWithoutExtension(currentFile);
sfd.InitialDirectory = Path.GetDirectoryName(currentFile);
}
else if (!(Global.Emulator is NullEmulator))
{
sfd.FileName = PathManager.FilesystemSafeName(Global.Game);
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.WatchPath, null);
}
else
{
sfd.FileName = "NULL";
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.WatchPath, null);
}
sfd.Filter = "Watch Files (*.wch)|*.wch|All Files|*.*";
sfd.RestoreDirectory = true;
Global.Sound.StopSound();
var result = sfd.ShowDialog();
Global.Sound.StartSound();
if (result != DialogResult.OK)
return null;
var file = new FileInfo(sfd.FileName);
return file;
}
public static FileInfo GetSaveFileFromUser(string currentFile)
{
var sfd = new SaveFileDialog();
if (currentFile.Length > 0)
{
sfd.FileName = Path.GetFileNameWithoutExtension(currentFile);
sfd.InitialDirectory = Path.GetDirectoryName(currentFile);
}
else if (!(Global.Emulator is NullEmulator))
{
sfd.FileName = PathManager.FilesystemSafeName(Global.Game);
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.WatchPath, null);
}
else
{
sfd.FileName = "NULL";
sfd.InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.WatchPath, null);
}
sfd.Filter = "Watch Files (*.wch)|*.wch|All Files|*.*";
sfd.RestoreDirectory = true;
Global.Sound.StopSound();
var result = sfd.ShowDialog();
Global.Sound.StartSound();
if (result != DialogResult.OK)
return null;
var file = new FileInfo(sfd.FileName);
return file;
}
#endregion
}