Watch classes - refactor, simplify, and cleanup code

This commit is contained in:
adelikat 2017-05-17 10:46:56 -05:00
parent c2fa9070a3
commit f576cb14b0
14 changed files with 411 additions and 670 deletions

View File

@ -1,286 +1,254 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using BizHawk.Common.NumberExtensions; using BizHawk.Common.NumberExtensions;
using BizHawk.Common.StringExtensions; using BizHawk.Common.StringExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common namespace BizHawk.Client.Common
{ {
/// <summary> /// <summary>
/// This class holds a byte (8 bits) <see cref="Watch"/> /// This class holds a byte (8 bits) <see cref="Watch"/>
/// </summary> /// </summary>
public sealed class ByteWatch : Watch public sealed class ByteWatch : Watch
{ {
#region Fields private byte _previous;
private byte _value;
private byte _previous;
private byte _value; /// <summary>
/// Initializes a new instance of the <see cref="ByteWatch"/> class.
#endregion /// </summary>
/// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param>
#region cTor(s) /// <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>
/// <summary> /// <param name="bigEndian">Specify the endianess. true for big endian</param>
/// Inialize a new instance of <see cref="ByteWatch"/> /// <param name="note">A custom note about the <see cref="Watch"/></param>
/// </summary> /// <param name="value">Current value</param>
/// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param> /// <param name="previous">Previous value</param>
/// <param name="address">The address you want to track</param> /// <param name="changeCount">How many times value has changed</param>
/// <param name="type">How you you want to display the value See <see cref="DisplayType"/></param> /// <exception cref="ArgumentException">Occurs when a <see cref="DisplayType"/> is incompatible with <see cref="WatchSize.Byte"/></exception>
/// <param name="bigEndian">Specify the endianess. true for big endian</param> internal ByteWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note, byte value, byte previous, int changeCount)
/// <param name="note">A custom note about the <see cref="Watch"/></param> : base(domain, address, WatchSize.Byte, type, bigEndian, note)
/// <param name="value">Current value</param> {
/// <param name="previous">Previous value</param> _value = value == 0 ? GetByte() : value;
/// <param name="changeCount">How many times value has changed</param> _previous = previous;
/// <exception cref="ArgumentException">Occurs when a <see cref="DisplayType"/> is incompatible with <see cref="WatchSize.Byte"/></exception> ChangeCount = changeCount;
internal ByteWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note, byte value, byte previous, int changeCount) }
: base(domain, address, WatchSize.Byte, type, bigEndian, note)
{ /// <summary>
if (value == 0) /// Gets an enumeration of <see cref="DisplayType"/> that are valid for a <see cref="ByteWatch"/>
{ /// </summary>
_value = GetByte(); public static IEnumerable<DisplayType> ValidTypes
} {
else get
{ {
_value = value; yield return DisplayType.Unsigned;
} yield return DisplayType.Signed;
yield return DisplayType.Hex;
_previous = previous; yield return DisplayType.Binary;
_changecount = changeCount; }
} }
#endregion /// <summary>
/// Get a list a <see cref="DisplayType"/> that can be used for this <see cref="ByteWatch"/>
#region Methods /// </summary>
/// <returns>An enumeration that contains all valid <see cref="DisplayType"/></returns>
/// <summary> public override IEnumerable<DisplayType> AvailableTypes()
/// Enumerate which <see cref="DisplayType"/> are valid for a <see cref="ByteWatch"/> {
/// </summary> return ValidTypes;
public static IEnumerable<DisplayType> ValidTypes }
{
get /// <summary>
{ /// Reset the previous value; set it to the current one
yield return DisplayType.Unsigned; /// </summary>
yield return DisplayType.Signed; public override void ResetPrevious()
yield return DisplayType.Hex; {
yield return DisplayType.Binary; _previous = GetByte();
} }
}
/// <summary>
#region Implements /// Try to sets the value into the <see cref="MemoryDomain"/>
/// at the current <see cref="Watch"/> address
/// <summary> /// </summary>
/// Get a list a <see cref="DisplayType"/> that can be used for this <see cref="ByteWatch"/> /// <param name="value">Value to set</param>
/// </summary> /// <returns>True if value successfully sets; otherwise, false</returns>
/// <returns>An enumartion that contains all valid <see cref="DisplayType"/></returns> public override bool Poke(string value)
public override IEnumerable<DisplayType> AvailableTypes() {
{ try
return ValidTypes; {
} byte val = 0;
switch (Type)
/// <summary> {
/// Reset the previous value; set it to the current one case DisplayType.Unsigned:
/// </summary> if (value.IsUnsigned())
public override void ResetPrevious() {
{ val = (byte)int.Parse(value);
_previous = GetByte(); }
} else
{
/// <summary> return false;
/// Try to sets the value into the <see cref="MemoryDomain"/> }
/// at the current <see cref="Watch"/> address
/// </summary> break;
/// <param name="value">Value to set</param> case DisplayType.Signed:
/// <returns>True if value successfully sets; othewise, false</returns> if (value.IsSigned())
public override bool Poke(string value) {
{ val = (byte)(sbyte)int.Parse(value);
try }
{ else
byte val = 0; {
switch (Type) return false;
{ }
case DisplayType.Unsigned:
if (value.IsUnsigned()) break;
{ case DisplayType.Hex:
val = (byte)int.Parse(value); if (value.IsHex())
} {
else val = (byte)int.Parse(value, NumberStyles.HexNumber);
{ }
return false; else
} {
return false;
break; }
case DisplayType.Signed:
if (value.IsSigned()) break;
{ case DisplayType.Binary:
val = (byte)(sbyte)int.Parse(value); if (value.IsBinary())
} {
else val = (byte)Convert.ToInt32(value, 2);
{ }
return false; else
} {
return false;
break; }
case DisplayType.Hex:
if (value.IsHex()) break;
{ }
val = (byte)int.Parse(value, NumberStyles.HexNumber);
} if (Global.CheatList.Contains(Domain, Address))
else {
{ var cheat = Global.CheatList.FirstOrDefault(c => c.Address == Address && c.Domain == Domain);
return false;
} if (cheat != (Cheat)null)
{
break; cheat.PokeValue(val);
case DisplayType.Binary: PokeByte(val);
if (value.IsBinary()) return true;
{ }
val = (byte)Convert.ToInt32(value, 2); }
}
else PokeByte(val);
{ return true;
return false; }
} catch
{
break; return false;
} }
}
if (Global.CheatList.Contains(Domain, _address))
{ /// <summary>
var cheat = Global.CheatList.FirstOrDefault(c => c.Address == _address && c.Domain == Domain); /// Update the Watch (read it from <see cref="MemoryDomain"/>
/// </summary>
if (cheat != (Cheat)null) public override void Update()
{ {
cheat.PokeValue(val); switch (Global.Config.RamWatchDefinePrevious)
PokeByte(val); {
return true; case PreviousType.Original:
} return;
} case PreviousType.LastChange:
var temp = _value;
PokeByte(val); _value = GetByte();
return true; if (_value != temp)
} {
catch _previous = _value;
{ ChangeCount++;
return false; }
}
} break;
case PreviousType.LastFrame:
/// <summary> _previous = _value;
/// Update the Watch (read it from <see cref="MemoryDomain"/> _value = GetByte();
/// </summary> if (_value != Previous)
public override void Update() {
{ ChangeCount++;
switch (Global.Config.RamWatchDefinePrevious) }
{
case PreviousType.Original: break;
return; }
case PreviousType.LastChange: }
var temp = _value;
_value = GetByte(); // TODO: Implements IFormattable
if (_value != temp) public string FormatValue(byte val)
{ {
_previous = _value; switch (Type)
_changecount++; {
} default:
case DisplayType.Unsigned:
break; return val.ToString();
case PreviousType.LastFrame: case DisplayType.Signed:
_previous = _value; return ((sbyte)val).ToString();
_value = GetByte(); case DisplayType.Hex:
if (_value != Previous) return val.ToHexString(2);
{ case DisplayType.Binary:
_changecount++; return Convert.ToString(val, 2).PadLeft(8, '0').Insert(4, " ");
} }
}
break;
} /// <summary>
} /// Get a string representation of difference
/// between current value and the previous one
#endregion Implements /// </summary>
public override string Diff
// TODO: Implements IFormattable {
public string FormatValue(byte val) get
{ {
switch (Type) string diff = "";
{ int diffVal = _value - _previous;
default: if (diffVal > 0)
case DisplayType.Unsigned: {
return val.ToString(); diff = "+";
case DisplayType.Signed: }
return ((sbyte)val).ToString(); else if (diffVal < 0)
case DisplayType.Hex: {
return val.ToHexString(2); diff = "-";
case DisplayType.Binary: }
return Convert.ToString(val, 2).PadLeft(8, '0').Insert(4, " ");
} return $"{diff}{FormatValue((byte)Math.Abs(diffVal))}";
} }
}
#endregion
/// <summary>
#region Properties /// Get the maximum possible value
/// </summary>
#region Implements public override uint MaxValue => byte.MaxValue;
/// <summary> /// <summary>
/// Get a string representation of difference /// Get the current value
/// between current value and the previous one /// </summary>
/// </summary> public override int Value => GetByte();
public override string Diff
{ /// <summary>
get /// Gets the current value
{ /// but with stuff I don't understand
string diff = ""; /// </summary>
int diffVal = _value - _previous; /// <remarks>zero 15-nov-2015 - bypass LIAR LOGIC, see fdc9ea2aa922876d20ba897fb76909bf75fa6c92 https://github.com/TASVideos/BizHawk/issues/326 </remarks>
if (diffVal > 0) public override int ValueNoFreeze => GetByte(true);
{
diff = "+"; /// <summary>
} /// Get a string representation of the current value
else if (diffVal < 0) /// </summary>
{ public override string ValueString => FormatValue(GetByte());
diff = "-";
} /// <summary>
/// Get the previous value
return $"{diff}{FormatValue((byte)Math.Abs(diffVal))}"; /// </summary>
} public override int Previous => _previous;
}
/// <summary>
/// <summary> /// Get a string representation of the previous value
/// Get the maximum possible value /// </summary>
/// </summary> public override string PreviousStr => FormatValue(_previous);
public override uint MaxValue => byte.MaxValue; }
}
/// <summary>
/// Get the current value
/// </summary>
public override int Value => 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 => GetByte(true);
/// <summary>
/// Get a string representation of the current value
/// </summary>
public override string ValueString => FormatValue(GetByte());
/// <summary>
/// Get the previous value
/// </summary>
public override int Previous => _previous;
/// <summary>
/// Get a string representation of the previous value
/// </summary>
public override string PreviousStr => FormatValue(_previous);
#endregion Implements
#endregion
}
}

View File

@ -36,19 +36,19 @@
Binary, Binary,
/// <summary> /// <summary>
/// Display the value as fractionnal number. 12 before coma and 4 after /// Display the value as fractional number. 12 before coma and 4 after
/// Used only by <see cref="WordWatch"/> as it is 16 bits length /// Used only by <see cref="WordWatch"/> as it is 16 bits length
/// </summary> /// </summary>
FixedPoint_12_4, FixedPoint_12_4,
/// <summary> /// <summary>
/// Display the value as fractionnal number. 20 before coma and 12 after /// Display the value as fractional number. 20 before coma and 12 after
/// Used only by <see cref="DWordWatch"/> as it is 32 bits length /// Used only by <see cref="DWordWatch"/> as it is 32 bits length
/// </summary> /// </summary>
FixedPoint_20_12, FixedPoint_20_12,
/// <summary> /// <summary>
/// Display the value as fractionnal number. 16 before coma and 16 after /// Display the value as fractional number. 16 before coma and 16 after
/// Used only by <see cref="DWordWatch"/> as it is 32 bits length /// Used only by <see cref="DWordWatch"/> as it is 32 bits length
/// </summary> /// </summary>
FixedPoint_16_16, FixedPoint_16_16,

View File

@ -14,17 +14,11 @@ namespace BizHawk.Client.Common
/// </summary> /// </summary>
public sealed class DWordWatch : Watch public sealed class DWordWatch : Watch
{ {
#region Fields
private uint _value; private uint _value;
private uint _previous; private uint _previous;
#endregion
#region cTor(s)
/// <summary> /// <summary>
/// Initialize a new instance of <see cref="DWordWatch"/> /// Initializes a new instance of the <see cref="DWordWatch"/> class
/// </summary> /// </summary>
/// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param> /// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param>
/// <param name="address">The address you want to track</param> /// <param name="address">The address you want to track</param>
@ -38,23 +32,11 @@ namespace BizHawk.Client.Common
internal DWordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note, uint value, uint previous, int changeCount) 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) : base(domain, address, WatchSize.DWord, type, bigEndian, note)
{ {
if (value == 0) _value = value == 0 ? GetDWord() : value;
{
_value = GetDWord();
}
else
{
_value = value;
}
_previous = previous; _previous = previous;
_changecount = changeCount; ChangeCount = changeCount;
} }
#endregion
#region Methods
/// <summary> /// <summary>
/// Gets a list of <see cref="DisplayType"/> for a <see cref="DWordWatch"/> /// Gets a list of <see cref="DisplayType"/> for a <see cref="DWordWatch"/>
/// </summary> /// </summary>
@ -72,8 +54,6 @@ namespace BizHawk.Client.Common
} }
} }
#region Implements
/// <summary> /// <summary>
/// Get a list of <see cref="DisplayType"/> that can be used for a <see cref="DWordWatch"/> /// Get a list of <see cref="DisplayType"/> that can be used for a <see cref="DWordWatch"/>
/// </summary> /// </summary>
@ -173,9 +153,9 @@ namespace BizHawk.Client.Common
break; break;
} }
if (Global.CheatList.Contains(Domain, _address)) if (Global.CheatList.Contains(Domain, Address))
{ {
var cheat = Global.CheatList.FirstOrDefault(c => c.Address == _address && c.Domain == Domain); var cheat = Global.CheatList.FirstOrDefault(c => c.Address == Address && c.Domain == Domain);
if (cheat != (Cheat)null) if (cheat != (Cheat)null)
{ {
cheat.PokeValue((int)val); cheat.PokeValue((int)val);
@ -208,7 +188,7 @@ namespace BizHawk.Client.Common
if (_value != temp) if (_value != temp)
{ {
_previous = _value; _previous = _value;
_changecount++; ChangeCount++;
} }
break; break;
@ -217,15 +197,13 @@ namespace BizHawk.Client.Common
_value = GetDWord(); _value = GetDWord();
if (_value != Previous) if (_value != Previous)
{ {
_changecount++; ChangeCount++;
} }
break; break;
} }
} }
#endregion Implements
// TODO: Implements IFormattable // TODO: Implements IFormattable
public string FormatValue(uint val) public string FormatValue(uint val)
{ {
@ -245,17 +223,10 @@ namespace BizHawk.Client.Common
case DisplayType.Float: case DisplayType.Float:
var bytes = BitConverter.GetBytes(val); var bytes = BitConverter.GetBytes(val);
var _float = BitConverter.ToSingle(bytes, 0); 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 return _float.ToString(); // adelikat: decided that we like sci notation instead of spooky rounding
} }
} }
#endregion
#region Properties
#region Implements
/// <summary> /// <summary>
/// Get a string representation of difference /// Get a string representation of difference
/// between current value and the previous one /// between current value and the previous one
@ -292,9 +263,5 @@ namespace BizHawk.Client.Common
/// Get a string representation of the previous value /// Get a string representation of the previous value
/// </summary> /// </summary>
public override string PreviousStr => FormatValue(_previous); public override string PreviousStr => FormatValue(_previous);
#endregion Implements
#endregion
} }
} }

View File

@ -9,7 +9,7 @@ namespace BizHawk.Client.Common
public sealed class SeparatorWatch : Watch public sealed class SeparatorWatch : Watch
{ {
/// <summary> /// <summary>
/// Initialize a new separator instance /// Initializes a new instance of the <see cref="SeparatorWatch"/> class.
/// </summary> /// </summary>
internal SeparatorWatch() internal SeparatorWatch()
: base(null, 0, WatchSize.Separator, DisplayType.Separator, true, "") : base(null, 0, WatchSize.Separator, DisplayType.Separator, true, "")
@ -30,8 +30,6 @@ namespace BizHawk.Client.Common
yield return DisplayType.Separator; yield return DisplayType.Separator;
} }
#region Stuff to ignore
/// <summary> /// <summary>
/// Ignore that stuff /// Ignore that stuff
/// </summary> /// </summary>
@ -98,7 +96,5 @@ namespace BizHawk.Client.Common
public override void Update() public override void Update()
{ {
} }
#endregion
} }
} }

View File

@ -15,27 +15,16 @@ namespace BizHawk.Client.Common
/// This is an abstract class /// This is an abstract class
/// </summary> /// </summary>
[DebuggerDisplay("Note={Notes}, Value={ValueString}")] [DebuggerDisplay("Note={Notes}, Value={ValueString}")]
public abstract partial class Watch public abstract class Watch
: IEquatable<Watch>, : IEquatable<Watch>,
IEquatable<Cheat>, IEquatable<Cheat>,
IComparable<Watch> IComparable<Watch>
{ {
#region Fields private MemoryDomain _domain;
private DisplayType _type;
protected long _address;
protected MemoryDomain _domain;
protected DisplayType _type;
protected WatchSize _size;
protected bool _bigEndian;
protected string _notes;
protected int _changecount = 0;
#endregion
#region cTor(s)
/// <summary> /// <summary>
/// Initialize a new instance of <see cref="Watch"/> /// Initializes a new instance of the <see cref="Watch"/> class
/// </summary> /// </summary>
/// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param> /// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param>
/// <param name="address">The address you want to track</param> /// <param name="address">The address you want to track</param>
@ -49,20 +38,18 @@ namespace BizHawk.Client.Common
if (IsDiplayTypeAvailable(type)) if (IsDiplayTypeAvailable(type))
{ {
_domain = domain; _domain = domain;
_address = address; Address = address;
_size = size; Size = size;
_type = type; _type = type;
_bigEndian = bigEndian; BigEndian = bigEndian;
_notes = note; Notes = note;
} }
else else
{ {
throw new ArgumentException(string.Format("DisplayType {0} is invalid for this type of Watch", type), nameof(type)); throw new ArgumentException($"DisplayType {type} is invalid for this type of Watch", nameof(type));
} }
} }
#endregion
#region Methods #region Methods
#region Static #region Static
@ -71,7 +58,7 @@ namespace BizHawk.Client.Common
/// Generate sa <see cref="Watch"/> from a given string /// Generate sa <see cref="Watch"/> from a given string
/// String is tab separate /// String is tab separate
/// </summary> /// </summary>
/// <param name="line">Entire string, tab seperated for each value Order is: /// <param name="line">Entire string, tab separated for each value Order is:
/// <list type="number"> /// <list type="number">
/// <item> /// <item>
/// <term>0x00</term> /// <term>0x00</term>
@ -119,9 +106,9 @@ namespace BizHawk.Client.Common
{ {
WatchSize size = SizeFromChar(parts[1][0]); WatchSize size = SizeFromChar(parts[1][0]);
DisplayType type = DisplayTypeFromChar(parts[2][0]); DisplayType type = DisplayTypeFromChar(parts[2][0]);
bool bigEndian = parts[3] == "0" ? false : true; bool bigEndian = parts[3] != "0";
MemoryDomain domain = domains[parts[4]]; MemoryDomain domain = domains[parts[4]];
string notes = parts[5].Trim(new char[] { '\r', '\n' }); string notes = parts[5].Trim('\r', '\n');
return GenerateWatch( return GenerateWatch(
domain, domain,
@ -131,10 +118,8 @@ namespace BizHawk.Client.Common
bigEndian, bigEndian,
notes); notes);
} }
else
{ return null;
return null;
}
} }
/// <summary> /// <summary>
@ -151,7 +136,7 @@ namespace BizHawk.Client.Common
/// <param name="prev">Previous value</param> /// <param name="prev">Previous value</param>
/// <param name="changeCount">Number of changes occurs in current <see cref="Watch"/></param> /// <param name="changeCount">Number of changes occurs in current <see cref="Watch"/></param>
/// <returns>New <see cref="Watch"/> instance. True type is depending of size parameter</returns> /// <returns>New <see cref="Watch"/> instance. True type is depending of size parameter</returns>
public static Watch GenerateWatch(MemoryDomain domain, long address, WatchSize size, DisplayType type, bool bigEndian, string note, long value, long prev, int changeCount) public static Watch GenerateWatch(MemoryDomain domain, long address, WatchSize size, DisplayType type, bool bigEndian, string note = "", long value = 0, long prev = 0, int changeCount = 0)
{ {
switch (size) switch (size)
{ {
@ -167,37 +152,6 @@ namespace BizHawk.Client.Common
} }
} }
/// <summary>
/// Generates a new <see cref="Watch"/> instance
/// Can be either <see cref="ByteWatch"/>, <see cref="WordWatch"/>, <see cref="DWordWatch"/> or <see cref="SeparatorWatch"/>
/// </summary>
/// <param name="domain">The <see cref="MemoryDomain"/> where you want to watch</param>
/// <param name="address">The address into the <see cref="MemoryDomain"/></param>
/// <param name="size">The size</param>
/// <param name="type">How the watch will be displayed</param>
/// <param name="bigEndian">Endianess (true for big endian)</param>
/// <param name="note">A customp note about your watch</param>
/// <returns>New <see cref="Watch"/> instance. True type is depending of size parameter</returns>
public static Watch GenerateWatch(MemoryDomain domain, long address, WatchSize size, DisplayType type, bool bigEndian, string note)
{
return GenerateWatch(domain, address, size, type, bigEndian, note, 0, 0, 0);
}
/// <summary>
/// Generates a new <see cref="Watch"/> instance
/// Can be either <see cref="ByteWatch"/>, <see cref="WordWatch"/>, <see cref="DWordWatch"/> or <see cref="SeparatorWatch"/>
/// </summary>
/// <param name="domain">The <see cref="MemoryDomain"/> where you want to watch</param>
/// <param name="address">The address into the <see cref="MemoryDomain"/></param>
/// <param name="size">The size</param>
/// <param name="type">How the watch will be displayed</param>
/// <param name="bigEndian">Endianess (true for big endian)</param>
/// <returns>New <see cref="Watch"/> instance. True type is depending of size parameter</returns>
public static Watch GenerateWatch(MemoryDomain domain, long address, WatchSize size, DisplayType type, bool bigEndian)
{
return GenerateWatch(domain, address, size, type, bigEndian, "", 0, 0, 0);
}
#region Operators #region Operators
/// <summary> /// <summary>
@ -208,12 +162,12 @@ namespace BizHawk.Client.Common
/// <returns>True if both watch are equals; otherwise, false</returns> /// <returns>True if both watch are equals; otherwise, false</returns>
public static bool operator ==(Watch a, Watch b) public static bool operator ==(Watch a, Watch b)
{ {
if (object.ReferenceEquals(a, null) || object.ReferenceEquals(b, null)) if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
{ {
return false; return false;
} }
if (object.ReferenceEquals(a, b)) if (ReferenceEquals(a, b))
{ {
return true; return true;
} }
@ -229,16 +183,11 @@ namespace BizHawk.Client.Common
/// <returns>True if they are equals; otherwise, false</returns> /// <returns>True if they are equals; otherwise, false</returns>
public static bool operator ==(Watch a, Cheat b) public static bool operator ==(Watch a, Cheat b)
{ {
if (object.ReferenceEquals(a, null) || object.ReferenceEquals(b, null)) if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
{ {
return false; return false;
} }
if (object.ReferenceEquals(a, b))
{
return true;
}
return a.Equals(b); return a.Equals(b);
} }
@ -321,7 +270,7 @@ namespace BizHawk.Client.Common
/// <summary> /// <summary>
/// Gets a list a <see cref="DisplayType"/> that can be used for this <see cref="Watch"/> /// Gets a list a <see cref="DisplayType"/> that can be used for this <see cref="Watch"/>
/// </summary> /// </summary>
/// <returns>An enumartion that contains all valid <see cref="DisplayType"/></returns> /// <returns>An enumeration that contains all valid <see cref="DisplayType"/></returns>
public abstract IEnumerable<DisplayType> AvailableTypes(); public abstract IEnumerable<DisplayType> AvailableTypes();
/// <summary> /// <summary>
@ -340,61 +289,61 @@ namespace BizHawk.Client.Common
protected byte GetByte(bool bypassFreeze = false) protected byte GetByte(bool bypassFreeze = false)
{ {
if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address)) if (!bypassFreeze && Global.CheatList.IsActive(_domain, Address))
{ {
// LIAR logic // LIAR logic
return Global.CheatList.GetByteValue(_domain, _address) ?? 0; return Global.CheatList.GetByteValue(_domain, Address) ?? 0;
} }
if (_domain.Size == 0) if (_domain.Size == 0)
{ {
return _domain.PeekByte(_address); return _domain.PeekByte(Address);
} }
return _domain.PeekByte(_address % _domain.Size); return _domain.PeekByte(Address % _domain.Size);
} }
protected ushort GetWord(bool bypassFreeze = false) protected ushort GetWord(bool bypassFreeze = false)
{ {
if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address)) if (!bypassFreeze && Global.CheatList.IsActive(_domain, Address))
{ {
// LIAR logic // LIAR logic
return (ushort)(Global.CheatList.GetCheatValue(_domain, _address, WatchSize.Word) ?? 0); return (ushort)(Global.CheatList.GetCheatValue(_domain, Address, WatchSize.Word) ?? 0);
} }
if (_domain.Size == 0) if (_domain.Size == 0)
{ {
return _domain.PeekUshort(_address, _bigEndian); return _domain.PeekUshort(Address, BigEndian);
} }
return _domain.PeekUshort(_address % _domain.Size, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain return _domain.PeekUshort(Address % _domain.Size, BigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
} }
protected uint GetDWord(bool bypassFreeze = false) protected uint GetDWord(bool bypassFreeze = false)
{ {
if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address)) if (!bypassFreeze && Global.CheatList.IsActive(_domain, Address))
{ {
// LIAR logic // LIAR logic
return (uint)(Global.CheatList.GetCheatValue(_domain, _address, WatchSize.DWord) ?? 0); return (uint)(Global.CheatList.GetCheatValue(_domain, Address, WatchSize.DWord) ?? 0);
} }
if (_domain.Size == 0) if (_domain.Size == 0)
{ {
return _domain.PeekUint(_address, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain return _domain.PeekUint(Address, BigEndian); // TODO: % size still isn't correct since it could be the last byte of the domain
} }
return _domain.PeekUint(_address % _domain.Size, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain return _domain.PeekUint(Address % _domain.Size, BigEndian); // TODO: % size still isn't correct since it could be the last byte of the domain
} }
protected void PokeByte(byte val) protected void PokeByte(byte val)
{ {
if (_domain.Size == 0) if (_domain.Size == 0)
{ {
_domain.PokeByte(_address, val); _domain.PokeByte(Address, val);
} }
else else
{ {
_domain.PokeByte(_address % _domain.Size, val); _domain.PokeByte(Address % _domain.Size, val);
} }
} }
@ -402,11 +351,11 @@ namespace BizHawk.Client.Common
{ {
if (_domain.Size == 0) if (_domain.Size == 0)
{ {
_domain.PokeUshort(_address, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain _domain.PokeUshort(Address, val, BigEndian); // TODO: % size still isn't correct since it could be the last byte of the domain
} }
else else
{ {
_domain.PokeUshort(_address % _domain.Size, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain _domain.PokeUshort(Address % _domain.Size, val, BigEndian); // TODO: % size still isn't correct since it could be the last byte of the domain
} }
} }
@ -414,11 +363,11 @@ namespace BizHawk.Client.Common
{ {
if (_domain.Size == 0) if (_domain.Size == 0)
{ {
_domain.PokeUint(_address, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain _domain.PokeUint(Address, val, BigEndian); // TODO: % size still isn't correct since it could be the last byte of the domain
} }
else else
{ {
_domain.PokeUint(_address % _domain.Size, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain _domain.PokeUint(Address % _domain.Size, val, BigEndian); // TODO: % size still isn't correct since it could be the last byte of the domain
} }
} }
@ -429,45 +378,43 @@ namespace BizHawk.Client.Common
/// </summary> /// </summary>
public void ClearChangeCount() public void ClearChangeCount()
{ {
_changecount = 0; ChangeCount = 0;
} }
#region IEquatable<Watch> #region IEquatable<Watch>
/// <summary> /// <summary>
/// Determines if this <see cref="Watch"/> is equals to another /// Determines if this <see cref="Watch"/> is equals to another
/// </summary> /// </summary>
/// <param name="obj">The <see cref="Watch"/> to compare</param> /// <param name="other">The <see cref="Watch"/> to compare</param>
/// <returns>True if both object are equals; otherwise, false</returns> /// <returns>True if both object are equals; otherwise, false</returns>
public bool Equals(Watch other) public bool Equals(Watch other)
{ {
if (object.ReferenceEquals(other, null)) if (ReferenceEquals(other, null))
{ {
return false; return false;
} }
else
{
return _domain == other._domain &&
_address == other._address &&
_size == other._size;
}
}
return _domain == other._domain &&
Address == other.Address &&
Size == other.Size;
}
#endregion IEquatable<Watch> #endregion IEquatable<Watch>
#region IEquatable<Cheat> #region IEquatable<Cheat>
/// <summary> /// <summary>
/// Determines if this <see cref="Watch"/> is equals to an instance of <see cref="Cheat"/> /// Determines if this <see cref="Watch"/> is equals to an instance of <see cref="Cheat"/>
/// </summary> /// </summary>
/// <param name="obj">The <see cref="Cheat"/> to compare</param> /// <param name="other">The <see cref="Cheat"/> to compare</param>
/// <returns>True if both object are equals; otherwise, false</returns> /// <returns>True if both object are equals; otherwise, false</returns>
public bool Equals(Cheat other) public bool Equals(Cheat other)
{ {
return !object.ReferenceEquals(other, null) && return !ReferenceEquals(other, null)
_domain == other.Domain && && _domain == other.Domain
_address == other.Address && && Address == other.Address
_size == other.Size; && Size == other.Size;
} }
#endregion IEquatable<Cheat> #endregion IEquatable<Cheat>
@ -475,7 +422,7 @@ namespace BizHawk.Client.Common
#region IComparable<Watch> #region IComparable<Watch>
/// <summary> /// <summary>
/// Compares two <see cref="Watch"/> together and determine wich one comes first. /// Compares two <see cref="Watch"/> together and determine which one comes first.
/// First we look the address and then the size /// First we look the address and then the size
/// </summary> /// </summary>
/// <param name="other">The other <see cref="Watch"/> to compare to</param> /// <param name="other">The other <see cref="Watch"/> to compare to</param>
@ -493,17 +440,12 @@ namespace BizHawk.Client.Common
return 0; return 0;
} }
if (object.ReferenceEquals(other, null)) if (Address.Equals(other.Address))
{ {
return 1; return ((int)Size).CompareTo((int)other.Size);
} }
if (_address.Equals(other._address)) return Address.CompareTo(other.Address);
{
return ((int)_size).CompareTo((int)other._size);
}
return _address.CompareTo(other._address);
} }
#endregion IComparable<Watch> #endregion IComparable<Watch>
@ -534,7 +476,7 @@ namespace BizHawk.Client.Common
/// <returns><see cref="int"/> that can serves as a unique representation of current Watch</returns> /// <returns><see cref="int"/> that can serves as a unique representation of current Watch</returns>
public override int GetHashCode() public override int GetHashCode()
{ {
return Domain.GetHashCode() + (int)(Address); return Domain.GetHashCode() + (int)Address;
} }
/// <summary> /// <summary>
@ -542,7 +484,6 @@ namespace BizHawk.Client.Common
/// used for the current <see cref="Watch"/> /// used for the current <see cref="Watch"/>
/// </summary> /// </summary>
/// <param name="type"><see cref="DisplayType"/> you want to check</param> /// <param name="type"><see cref="DisplayType"/> you want to check</param>
/// <returns></returns>
public bool IsDiplayTypeAvailable(DisplayType type) public bool IsDiplayTypeAvailable(DisplayType type)
{ {
return AvailableTypes().Any(d => d == type); return AvailableTypes().Any(d => d == type);
@ -554,7 +495,7 @@ namespace BizHawk.Client.Common
/// <returns>A <see cref="string"/> representation of the current <see cref="Watch"/></returns> /// <returns>A <see cref="string"/> representation of the current <see cref="Watch"/></returns>
public override string ToString() public override string ToString()
{ {
return $"{(Domain == null && Address == 0 ? "0" : Address.ToHexString((Domain.Size - 1).NumHexDigits()))}\t{SizeAsChar}\t{TypeAsChar}\t{Convert.ToInt32(BigEndian)}\t{DomainName}\t{Notes.Trim('\r', '\n')}"; return $"{(Domain == null && Address == 0 ? "0" : Address.ToHexString((Domain?.Size ?? 0xFF - 1).NumHexDigits()))}\t{SizeAsChar}\t{TypeAsChar}\t{Convert.ToInt32(BigEndian)}\t{Domain?.Name}\t{Notes.Trim('\r', '\n')}";
} }
/// <summary> /// <summary>
@ -574,18 +515,18 @@ namespace BizHawk.Client.Common
#region Abstracts #region Abstracts
/// <summary> /// <summary>
/// Get a string representation of difference /// Gets a string representation of difference
/// between current value and the previous one /// between current value and the previous one
/// </summary> /// </summary>
public abstract string Diff { get; } public abstract string Diff { get; }
/// <summary> /// <summary>
/// Get the maximum possible value /// Gets the maximum possible value
/// </summary> /// </summary>
public abstract uint MaxValue { get; } public abstract uint MaxValue { get; }
/// <summary> /// <summary>
/// Get the current value /// Gets the current value
/// </summary> /// </summary>
public abstract int Value { get; } public abstract int Value { get; }
@ -597,7 +538,7 @@ namespace BizHawk.Client.Common
public abstract int ValueNoFreeze { get; } public abstract int ValueNoFreeze { get; }
/// <summary> /// <summary>
/// Get a string representation of the current value /// Gets a string representation of the current value
/// </summary> /// </summary>
public abstract string ValueString { get; } public abstract string ValueString { get; }
@ -606,16 +547,16 @@ namespace BizHawk.Client.Common
/// at the current <see cref="Watch"/> address /// at the current <see cref="Watch"/> address
/// </summary> /// </summary>
/// <param name="value">Value to set</param> /// <param name="value">Value to set</param>
/// <returns>True if value successfully sets; othewise, false</returns> /// <returns>True if value successfully sets; otherwise, false</returns>
public abstract bool Poke(string value); public abstract bool Poke(string value);
/// <summary> /// <summary>
/// Get the previous value /// Gets the previous value
/// </summary> /// </summary>
public abstract int Previous { get; } public abstract int Previous { get; }
/// <summary> /// <summary>
/// Get a string representation of the previous value /// Gets a string representation of the previous value
/// </summary> /// </summary>
public abstract string PreviousStr { get; } public abstract string PreviousStr { get; }
@ -624,11 +565,8 @@ namespace BizHawk.Client.Common
/// <summary> /// <summary>
/// Gets the address in the <see cref="MemoryDomain"/> /// Gets the address in the <see cref="MemoryDomain"/>
/// </summary> /// </summary>
public long Address => _address; public long Address { get; }
/// <summary>
/// Gets the format tha should be used by string.Format()
/// </summary>
private string AddressFormatStr private string AddressFormatStr
{ {
get get
@ -645,28 +583,18 @@ namespace BizHawk.Client.Common
/// <summary> /// <summary>
/// Gets the address in the <see cref="MemoryDomain"/> formatted as string /// Gets the address in the <see cref="MemoryDomain"/> formatted as string
/// </summary> /// </summary>
public string AddressString => _address.ToString(AddressFormatStr); public string AddressString => Address.ToString(AddressFormatStr);
/// <summary> /// <summary>
/// Gets or sets the endianess of current <see cref="Watch"/> /// Gets or sets a value indicating the endianess of current <see cref="Watch"/>
/// True for big endian, flase for little endian /// True for big endian, flase for little endian
/// </summary> /// </summary>
public bool BigEndian public bool BigEndian { get; set; }
{
get
{
return _bigEndian;
}
set
{
_bigEndian = value;
}
}
/// <summary> /// <summary>
/// Gets the number of time tha value of current <see cref="Watch"/> has changed /// Gets or sets the number of times that value of current <see cref="Watch"/> value has changed
/// </summary> /// </summary>
public int ChangeCount => _changecount; public int ChangeCount { get; protected set; }
/// <summary> /// <summary>
/// Gets or sets the way current <see cref="Watch"/> is displayed /// Gets or sets the way current <see cref="Watch"/> is displayed
@ -678,6 +606,7 @@ namespace BizHawk.Client.Common
{ {
return _type; return _type;
} }
set set
{ {
if (IsDiplayTypeAvailable(value)) if (IsDiplayTypeAvailable(value))
@ -686,13 +615,13 @@ namespace BizHawk.Client.Common
} }
else else
{ {
throw new ArgumentException(string.Format("DisplayType {0} is invalid for this type of Watch", value)); throw new ArgumentException($"DisplayType {value} is invalid for this type of Watch");
} }
} }
} }
/// <summary> /// <summary>
/// Gets or sets current <see cref="MemoryDomain"/> /// Gets the current <see cref="MemoryDomain"/>
/// </summary> /// </summary>
public MemoryDomain Domain public MemoryDomain Domain
{ {
@ -715,72 +644,25 @@ namespace BizHawk.Client.Common
} }
/// <summary> /// <summary>
/// Gets the domain name of the current <see cref="MemoryDomain"/> /// Gets a value indicating whether the current address is
/// It's the same of doing myWatch.Domain.Name /// within in the range of current <see cref="MemoryDomain"/>
/// </summary> /// </summary>
public string DomainName public bool IsOutOfRange => !IsSeparator && _domain.Size != 0 && Address >= _domain.Size;
{
get
{
if (_domain != null)
{
return _domain.Name;
}
else
{
return "";
}
}
}
/// <summary>
/// Gets a value that defined if the current address is
/// well in the range of current <see cref="MemoryDomain"/>
/// </summary>
public bool IsOutOfRange
{
get
{
return !IsSeparator && (_domain.Size != 0 && _address >= _domain.Size);
}
}
/// <summary> /// <summary>
/// Gets a value that defined if the current <see cref="Watch"/> is actually a <see cref="SeparatorWatch"/> /// Gets a value that defined if the current <see cref="Watch"/> is actually a <see cref="SeparatorWatch"/>
/// </summary> /// </summary>
public bool IsSeparator public bool IsSeparator => this is SeparatorWatch;
{
get
{
return this is SeparatorWatch;
}
}
/// <summary> /// <summary>
/// Gets or sets notes for current <see cref="Watch"/> /// Gets or sets notes for current <see cref="Watch"/>
/// </summary> /// </summary>
public string Notes public string Notes { get; set; }
{
get
{
return _notes;
}
set
{
_notes = value;
}
}
/// <summary> /// <summary>
/// Gets the current size of the watch /// Gets the current size of the watch
/// </summary> /// </summary>
public WatchSize Size public WatchSize Size { get; }
{
get
{
return _size;
}
}
#endregion #endregion

View File

@ -9,17 +9,16 @@ namespace BizHawk.Client.Common
public sealed partial class WatchList public sealed partial class WatchList
{ {
/// <summary> /// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/> /// Nested private class that define how to compare two <see cref="Watch"/>
/// based on their address /// based on their address
/// </summary> /// </summary>
private sealed class WatchAddressComparer private sealed class WatchAddressComparer
: WatchEqualityComparer, : WatchEqualityComparer, IComparer<Watch>
IComparer<Watch>
{ {
/// <summary> /// <summary>
/// Compares two <see cref="Watch"/> between them /// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first. /// and determines which one comes first.
/// If they are equals, comapraison will done one the domain and next on size /// If they are equals, comparison will done one the domain and next on size
/// </summary> /// </summary>
/// <param name="x">First <see cref="Watch"/></param> /// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param> /// <param name="y">Second <see cref="Watch"/></param>
@ -30,21 +29,18 @@ namespace BizHawk.Client.Common
{ {
return 0; return 0;
} }
else if (x.Address.Equals(y.Address))
if (x.Address.Equals(y.Address))
{ {
if (x.Domain.Name.Equals(y.Domain.Name)) if (x.Domain.Name.Equals(y.Domain.Name))
{ {
return x.Size.CompareTo(y.Size); return x.Size.CompareTo(y.Size);
} }
else
{ return x.Domain.Name.CompareTo(y.Domain.Name);
return x.Domain.Name.CompareTo(y.Domain.Name);
}
}
else
{
return x.Address.CompareTo(y.Address);
} }
return x.Address.CompareTo(y.Address);
} }
} }
} }

View File

@ -9,7 +9,7 @@ namespace BizHawk.Client.Common
public sealed partial class WatchList public sealed partial class WatchList
{ {
/// <summary> /// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/> /// Nested private class that define how to compare two <see cref="Watch"/>
/// based on the number of changes /// based on the number of changes
/// </summary> /// </summary>
private sealed class WatchChangeCountComparer private sealed class WatchChangeCountComparer

View File

@ -9,17 +9,16 @@ namespace BizHawk.Client.Common
public sealed partial class WatchList public sealed partial class WatchList
{ {
/// <summary> /// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/> /// Nested private class that define how to compare two <see cref="Watch"/>
/// based on their domain /// based on their domain
/// </summary> /// </summary>
private sealed class WatchDomainComparer private sealed class WatchDomainComparer
: WatchEqualityComparer, : WatchEqualityComparer, IComparer<Watch>
IComparer<Watch>
{ {
/// <summary> /// <summary>
/// Compares two <see cref="Watch"/> between them /// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first. /// and determines which one comes first.
/// If they are equals, comapraison will done one the address and next on size /// If they are equals, comparison will done one the address and next on size
/// </summary> /// </summary>
/// <param name="x">First <see cref="Watch"/></param> /// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param> /// <param name="y">Second <see cref="Watch"/></param>
@ -30,21 +29,18 @@ namespace BizHawk.Client.Common
{ {
return 0; return 0;
} }
else if (x.Domain.Name.Equals(y.Domain.Name))
if (x.Domain.Name.Equals(y.Domain.Name))
{ {
if (x.Address.Equals(y.Address)) if (x.Address.Equals(y.Address))
{ {
return x.Size.CompareTo(y.Size); return x.Size.CompareTo(y.Size);
} }
else
{ return x.Address.CompareTo(y.Address);
return x.Address.CompareTo(y.Address);
}
}
else
{
return x.Domain.Name.CompareTo(y.Domain.Name);
} }
return x.Domain.Name.CompareTo(y.Domain.Name);
} }
} }
} }

View File

@ -9,7 +9,7 @@ namespace BizHawk.Client.Common
public sealed partial class WatchList public sealed partial class WatchList
{ {
/// <summary> /// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/> /// Nested private class that define how to compare two <see cref="Watch"/>
/// based on their note /// based on their note
/// </summary> /// </summary>
private sealed class WatchNoteComparer private sealed class WatchNoteComparer
@ -18,8 +18,8 @@ namespace BizHawk.Client.Common
{ {
/// <summary> /// <summary>
/// Compares two <see cref="Watch"/> between them /// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first. /// and determines which one comes first.
/// If they are equals, comapraison will done one the address and next on size /// If they are equals, comparison will done one the address and next on size
/// </summary> /// </summary>
/// <param name="x">First <see cref="Watch"/></param> /// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param> /// <param name="y">Second <see cref="Watch"/></param>

View File

@ -9,17 +9,16 @@ namespace BizHawk.Client.Common
public sealed partial class WatchList public sealed partial class WatchList
{ {
/// <summary> /// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/> /// Nested private class that define how to compare two <see cref="Watch"/>
/// based on their previous value /// based on their previous value
/// </summary> /// </summary>
private sealed class WatchPreviousValueComparer private sealed class WatchPreviousValueComparer
: WatchEqualityComparer, : WatchEqualityComparer, IComparer<Watch>
IComparer<Watch>
{ {
/// <summary> /// <summary>
/// Compares two <see cref="Watch"/> between them /// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first. /// and determines which one comes first.
/// If they are equals, comapraison will done one the address and next on size /// If they are equals, comparison will done one the address and next on size
/// </summary> /// </summary>
/// <param name="x">First <see cref="Watch"/></param> /// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param> /// <param name="y">Second <see cref="Watch"/></param>
@ -30,21 +29,18 @@ namespace BizHawk.Client.Common
{ {
return 0; return 0;
} }
else if (x.Previous.Equals(y.Previous))
if (x.Previous.Equals(y.Previous))
{ {
if (x.Address.Equals(y.Address)) if (x.Address.Equals(y.Address))
{ {
return x.Size.CompareTo(y.Size); return x.Size.CompareTo(y.Size);
} }
else
{ return x.Address.CompareTo(y.Address);
return x.Address.CompareTo(y.Address);
}
}
else
{
return x.Previous.CompareTo(y.Previous);
} }
return x.Previous.CompareTo(y.Previous);
} }
} }
} }

View File

@ -9,7 +9,7 @@ namespace BizHawk.Client.Common
public sealed partial class WatchList public sealed partial class WatchList
{ {
/// <summary> /// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/> /// Nested private class that define how to compare two <see cref="Watch"/>
/// based on their values /// based on their values
/// </summary> /// </summary>
private sealed class WatchValueComparer private sealed class WatchValueComparer
@ -18,8 +18,8 @@ namespace BizHawk.Client.Common
{ {
/// <summary> /// <summary>
/// Compares two <see cref="Watch"/> between them /// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first. /// and determines which one comes first.
/// If they are equals, comapraison will done one the address and next on size /// If they are equals, comparison will done one the address and next on size
/// </summary> /// </summary>
/// <param name="x">First <see cref="Watch"/></param> /// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param> /// <param name="y">Second <see cref="Watch"/></param>

View File

@ -10,18 +10,21 @@
/// Use this for <see cref="ByteWatch"/> /// Use this for <see cref="ByteWatch"/>
/// </summary> /// </summary>
Byte = 1, Byte = 1,
/// <summary> /// <summary>
/// 2 bytes (16 bits) /// 2 bytes (16 bits)
/// Use this for <see cref="WordWatch"/> /// Use this for <see cref="WordWatch"/>
/// </summary> /// </summary>
Word = 2, Word = 2,
/// <summary> /// <summary>
/// 4 bytes (32 bits) /// 4 bytes (32 bits)
/// Use this for <see cref="DWordWatch"/> /// Use this for <see cref="DWordWatch"/>
/// </summary> /// </summary>
DWord = 4, DWord = 4,
/// <summary> /// <summary>
/// Special case used for a separator in ramwatch /// Special case used for a separator in ram tools
/// Use this for <see cref="SeparatorWatch"/> /// Use this for <see cref="SeparatorWatch"/>
/// </summary> /// </summary>
Separator = 0 Separator = 0

View File

@ -14,17 +14,11 @@ namespace BizHawk.Client.Common
/// </summary> /// </summary>
public sealed class WordWatch : Watch public sealed class WordWatch : Watch
{ {
#region Fields
private ushort _previous; private ushort _previous;
private ushort _value; private ushort _value;
#endregion
#region cTor(s)
/// <summary> /// <summary>
/// Inialize a new instance of <see cref="WordWatch"/> /// Initializes a new instance of the <see cref="WordWatch"/> class
/// </summary> /// </summary>
/// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param> /// <param name="domain"><see cref="MemoryDomain"/> where you want to track</param>
/// <param name="address">The address you want to track</param> /// <param name="address">The address you want to track</param>
@ -38,24 +32,13 @@ namespace BizHawk.Client.Common
internal WordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note, ushort value, ushort previous, int changeCount) 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) : base(domain, address, WatchSize.Word, type, bigEndian, note)
{ {
if (value == 0) _value = value == 0 ? GetWord() : value;
{
_value = GetWord();
}
else
{
_value = value;
}
_previous = previous; _previous = previous;
_changecount = changeCount; ChangeCount = changeCount;
} }
#endregion
#region Methods
/// <summary> /// <summary>
/// Enumerate wich <see cref="DisplayType"/> are valid for a <see cref="WordWatch"/> /// Gets an Enumeration of <see cref="DisplayType"/>s that are valid for a <see cref="WordWatch"/>
/// </summary> /// </summary>
public static IEnumerable<DisplayType> ValidTypes public static IEnumerable<DisplayType> ValidTypes
{ {
@ -69,12 +52,10 @@ namespace BizHawk.Client.Common
} }
} }
#region Implements
/// <summary> /// <summary>
/// Get a list a <see cref="DisplayType"/> that can be used for this <see cref="WordWatch"/> /// Get a list a <see cref="DisplayType"/> that can be used for this <see cref="WordWatch"/>
/// </summary> /// </summary>
/// <returns>An enumartion that contains all valid <see cref="DisplayType"/></returns> /// <returns>An enumeration that contains all valid <see cref="DisplayType"/></returns>
public override IEnumerable<DisplayType> AvailableTypes() public override IEnumerable<DisplayType> AvailableTypes()
{ {
return ValidTypes; return ValidTypes;
@ -93,7 +74,7 @@ namespace BizHawk.Client.Common
/// at the current <see cref="Watch"/> address /// at the current <see cref="Watch"/> address
/// </summary> /// </summary>
/// <param name="value">Value to set</param> /// <param name="value">Value to set</param>
/// <returns>True if value successfully sets; othewise, false</returns> /// <returns>True if value successfully sets; otherwise, false</returns>
public override bool Poke(string value) public override bool Poke(string value)
{ {
try try
@ -158,9 +139,9 @@ namespace BizHawk.Client.Common
break; break;
} }
if (Global.CheatList.Contains(Domain, _address)) if (Global.CheatList.Contains(Domain, Address))
{ {
var cheat = Global.CheatList.FirstOrDefault(c => c.Address == _address && c.Domain == Domain); var cheat = Global.CheatList.FirstOrDefault(c => c.Address == Address && c.Domain == Domain);
if (cheat != (Cheat)null) if (cheat != (Cheat)null)
{ {
cheat.PokeValue(val); cheat.PokeValue(val);
@ -194,7 +175,7 @@ namespace BizHawk.Client.Common
if (_value != temp) if (_value != temp)
{ {
_previous = temp; _previous = temp;
_changecount++; ChangeCount++;
} }
break; break;
@ -203,15 +184,13 @@ namespace BizHawk.Client.Common
_value = GetWord(); _value = GetWord();
if (_value != Previous) if (_value != Previous)
{ {
_changecount++; ChangeCount++;
} }
break; break;
} }
} }
#endregion Implements
// TODO: Implements IFormattable // TODO: Implements IFormattable
public string FormatValue(ushort val) public string FormatValue(ushort val)
{ {
@ -225,18 +204,12 @@ namespace BizHawk.Client.Common
case DisplayType.Hex: case DisplayType.Hex:
return val.ToHexString(4); return val.ToHexString(4);
case DisplayType.FixedPoint_12_4: case DisplayType.FixedPoint_12_4:
return string.Format("{0:F4}", val / 16.0); return $"{val / 16.0:F4}";
case DisplayType.Binary: case DisplayType.Binary:
return Convert.ToString(val, 2).PadLeft(16, '0').Insert(8, " ").Insert(4, " ").Insert(14, " "); return Convert.ToString(val, 2).PadLeft(16, '0').Insert(8, " ").Insert(4, " ").Insert(14, " ");
} }
} }
#endregion
#region Properties
#region Implements
/// <summary> /// <summary>
/// Get a string representation of difference /// Get a string representation of difference
/// between current value and the previous one /// between current value and the previous one
@ -256,79 +229,39 @@ namespace BizHawk.Client.Common
diff = "-"; diff = "-";
} }
return string.Format("{0}{1}", diff, FormatValue((ushort)Math.Abs(diffVal))); return $"{diff}{FormatValue((ushort)Math.Abs(diffVal))}";
} }
} }
/// <summary> /// <summary>
/// Get the maximum possible value /// Get the maximum possible value
/// </summary> /// </summary>
public override uint MaxValue public override uint MaxValue => ushort.MaxValue;
{
get
{
return ushort.MaxValue;
}
}
/// <summary> /// <summary>
/// Gets the current value /// Gets the current value
/// </summary> /// </summary>
public override int Value public override int Value => GetWord();
{
get
{
return GetWord();
}
}
/// <summary> /// <summary>
/// Gets the current value /// Gets the current value
/// but with stuff I don't understand /// but with stuff I don't understand
/// </summary> /// </summary>
public override int ValueNoFreeze public override int ValueNoFreeze => GetWord(true);
{
get
{
return GetWord(true);
}
}
/// <summary> /// <summary>
/// Get a string representation of the current value /// Get a string representation of the current value
/// </summary> /// </summary>
public override string ValueString public override string ValueString => FormatValue(GetWord());
{
get
{
return FormatValue(GetWord());
}
}
/// <summary> /// <summary>
/// Get the previous value /// Get the previous value
/// </summary> /// </summary>
public override int Previous public override int Previous => _previous;
{
get
{
return _previous;
}
}
/// <summary> /// <summary>
/// Get a string representation of the previous value /// Get a string representation of the previous value
/// </summary> /// </summary>
public override string PreviousStr public override string PreviousStr => FormatValue(_previous);
{
get
{
return FormatValue(_previous);
}
}
#endregion Implements
#endregion
} }
} }

View File

@ -20,11 +20,15 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLastIndexOfIsCultureSpecific_002E3/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLastIndexOfIsCultureSpecific_002E3/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1101/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1101/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1108/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1108/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1115/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1116/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1117/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1122/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1122/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1126/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1126/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1200/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1200/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1309/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1309/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1402/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1402/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1502/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1516/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1516/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1600/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1600/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1601/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StyleCop_002ESA1601/@EntryIndexedValue">DO_NOT_SHOW</s:String>