Comments on Watch derived class; started on watchlist
+ Moved WatchList.cs to specific directory (just a matter of ordering) + Mark some properties and methods in watchlist as obsolete + Create Comparer class that are used for sorting (Only domain and address atm, other a still stored with linq). Unlike OrderBy in LINQ, it doesn't create a new list for sorting (so it saves memory), furthermore, it runs faster. Finally, change to type of Watch.Address from nullable lon to regular long (the rare times watch.Address.Value was used, there wasn't any check of null and so, program would have crashed - InvalidOperationException -)
This commit is contained in:
parent
ef563a77e0
commit
32271899c3
|
@ -239,7 +239,9 @@
|
|||
<Compile Include="tools\RamSearchEngine.cs" />
|
||||
<Compile Include="tools\Watch\SeparatorWatch.cs" />
|
||||
<Compile Include="tools\Watch\Watch.cs" />
|
||||
<Compile Include="tools\Watch\WatchList.cs" />
|
||||
<Compile Include="tools\Watch\WatchList\WatchDomainComparer.cs" />
|
||||
<Compile Include="tools\Watch\WatchList\WatchAddressComparer.cs" />
|
||||
<Compile Include="tools\Watch\WatchList\WatchList.cs" />
|
||||
<Compile Include="tools\Watch\WatchSize.cs" />
|
||||
<Compile Include="tools\Watch\WordWatch.cs" />
|
||||
<Compile Include="XmlGame.cs" />
|
||||
|
|
|
@ -248,12 +248,12 @@ namespace BizHawk.Client.Common
|
|||
case WatchSize.Separator:
|
||||
return false;
|
||||
case WatchSize.Byte:
|
||||
return (_watch.Address ?? 0) == addr;
|
||||
return _watch.Address == addr;
|
||||
case WatchSize.Word:
|
||||
return (addr == (_watch.Address ?? 0)) || (addr == (_watch.Address ?? 0) + 1);
|
||||
return (addr == _watch.Address) || (addr == (_watch.Address) + 1);
|
||||
case WatchSize.DWord:
|
||||
return (addr == (_watch.Address ?? 0)) || (addr == (_watch.Address ?? 0) + 1) ||
|
||||
(addr == (_watch.Address ?? 0) + 2) || (addr == (_watch.Address ?? 0) + 3);
|
||||
return (addr == (_watch.Address)) || (addr == (_watch.Address) + 1) ||
|
||||
(addr == (_watch.Address) + 2) || (addr == (_watch.Address) + 3);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,22 +271,22 @@ namespace BizHawk.Client.Common
|
|||
case WatchSize.Byte:
|
||||
return (byte?)_val;
|
||||
case WatchSize.Word:
|
||||
if (addr == (_watch.Address ?? 0))
|
||||
if (addr == (_watch.Address))
|
||||
{
|
||||
return (byte)(_val >> 8);
|
||||
}
|
||||
|
||||
return (byte)(_val & 0xFF);
|
||||
case WatchSize.DWord:
|
||||
if (addr == (_watch.Address ?? 0))
|
||||
if (addr == (_watch.Address))
|
||||
{
|
||||
return (byte)((_val >> 24) & 0xFF);
|
||||
}
|
||||
else if (addr == (_watch.Address ?? 0) + 1)
|
||||
else if (addr == (_watch.Address) + 1)
|
||||
{
|
||||
return (byte)((_val >> 16) & 0xFF);
|
||||
}
|
||||
else if (addr == ((_watch.Address ?? 0)) + 2)
|
||||
else if (addr == ((_watch.Address)) + 2)
|
||||
{
|
||||
return (byte)((_val >> 8) & 0xFF);
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ namespace BizHawk.Client.Common
|
|||
_history.AddState(_watchList);
|
||||
}
|
||||
|
||||
var addresses = watches.Select(x => x.Address ?? 0);
|
||||
var addresses = watches.Select(x => x.Address);
|
||||
var removeList = _watchList.Where(x => !addresses.Contains(x.Address)).ToList();
|
||||
}
|
||||
|
||||
|
|
|
@ -80,136 +80,6 @@ namespace BizHawk.Client.Common
|
|||
_previous = GetByte();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the Watch (read it from <see cref="MemoryDomain"/>
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
switch (Global.Config.RamWatchDefinePrevious)
|
||||
{
|
||||
case PreviousType.Original:
|
||||
return;
|
||||
case PreviousType.LastChange:
|
||||
var temp = _value;
|
||||
_value = GetByte();
|
||||
if (_value != temp)
|
||||
{
|
||||
_previous = _value;
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
case PreviousType.LastFrame:
|
||||
_previous = _value;
|
||||
_value = GetByte();
|
||||
if (_value != Previous)
|
||||
{
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
//TODO: Implements IFormattable
|
||||
public string FormatValue(byte val)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
default:
|
||||
case DisplayType.Unsigned:
|
||||
return val.ToString();
|
||||
case DisplayType.Signed:
|
||||
return ((sbyte)val).ToString();
|
||||
case DisplayType.Hex:
|
||||
return val.ToHexString(2);
|
||||
case DisplayType.Binary:
|
||||
return Convert.ToString(val, 2).PadLeft(8, '0').Insert(4, " ");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/*public override string ToString()
|
||||
{
|
||||
return Notes + ": " + ValueString;
|
||||
}*/
|
||||
|
||||
#region Properties
|
||||
|
||||
#region Implements
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of difference
|
||||
/// between current value and the previous one
|
||||
/// </summary>
|
||||
public override string Diff
|
||||
{
|
||||
get
|
||||
{
|
||||
string diff = string.Empty;
|
||||
byte diffVal = Convert.ToByte(_value - _previous);
|
||||
if (diffVal > 0)
|
||||
{
|
||||
diff = "+";
|
||||
}
|
||||
else if (diffVal < 0)
|
||||
{
|
||||
diff = "-";
|
||||
}
|
||||
|
||||
return string.Format("{0}{1}", diff, FormatValue(diffVal));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the maximum possible value
|
||||
/// </summary>
|
||||
public override uint MaxValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return byte.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current value
|
||||
/// </summary>
|
||||
public override int Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetByte();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current value
|
||||
/// but with stuff I don't understand
|
||||
/// </summary>
|
||||
/// <remarks>zero 15-nov-2015 - bypass LIAR LOGIC, see fdc9ea2aa922876d20ba897fb76909bf75fa6c92 https://github.com/TASVideos/BizHawk/issues/326 </remarks>
|
||||
public override int ValueNoFreeze
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetByte(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of the current value
|
||||
/// </summary>
|
||||
public override string ValueString
|
||||
{
|
||||
get
|
||||
{
|
||||
return FormatValue(_value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to sets the value into the <see cref="MemoryDomain"/>
|
||||
/// at the current <see cref="Watch"/> address
|
||||
|
@ -290,6 +160,131 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the Watch (read it from <see cref="MemoryDomain"/>
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
switch (Global.Config.RamWatchDefinePrevious)
|
||||
{
|
||||
case PreviousType.Original:
|
||||
return;
|
||||
case PreviousType.LastChange:
|
||||
var temp = _value;
|
||||
_value = GetByte();
|
||||
if (_value != temp)
|
||||
{
|
||||
_previous = _value;
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
case PreviousType.LastFrame:
|
||||
_previous = _value;
|
||||
_value = GetByte();
|
||||
if (_value != Previous)
|
||||
{
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Implements
|
||||
|
||||
//TODO: Implements IFormattable
|
||||
public string FormatValue(byte val)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
default:
|
||||
case DisplayType.Unsigned:
|
||||
return val.ToString();
|
||||
case DisplayType.Signed:
|
||||
return ((sbyte)val).ToString();
|
||||
case DisplayType.Hex:
|
||||
return val.ToHexString(2);
|
||||
case DisplayType.Binary:
|
||||
return Convert.ToString(val, 2).PadLeft(8, '0').Insert(4, " ");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
#region Implements
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of difference
|
||||
/// between current value and the previous one
|
||||
/// </summary>
|
||||
public override string Diff
|
||||
{
|
||||
get
|
||||
{
|
||||
string diff = string.Empty;
|
||||
byte diffVal = Convert.ToByte(_value - _previous);
|
||||
if (diffVal > 0)
|
||||
{
|
||||
diff = "+";
|
||||
}
|
||||
else if (diffVal < 0)
|
||||
{
|
||||
diff = "-";
|
||||
}
|
||||
|
||||
return string.Format("{0}{1}", diff, FormatValue(diffVal));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the maximum possible value
|
||||
/// </summary>
|
||||
public override uint MaxValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return byte.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current value
|
||||
/// </summary>
|
||||
public override int Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetByte();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current value
|
||||
/// but with stuff I don't understand
|
||||
/// </summary>
|
||||
/// <remarks>zero 15-nov-2015 - bypass LIAR LOGIC, see fdc9ea2aa922876d20ba897fb76909bf75fa6c92 https://github.com/TASVideos/BizHawk/issues/326 </remarks>
|
||||
public override int ValueNoFreeze
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetByte(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of the current value
|
||||
/// </summary>
|
||||
public override string ValueString
|
||||
{
|
||||
get
|
||||
{
|
||||
return FormatValue(_value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the previous value
|
||||
/// </summary>
|
||||
|
@ -314,6 +309,6 @@ namespace BizHawk.Client.Common
|
|||
|
||||
#endregion Implements
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,9 @@ using System.Text;
|
|||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// This class holds a double word (32 bits) <see cref="Watch"/>
|
||||
/// </summary>
|
||||
public sealed class DWordWatch : Watch
|
||||
{
|
||||
#region Fields
|
||||
|
@ -20,6 +23,18 @@ namespace BizHawk.Client.Common
|
|||
|
||||
#region cTor(s)
|
||||
|
||||
/// <summary>
|
||||
/// Inialize a new instance of <see cref="DWordWatch"/>
|
||||
/// </summary>
|
||||
/// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param>
|
||||
/// <param name="address">The address you want to track</param>
|
||||
/// <param name="type">How you you want to display the value See <see cref="DisplayType"/></param>
|
||||
/// <param name="bigEndian">Specify the endianess. true for big endian</param>
|
||||
/// <param name="note">A custom note about the <see cref="Watch"/></param>
|
||||
/// <param name="value">Current value</param>
|
||||
/// <param name="previous">Previous value</param>
|
||||
/// <param name="changeCount">How many times value has changed</param>
|
||||
/// <exception cref="ArgumentException">Occurs when a <see cref="DisplayType"/> is incompatible with <see cref="WatchSize.DWord"/></exception>
|
||||
internal DWordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note, uint value, uint previous, int changeCount)
|
||||
: base(domain, address, WatchSize.DWord, type, bigEndian, note)
|
||||
{
|
||||
|
@ -28,15 +43,13 @@ namespace BizHawk.Client.Common
|
|||
this._changecount = changeCount;
|
||||
}
|
||||
|
||||
internal DWordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note)
|
||||
:this(domain, address, type, bigEndian, note, 0, 0, 0)
|
||||
{
|
||||
_previous = GetDWord();
|
||||
_value = GetDWord();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Enumerate wich <see cref="DisplayType"/> are valid for a <see cref="DWordWatch"/>
|
||||
/// </summary>
|
||||
public static IEnumerable<DisplayType> ValidTypes
|
||||
{
|
||||
get
|
||||
|
@ -51,80 +64,31 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
#region Implements
|
||||
|
||||
/// <summary>
|
||||
/// Get a list a <see cref="DisplayType"/> that can be used for this <see cref="DWordWatch"/>
|
||||
/// </summary>
|
||||
/// <returns>An enumartion that contains all valid <see cref="DisplayType"/></returns>
|
||||
public override IEnumerable<DisplayType> AvailableTypes()
|
||||
{
|
||||
yield return DisplayType.Unsigned;
|
||||
yield return DisplayType.Signed;
|
||||
yield return DisplayType.Hex;
|
||||
yield return DisplayType.Binary;
|
||||
yield return DisplayType.FixedPoint_20_12;
|
||||
yield return DisplayType.FixedPoint_16_16;
|
||||
yield return DisplayType.Float;
|
||||
}
|
||||
|
||||
public override int Value
|
||||
{
|
||||
get { return (int)GetDWord(); }
|
||||
}
|
||||
|
||||
public override int ValueNoFreeze
|
||||
{
|
||||
get { return (int)GetDWord(true); }
|
||||
}
|
||||
|
||||
public override int Previous
|
||||
{
|
||||
get { return (int)_previous; }
|
||||
}
|
||||
|
||||
public override string PreviousStr
|
||||
{
|
||||
get { return FormatValue(_previous); }
|
||||
return ValidTypes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset the previous value; set it to the current one
|
||||
/// </summary>
|
||||
public override void ResetPrevious()
|
||||
{
|
||||
_previous = GetWord();
|
||||
}
|
||||
|
||||
public override uint MaxValue
|
||||
{
|
||||
get { return uint.MaxValue; }
|
||||
}
|
||||
|
||||
public override string ValueString
|
||||
{
|
||||
get { return FormatValue(GetDWord()); }
|
||||
}
|
||||
|
||||
/*public override string ToString()
|
||||
{
|
||||
return Notes + ": " + ValueString;
|
||||
}*/
|
||||
|
||||
public string FormatValue(uint val)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
default:
|
||||
case DisplayType.Unsigned:
|
||||
return val.ToString();
|
||||
case DisplayType.Signed:
|
||||
return ((int)val).ToString();
|
||||
case DisplayType.Hex:
|
||||
return val.ToHexString(8);
|
||||
case DisplayType.FixedPoint_20_12:
|
||||
return string.Format("{0:0.######}", val / 4096.0);
|
||||
case DisplayType.FixedPoint_16_16:
|
||||
return string.Format("{0:0.######}", val / 65536.0);
|
||||
case DisplayType.Float:
|
||||
var bytes = BitConverter.GetBytes(val);
|
||||
var _float = BitConverter.ToSingle(bytes, 0);
|
||||
//return string.Format("{0:0.######}", _float);
|
||||
return _float.ToString(); // adelikat: decided that we like sci notation instead of spooky rounding
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to sets the value into the <see cref="MemoryDomain"/>
|
||||
/// at the current <see cref="Watch"/> address
|
||||
/// </summary>
|
||||
/// <param name="value">Value to set</param>
|
||||
/// <returns>True if value successfully sets; othewise, false</returns>
|
||||
public override bool Poke(string value)
|
||||
{
|
||||
try
|
||||
|
@ -221,11 +185,9 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
public override string Diff
|
||||
{
|
||||
get { return FormatValue(_previous - _value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the Watch (read it from <see cref="MemoryDomain"/>
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
switch (Global.Config.RamWatchDefinePrevious)
|
||||
|
@ -253,5 +215,120 @@ namespace BizHawk.Client.Common
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Implements
|
||||
|
||||
//TODO: Implements IFormattable
|
||||
public string FormatValue(uint val)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
default:
|
||||
case DisplayType.Unsigned:
|
||||
return val.ToString();
|
||||
case DisplayType.Signed:
|
||||
return ((int)val).ToString();
|
||||
case DisplayType.Hex:
|
||||
return val.ToHexString(8);
|
||||
case DisplayType.FixedPoint_20_12:
|
||||
return string.Format("{0:0.######}", val / 4096.0);
|
||||
case DisplayType.FixedPoint_16_16:
|
||||
return string.Format("{0:0.######}", val / 65536.0);
|
||||
case DisplayType.Float:
|
||||
var bytes = BitConverter.GetBytes(val);
|
||||
var _float = BitConverter.ToSingle(bytes, 0);
|
||||
//return string.Format("{0:0.######}", _float);
|
||||
return _float.ToString(); // adelikat: decided that we like sci notation instead of spooky rounding
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
#region Implements
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of difference
|
||||
/// between current value and the previous one
|
||||
/// </summary>
|
||||
public override string Diff
|
||||
{
|
||||
get
|
||||
{
|
||||
return FormatValue(_previous - _value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the maximum possible value
|
||||
/// </summary>
|
||||
public override uint MaxValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return uint.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current value
|
||||
/// </summary>
|
||||
public override int Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)GetDWord();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current value
|
||||
/// but with stuff I don't understand
|
||||
/// </summary>
|
||||
public override int ValueNoFreeze
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)GetDWord(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of the current value
|
||||
/// </summary>
|
||||
public override string ValueString
|
||||
{
|
||||
get
|
||||
{
|
||||
return FormatValue(GetDWord());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the previous value
|
||||
/// </summary>
|
||||
public override int Previous
|
||||
{
|
||||
get
|
||||
{
|
||||
return (int)_previous;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of the previous value
|
||||
/// </summary>
|
||||
public override string PreviousStr
|
||||
{
|
||||
get
|
||||
{
|
||||
return FormatValue(_previous);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Implements
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,69 +3,117 @@ using System.Collections.Generic;
|
|||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// This class holds a separator for RamWatch
|
||||
/// Use the static property Instance to get it
|
||||
/// </summary>
|
||||
public sealed class SeparatorWatch : Watch
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize a new separator instance
|
||||
/// </summary>
|
||||
internal SeparatorWatch()
|
||||
:base(null, 0, WatchSize.Separator, DisplayType.Separator, true, string.Empty)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the separator instance
|
||||
/// </summary>
|
||||
public static SeparatorWatch Instance
|
||||
{
|
||||
get { return new SeparatorWatch(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the appropriate DisplayType
|
||||
/// </summary>
|
||||
/// <returns>DisplayType.Separator nothing else</returns>
|
||||
public override IEnumerable<DisplayType> AvailableTypes()
|
||||
{
|
||||
yield return DisplayType.Separator;
|
||||
}
|
||||
|
||||
#region Stuff to ignore
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override int Value
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override int ValueNoFreeze
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override int Previous
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override string ValueString
|
||||
{
|
||||
get { return string.Empty; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override string PreviousStr
|
||||
{
|
||||
get { return string.Empty; }
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "----";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override bool Poke(string value)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override void ResetPrevious()
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override string Diff { get { return string.Empty; } }
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override uint MaxValue
|
||||
{
|
||||
get { return 0; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ignore that stuff
|
||||
/// </summary>
|
||||
public override void Update() { return; }
|
||||
|
||||
public override IEnumerable<DisplayType> AvailableTypes()
|
||||
{
|
||||
yield return DisplayType.Separator;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -327,8 +327,8 @@ namespace BizHawk.Client.Common
|
|||
|
||||
#endregion Abstracts
|
||||
|
||||
#region Protected
|
||||
|
||||
#region Protected
|
||||
|
||||
protected byte GetByte(bool bypassFreeze = false)
|
||||
{
|
||||
if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
|
||||
|
@ -429,10 +429,16 @@ namespace BizHawk.Client.Common
|
|||
/// <returns>True if both object are equals; otherwise, false</returns>
|
||||
public bool Equals(Watch other)
|
||||
{
|
||||
return !object.ReferenceEquals(other, null) &&
|
||||
this._domain == other._domain &&
|
||||
this._address == other._address &&
|
||||
this._size == other._size;
|
||||
if (object.ReferenceEquals(other, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return this._domain == other._domain &&
|
||||
this._address == other._address &&
|
||||
this._size == other._size;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion IEquatable<Watch>
|
||||
|
@ -478,7 +484,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return 1;
|
||||
}
|
||||
else if (_address.Equals(other._address))
|
||||
else if (_address.Equals(other._address))
|
||||
{
|
||||
return ((int)_size).CompareTo((int)other._size);
|
||||
}
|
||||
|
@ -518,7 +524,7 @@ namespace BizHawk.Client.Common
|
|||
/// <returns>int that can serves as a unique representation of current Watch</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.Domain.GetHashCode() + (int)(this.Address ?? 0);
|
||||
return this.Domain.GetHashCode() + (int)(this.Address);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -539,7 +545,7 @@ namespace BizHawk.Client.Common
|
|||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}"
|
||||
, (Address ?? 0).ToHexString((Domain.Size - 1).NumHexDigits())
|
||||
, Address.ToHexString((Domain.Size - 1).NumHexDigits())
|
||||
, SizeAsChar
|
||||
, TypeAsChar
|
||||
, Convert.ToInt32(BigEndian)
|
||||
|
@ -605,7 +611,7 @@ namespace BizHawk.Client.Common
|
|||
/// <summary>
|
||||
/// Gets the address in the <see cref="MemoryDomain"/>
|
||||
/// </summary>
|
||||
public long? Address
|
||||
public long Address
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -699,9 +705,16 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return _domain;
|
||||
}
|
||||
set
|
||||
internal set
|
||||
{
|
||||
_domain = value;
|
||||
if (_domain.Name == value.Name)
|
||||
{
|
||||
_domain = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("You cannot set diffrent domain to a watch on the fly");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -719,7 +732,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// This class hold a collection <see cref="Watch"/>
|
||||
/// Different memory domain can be mixed
|
||||
/// </summary>
|
||||
public sealed partial class WatchList
|
||||
{
|
||||
/// <summary>
|
||||
/// Netsed private class that define how to compare two <see cref="Watch"/>
|
||||
/// based on their address
|
||||
/// </summary>
|
||||
private struct WatchAddressComparer
|
||||
: IEqualityComparer<Watch>,
|
||||
IComparer<Watch>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compare two <see cref="Watch"/> between them
|
||||
/// and determine wich one comes first.
|
||||
/// If they are equals, comapraison will done one the domain and next on size
|
||||
/// </summary>
|
||||
/// <param name="x">First <see cref="Watch"/></param>
|
||||
/// <returns>True if <see cref="Watch"/> are equal; otherwise, false</returns>
|
||||
/// <returns></returns>
|
||||
public int Compare(Watch x, Watch y)
|
||||
{
|
||||
if (Equals(x, y))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (x.Address.Equals(y.Address))
|
||||
{
|
||||
if (x.Domain.Name.Equals(y.Domain.Name))
|
||||
{
|
||||
return x.Size.CompareTo(y.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return x.Domain.Name.CompareTo(y.Domain.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return x.Address.CompareTo(y.Address);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if two <see cref="Watch"/> are equals
|
||||
/// </summary>
|
||||
/// <param name="x">First <see cref="Watch"/></param>
|
||||
/// <param name="y">Second <see cref="Watch"/></param>
|
||||
/// <returns>True if <see cref="Watch"/> are equal; otherwise, false</returns>
|
||||
public bool Equals(Watch x, Watch y)
|
||||
{
|
||||
if (object.ReferenceEquals(x, null))
|
||||
{
|
||||
if (object.ReferenceEquals(y, null))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (object.ReferenceEquals(y, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (object.ReferenceEquals(x, y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return x.Address.Equals(y.Address);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the hash value of specified <see cref="Watch"/>
|
||||
/// </summary>
|
||||
/// <param name="obj">Watch to get hash</param>
|
||||
/// <returns>int that can serves as a unique representation of current Watch</returns>
|
||||
public int GetHashCode(Watch obj)
|
||||
{
|
||||
return obj.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// This class hold a collection <see cref="Watch"/>
|
||||
/// Different memory domain can be mixed
|
||||
/// </summary>
|
||||
public sealed partial class WatchList
|
||||
{
|
||||
/// <summary>
|
||||
/// Netsed private class that define how to compare two <see cref="Watch"/>
|
||||
/// based on their domain
|
||||
/// </summary>
|
||||
private struct WatchDomainComparer
|
||||
: IEqualityComparer<Watch>,
|
||||
IComparer<Watch>
|
||||
{
|
||||
/// <summary>
|
||||
/// Compare two <see cref="Watch"/> between them
|
||||
/// and determine wich one comes first.
|
||||
/// If they are equals, comapraison will done one the address and next on size
|
||||
/// </summary>
|
||||
/// <param name="x">First <see cref="Watch"/></param>
|
||||
/// <returns>True if <see cref="Watch"/> are equal; otherwise, false</returns>
|
||||
/// <returns></returns>
|
||||
public int Compare(Watch x, Watch y)
|
||||
{
|
||||
if(Equals(x, y))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if(x.Domain.Name.Equals(y.Domain.Name))
|
||||
{
|
||||
if (x.Address.Equals(y.Address))
|
||||
{
|
||||
return x.Size.CompareTo(y.Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
return x.Address.CompareTo(y.Address);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return x.Domain.Name.CompareTo(y.Domain.Name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine if two <see cref="Watch"/> are equals
|
||||
/// </summary>
|
||||
/// <param name="x">First <see cref="Watch"/></param>
|
||||
/// <param name="y">Second <see cref="Watch"/></param>
|
||||
/// <returns>True if <see cref="Watch"/> are equal; otherwise, false</returns>
|
||||
public bool Equals(Watch x, Watch y)
|
||||
{
|
||||
if(object.ReferenceEquals(x, null))
|
||||
{
|
||||
if(object.ReferenceEquals(y, null))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(object.ReferenceEquals(y, null))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if(object.ReferenceEquals(x,y))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return x.Domain.Name.Equals(y.Domain.Name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the hash value of specified <see cref="Watch"/>
|
||||
/// </summary>
|
||||
/// <param name="obj">Watch to get hash</param>
|
||||
/// <returns>int that can serves as a unique representation of current Watch</returns>
|
||||
public int GetHashCode(Watch obj)
|
||||
{
|
||||
return obj.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +1,27 @@
|
|||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
public class WatchList : IList<Watch>
|
||||
/// <summary>
|
||||
/// This class hold a collection <see cref="Watch"/>
|
||||
/// Different memory domain can be mixed
|
||||
/// </summary>
|
||||
public sealed partial class WatchList
|
||||
: IList<Watch>
|
||||
{
|
||||
private IMemoryDomains _memoryDomains;
|
||||
private List<Watch> _watchList = new List<Watch>();
|
||||
private MemoryDomain _domain;
|
||||
private string _currentFilename = string.Empty;
|
||||
private string _systemid;
|
||||
#region Fields
|
||||
|
||||
public const string ADDRESS = "AddressColumn";
|
||||
public const string VALUE = "ValueColumn";
|
||||
|
@ -27,14 +31,62 @@ namespace BizHawk.Client.Common
|
|||
public const string DOMAIN = "DomainColumn";
|
||||
public const string NOTES = "NotesColumn";
|
||||
|
||||
private static readonly WatchDomainComparer domainComparer = new WatchDomainComparer();
|
||||
private static readonly WatchAddressComparer addressComparer = new WatchAddressComparer();
|
||||
|
||||
private static IMemoryDomains _memoryDomains;
|
||||
|
||||
private List<Watch> _watchList = new List<Watch>(0);
|
||||
private MemoryDomain _domain;
|
||||
private string _currentFilename = string.Empty;
|
||||
private string _systemid;
|
||||
|
||||
#endregion
|
||||
|
||||
#region cTor(s)
|
||||
|
||||
/// <summary>
|
||||
/// Initialize a new instance of <see cref="WatchList"/> that will
|
||||
/// contains a set of <see cref="Watch"/>
|
||||
/// </summary>
|
||||
/// <param name="core">All available memomry domains</param>
|
||||
/// <param name="domain">Domain you want to watch</param>
|
||||
/// <param name="systemid">System identifier (NES, SNES, ...)</param>
|
||||
[Obsolete("Use the constructor with two parameters instead")]
|
||||
public WatchList(IMemoryDomains core, MemoryDomain domain, string systemid)
|
||||
{
|
||||
_memoryDomains = core;
|
||||
if (_memoryDomains == null)
|
||||
{
|
||||
_memoryDomains = core;
|
||||
}
|
||||
_domain = domain;
|
||||
_systemid = systemid;
|
||||
}
|
||||
|
||||
public void RefreshDomans(IMemoryDomains core, MemoryDomain domain)
|
||||
/// <summary>
|
||||
/// Initialize a new instance of <see cref="WatchList"/> that will
|
||||
/// contains a set of <see cref="Watch"/>
|
||||
/// </summary>
|
||||
/// <param name="core">All available memomry domains</param>
|
||||
/// <param name="domain">Domain you want to watch</param>
|
||||
/// <param name="systemid">System identifier (NES, SNES, ...)</param>
|
||||
public WatchList(IMemoryDomains core, string systemid)
|
||||
{
|
||||
if (_memoryDomains == null)
|
||||
{
|
||||
_memoryDomains = core;
|
||||
}
|
||||
//TODO: Remove this after tests
|
||||
_domain = core.MainMemory;
|
||||
_systemid = systemid;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
[Obsolete("Use the method with single parameter instead")]
|
||||
public void RefreshDomains(IMemoryDomains core, MemoryDomain domain)
|
||||
{
|
||||
_memoryDomains = core;
|
||||
_domain = domain;
|
||||
|
@ -47,8 +99,21 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public enum WatchPrevDef { LastSearch, Original, LastFrame, LastChange }
|
||||
|
||||
public void RefreshDomains(IMemoryDomains core)
|
||||
{
|
||||
_memoryDomains = core;
|
||||
Parallel.ForEach<Watch>(_watchList, watch =>
|
||||
{
|
||||
watch.Domain = core[watch.Domain.Name];
|
||||
watch.ResetPrevious();
|
||||
watch.Update();
|
||||
watch.ClearChangeCount();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public string AddressFormatStr // TODO: this is probably compensating for not using the ToHex string extension
|
||||
{
|
||||
|
@ -65,19 +130,30 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public int Count
|
||||
{
|
||||
get { return _watchList.Count; }
|
||||
get
|
||||
{
|
||||
return _watchList.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public int WatchCount
|
||||
{
|
||||
get { return _watchList.Count(w => !w.IsSeparator); }
|
||||
get
|
||||
{
|
||||
return _watchList.Count<Watch>(watch => !watch.IsSeparator);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use count property instead")]
|
||||
public int ItemCount
|
||||
{
|
||||
get { return _watchList.Count; }
|
||||
get
|
||||
{
|
||||
return Count;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("Use domain from individual watch instead")]
|
||||
public MemoryDomain Domain
|
||||
{
|
||||
get { return _domain; }
|
||||
|
@ -117,23 +193,12 @@ namespace BizHawk.Client.Common
|
|||
case ADDRESS:
|
||||
if (reverse)
|
||||
{
|
||||
_watchList = _watchList
|
||||
.OrderByDescending(x => x.Address)
|
||||
.ThenBy(x => x.Domain.Name)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ThenBy(x => x.BigEndian)
|
||||
.ToList();
|
||||
_watchList.Sort(addressComparer);
|
||||
_watchList.Reverse();
|
||||
}
|
||||
else
|
||||
{
|
||||
_watchList = _watchList
|
||||
.OrderBy(x => x.Address)
|
||||
.ThenBy(x => x.Domain.Name)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ThenBy(x => x.BigEndian)
|
||||
.ToList();
|
||||
_watchList.Sort();
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -165,7 +230,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList
|
||||
.OrderByDescending(x => x.PreviousStr)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Address)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
|
@ -174,7 +239,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList
|
||||
.OrderBy(x => x.PreviousStr)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Address)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
|
@ -186,7 +251,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList
|
||||
.OrderByDescending(x => x.Diff)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Address)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
|
@ -195,7 +260,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList
|
||||
.OrderBy(x => x.Diff)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Address)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
|
@ -207,7 +272,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList
|
||||
.OrderByDescending(x => x.ChangeCount)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Address)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
|
@ -216,7 +281,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList
|
||||
.OrderBy(x => x.ChangeCount)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Address)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
|
@ -226,23 +291,12 @@ namespace BizHawk.Client.Common
|
|||
case DOMAIN:
|
||||
if (reverse)
|
||||
{
|
||||
_watchList = _watchList
|
||||
.OrderByDescending(x => x.Domain)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ThenBy(x => x.BigEndian)
|
||||
.ToList();
|
||||
_watchList.Sort(domainComparer);
|
||||
_watchList.Reverse();
|
||||
}
|
||||
else
|
||||
{
|
||||
_watchList = _watchList
|
||||
.OrderBy(x => x.Domain)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ThenBy(x => x.BigEndian)
|
||||
.ToList();
|
||||
_watchList.Sort(domainComparer);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -251,7 +305,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList
|
||||
.OrderByDescending(x => x.Notes)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Address)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
|
@ -260,7 +314,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList
|
||||
.OrderBy(x => x.Notes)
|
||||
.ThenBy(x => x.Address ?? 0)
|
||||
.ThenBy(x => x.Address)
|
||||
.ThenBy(x => x.Size)
|
||||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
|
@ -279,11 +333,11 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void UpdateValues()
|
||||
{
|
||||
foreach (var watch in _watchList)
|
||||
Parallel.ForEach<Watch>(_watchList, watch =>
|
||||
{
|
||||
watch.Update();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Add(Watch watch)
|
||||
{
|
||||
|
@ -412,7 +466,7 @@ namespace BizHawk.Client.Common
|
|||
CurrentFileName = file.FullName;
|
||||
return Save();
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -476,7 +530,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
isOldBizHawkWatch = true; // This supports the legacy .wch format from 1.0.5 and earlier
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
continue; // If not 4, something is wrong with this line, ignore it
|
||||
}
|
||||
|
@ -532,9 +586,9 @@ namespace BizHawk.Client.Common
|
|||
memDomain,
|
||||
addr,
|
||||
size,
|
||||
type,
|
||||
type,
|
||||
bigEndian,
|
||||
notes));
|
||||
notes));
|
||||
_domain = _memoryDomains[domain];
|
||||
}
|
||||
|
|
@ -1,13 +1,17 @@
|
|||
using BizHawk.Common.NumberExtensions;
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
using BizHawk.Common.StringExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// This class holds a word (16 bits) <see cref="Watch"/>
|
||||
/// </summary>
|
||||
public sealed class WordWatch : Watch
|
||||
{
|
||||
#region Fields
|
||||
|
@ -19,6 +23,18 @@ namespace BizHawk.Client.Common
|
|||
|
||||
#region cTor(s)
|
||||
|
||||
/// <summary>
|
||||
/// Inialize a new instance of <see cref="WordWatch"/>
|
||||
/// </summary>
|
||||
/// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param>
|
||||
/// <param name="address">The address you want to track</param>
|
||||
/// <param name="type">How you you want to display the value See <see cref="DisplayType"/></param>
|
||||
/// <param name="bigEndian">Specify the endianess. true for big endian</param>
|
||||
/// <param name="note">A custom note about the <see cref="Watch"/></param>
|
||||
/// <param name="value">Current value</param>
|
||||
/// <param name="previous">Previous value</param>
|
||||
/// <param name="changeCount">How many times value has changed</param>
|
||||
/// <exception cref="ArgumentException">Occurs when a <see cref="DisplayType"/> is incompatible with <see cref="WatchSize.Word"/></exception>
|
||||
internal WordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note, ushort value, ushort previous, int changeCount)
|
||||
: base(domain, address, WatchSize.Word, type, bigEndian, note)
|
||||
{
|
||||
|
@ -27,15 +43,13 @@ namespace BizHawk.Client.Common
|
|||
this._changecount = changeCount;
|
||||
}
|
||||
|
||||
internal WordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note)
|
||||
:this(domain, address, type, bigEndian, note, 0, 0, 0)
|
||||
{
|
||||
_previous = GetWord();
|
||||
_value = GetWord();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
|
||||
/// <summary>
|
||||
/// Enumerate wich <see cref="DisplayType"/> are valid for a <see cref="WordWatch"/>
|
||||
/// </summary>
|
||||
public static IEnumerable<DisplayType> ValidTypes
|
||||
{
|
||||
get
|
||||
|
@ -48,73 +62,31 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
#region Implements
|
||||
|
||||
/// <summary>
|
||||
/// Get a list a <see cref="DisplayType"/> that can be used for this <see cref="WordWatch"/>
|
||||
/// </summary>
|
||||
/// <returns>An enumartion that contains all valid <see cref="DisplayType"/></returns>
|
||||
public override IEnumerable<DisplayType> AvailableTypes()
|
||||
{
|
||||
yield return DisplayType.Unsigned;
|
||||
yield return DisplayType.Signed;
|
||||
yield return DisplayType.Hex;
|
||||
yield return DisplayType.Binary;
|
||||
yield return DisplayType.FixedPoint_12_4;
|
||||
}
|
||||
|
||||
public override uint MaxValue
|
||||
{
|
||||
get { return ushort.MaxValue; }
|
||||
}
|
||||
|
||||
public override int Value
|
||||
{
|
||||
get { return GetWord(); }
|
||||
}
|
||||
|
||||
public override int ValueNoFreeze
|
||||
{
|
||||
get { return GetWord(true); }
|
||||
}
|
||||
|
||||
public override int Previous
|
||||
{
|
||||
get { return _previous; }
|
||||
}
|
||||
|
||||
public override string PreviousStr
|
||||
{
|
||||
get { return FormatValue(_previous); }
|
||||
return ValidTypes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset the previous value; set it to the current one
|
||||
/// </summary>
|
||||
public override void ResetPrevious()
|
||||
{
|
||||
_previous = GetWord();
|
||||
}
|
||||
|
||||
public override string ValueString
|
||||
{
|
||||
get { return FormatValue(GetWord()); }
|
||||
}
|
||||
|
||||
/*public override string ToString()
|
||||
{
|
||||
return Notes + ": " + ValueString;
|
||||
}*/
|
||||
|
||||
public string FormatValue(ushort val)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
default:
|
||||
case DisplayType.Unsigned:
|
||||
return val.ToString();
|
||||
case DisplayType.Signed:
|
||||
return ((short)val).ToString();
|
||||
case DisplayType.Hex:
|
||||
return val.ToHexString(4);
|
||||
case DisplayType.FixedPoint_12_4:
|
||||
return string.Format("{0:F4}", val / 16.0);
|
||||
case DisplayType.Binary:
|
||||
return Convert.ToString(val, 2).PadLeft(16, '0').Insert(8, " ").Insert(4, " ").Insert(14, " ");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to sets the value into the <see cref="MemoryDomain"/>
|
||||
/// at the current <see cref="Watch"/> address
|
||||
/// </summary>
|
||||
/// <param name="value">Value to set</param>
|
||||
/// <returns>True if value successfully sets; othewise, false</returns>
|
||||
public override bool Poke(string value)
|
||||
{
|
||||
try
|
||||
|
@ -199,11 +171,9 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
public override string Diff
|
||||
{
|
||||
get { return FormatValue((ushort)(_previous - _value)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the Watch (read it from <see cref="MemoryDomain"/>
|
||||
/// </summary>
|
||||
public override void Update()
|
||||
{
|
||||
switch (Global.Config.RamWatchDefinePrevious)
|
||||
|
@ -232,5 +202,115 @@ namespace BizHawk.Client.Common
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Implements
|
||||
|
||||
//TODO: Implements IFormattable
|
||||
public string FormatValue(ushort val)
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
default:
|
||||
case DisplayType.Unsigned:
|
||||
return val.ToString();
|
||||
case DisplayType.Signed:
|
||||
return ((short)val).ToString();
|
||||
case DisplayType.Hex:
|
||||
return val.ToHexString(4);
|
||||
case DisplayType.FixedPoint_12_4:
|
||||
return string.Format("{0:F4}", val / 16.0);
|
||||
case DisplayType.Binary:
|
||||
return Convert.ToString(val, 2).PadLeft(16, '0').Insert(8, " ").Insert(4, " ").Insert(14, " ");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
|
||||
#region Implements
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of difference
|
||||
/// between current value and the previous one
|
||||
/// </summary>
|
||||
public override string Diff
|
||||
{
|
||||
get
|
||||
{
|
||||
return FormatValue((ushort)(_previous - _value));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the maximum possible value
|
||||
/// </summary>
|
||||
public override uint MaxValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return ushort.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current value
|
||||
/// </summary>
|
||||
public override int Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetWord();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current value
|
||||
/// but with stuff I don't understand
|
||||
/// </summary>
|
||||
public override int ValueNoFreeze
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetWord(true);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of the current value
|
||||
/// </summary>
|
||||
public override string ValueString
|
||||
{
|
||||
get
|
||||
{
|
||||
return FormatValue(GetWord());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the previous value
|
||||
/// </summary>
|
||||
public override int Previous
|
||||
{
|
||||
get
|
||||
{
|
||||
return _previous;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of the previous value
|
||||
/// </summary>
|
||||
public override string PreviousStr
|
||||
{
|
||||
get
|
||||
{
|
||||
return FormatValue(_previous);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Implements
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,10 +172,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
var nextColor = Color.White;
|
||||
|
||||
var isCheat = Global.CheatList.IsActive(_settings.Domain, _searches[index].Address ?? 0);
|
||||
var isWeeded = Settings.PreviewMode && !_forcePreviewClear && _searches.Preview(_searches[index].Address ?? 0);
|
||||
var isCheat = Global.CheatList.IsActive(_settings.Domain, _searches[index].Address);
|
||||
var isWeeded = Settings.PreviewMode && !_forcePreviewClear && _searches.Preview(_searches[index].Address);
|
||||
|
||||
if (_searches[index].Address.Value >= _searches[index].Domain.Size)
|
||||
if (_searches[index].Address >= _searches[index].Domain.Size)
|
||||
{
|
||||
nextColor = Color.PeachPuff;
|
||||
}
|
||||
|
@ -852,7 +852,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
watches.Load(file.FullName, append);
|
||||
|
||||
var watchList = watches.Where(x => !x.IsSeparator);
|
||||
var addresses = watchList.Select(x => x.Address ?? 0).ToList();
|
||||
var addresses = watchList.Select(x => x.Address).ToList();
|
||||
|
||||
if (truncate)
|
||||
{
|
||||
|
@ -1319,7 +1319,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void FreezeAddressMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var allCheats = SelectedWatches.All(x => Global.CheatList.IsActive(x.Domain, x.Address ?? 0));
|
||||
var allCheats = SelectedWatches.All(x => Global.CheatList.IsActive(x.Domain, x.Address));
|
||||
if (allCheats)
|
||||
{
|
||||
SelectedWatches.UnfreezeAll();
|
||||
|
@ -1463,7 +1463,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
var allCheats = true;
|
||||
foreach (var index in SelectedIndices)
|
||||
{
|
||||
if (!Global.CheatList.IsActive(_settings.Domain, _searches[index].Address ?? 0))
|
||||
if (!Global.CheatList.IsActive(_settings.Domain, _searches[index].Address))
|
||||
{
|
||||
allCheats = false;
|
||||
}
|
||||
|
@ -1490,7 +1490,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (SelectedWatches.Any())
|
||||
{
|
||||
ToolHelpers.ViewInHexEditor(_searches.Domain, SelectedWatches.Select(x => x.Address ?? 0), SelectedSize);
|
||||
ToolHelpers.ViewInHexEditor(_searches.Domain, SelectedWatches.Select(x => x.Address), SelectedSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (_watches != null && !string.IsNullOrWhiteSpace(_watches.CurrentFileName))
|
||||
{
|
||||
_watches.RefreshDomans(_memoryDomains, _memoryDomains.MainMemory);
|
||||
_watches.RefreshDomains(_memoryDomains, _memoryDomains.MainMemory);
|
||||
_watches.Reload();
|
||||
SetPlatformAndMemoryDomainLabel();
|
||||
UpdateStatusBar();
|
||||
|
@ -251,7 +251,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
for (var i = 0; i < _watches.Count; i++)
|
||||
{
|
||||
var frozen = !_watches[i].IsSeparator && Global.CheatList.IsActive(_watches[i].Domain, _watches[i].Address ?? 0);
|
||||
var frozen = !_watches[i].IsSeparator && Global.CheatList.IsActive(_watches[i].Domain, _watches[i].Address);
|
||||
GlobalWin.OSD.AddGUIText(
|
||||
_watches[i].ToString(),
|
||||
Global.Config.DispRamWatchx,
|
||||
|
@ -286,7 +286,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
return true;
|
||||
}
|
||||
|
||||
if (Global.CheatList.IsActive(_watches.Domain, watch.Address ?? 0))
|
||||
if (Global.CheatList.IsActive(_watches.Domain, watch.Address))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
for (var i = 0; i < _watches.Count; i++)
|
||||
{
|
||||
var frozen = !_watches[i].IsSeparator && Global.CheatList.IsActive(_watches[i].Domain, _watches[i].Address ?? 0);
|
||||
var frozen = !_watches[i].IsSeparator && Global.CheatList.IsActive(_watches[i].Domain, _watches[i].Address);
|
||||
GlobalWin.OSD.AddGUIText(
|
||||
_watches[i].ToString(),
|
||||
Global.Config.DispRamWatchx,
|
||||
|
@ -585,7 +585,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
ErrorIconButton.Visible = _watches.Where(watch => !watch.IsSeparator).Any(watch => (watch.Address ?? 0) >= watch.Domain.Size);
|
||||
ErrorIconButton.Visible = _watches.Where(watch => !watch.IsSeparator).Any(watch => (watch.Address) >= watch.Domain.Size);
|
||||
|
||||
MessageLabel.Text = message;
|
||||
}
|
||||
|
@ -608,11 +608,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
color = BackColor;
|
||||
}
|
||||
else if (_watches[index].Address.Value >= _watches[index].Domain.Size)
|
||||
else if (_watches[index].Address >= _watches[index].Domain.Size)
|
||||
{
|
||||
color = Color.PeachPuff;
|
||||
}
|
||||
else if (Global.CheatList.IsActive(_watches.Domain, _watches[index].Address ?? 0))
|
||||
else if (Global.CheatList.IsActive(_watches.Domain, _watches[index].Address))
|
||||
{
|
||||
color = Color.LightCyan;
|
||||
}
|
||||
|
@ -813,7 +813,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void FreezeAddressMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var allCheats = SelectedWatches.All(x => Global.CheatList.IsActive(x.Domain, x.Address ?? 0));
|
||||
var allCheats = SelectedWatches.All(x => Global.CheatList.IsActive(x.Domain, x.Address));
|
||||
if (allCheats)
|
||||
{
|
||||
SelectedWatches.UnfreezeAll();
|
||||
|
@ -1074,7 +1074,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
SelectedIndices.Any() &&
|
||||
SelectedWatches.All(w => w.Domain.CanPoke());
|
||||
|
||||
var allCheats = _watches.All(x => Global.CheatList.IsActive(x.Domain, x.Address ?? 0));
|
||||
var allCheats = _watches.All(x => Global.CheatList.IsActive(x.Domain, x.Address));
|
||||
|
||||
if (allCheats)
|
||||
{
|
||||
|
@ -1108,11 +1108,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (selected.Select(x => x.Domain).Distinct().Count() > 1)
|
||||
{
|
||||
ToolHelpers.ViewInHexEditor(selected[0].Domain, new List<long> { selected.First().Address ?? 0 }, selected.First().Size);
|
||||
ToolHelpers.ViewInHexEditor(selected[0].Domain, new List<long> { selected.First().Address }, selected.First().Size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ToolHelpers.ViewInHexEditor(selected.First().Domain, selected.Select(x => x.Address ?? 0), selected.First().Size);
|
||||
ToolHelpers.ViewInHexEditor(selected.First().Domain, selected.Select(x => x.Address ), selected.First().Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1127,7 +1127,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
foreach (var watch in selected)
|
||||
{
|
||||
debugger.AddBreakpoint((uint)watch.Address.Value, MemoryCallbackType.Read);
|
||||
debugger.AddBreakpoint((uint)watch.Address, MemoryCallbackType.Read);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1142,7 +1142,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
foreach (var watch in selected)
|
||||
{
|
||||
debugger.AddBreakpoint((uint)watch.Address.Value, MemoryCallbackType.Write);
|
||||
debugger.AddBreakpoint((uint)watch.Address, MemoryCallbackType.Write);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1194,7 +1194,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
private void ErrorIconButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
var items = _watches
|
||||
.Where(watch => (watch.Address ?? 0) >= watch.Domain.Size)
|
||||
.Where(watch => (watch.Address) >= watch.Domain.Size)
|
||||
.ToList();
|
||||
|
||||
foreach (var item in items)
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
else
|
||||
{
|
||||
NotesBox.Text = _watchList[0].Notes;
|
||||
AddressBox.SetFromLong(_watchList[0].Address ?? 0);
|
||||
AddressBox.SetFromLong(_watchList[0].Address);
|
||||
}
|
||||
|
||||
SetBigEndianCheckBox();
|
||||
|
@ -267,7 +267,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
_watchList.Add(Watch.GenerateWatch(
|
||||
watch.Domain,
|
||||
watch.Address ?? 0,
|
||||
watch.Address,
|
||||
watch.Size,
|
||||
watch.Type,
|
||||
watch.BigEndian,
|
||||
|
@ -308,7 +308,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
_watchList[i] = Watch.GenerateWatch(
|
||||
_watchList[i].Domain,
|
||||
_watchList.Count == 1 ? AddressBox.ToRawInt() ?? 0 : _watchList[i].Address ?? 0,
|
||||
_watchList.Count == 1 ? AddressBox.ToRawInt() ?? 0 : _watchList[i].Address,
|
||||
size,
|
||||
_watchList[i].Type,
|
||||
_watchList[i].BigEndian,
|
||||
|
|
Loading…
Reference in New Issue