diff --git a/.gitignore b/.gitignore
index ead275a6c1..eb1c604da1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,8 @@
/BizHawk.Client.Common/bin
/BizHawk.Client.Common/obj
/BizHawk.Client.Common/Properties/svnrev.cs
+/BizHawk.Client.ApiHawk/bin
+/BizHawk.Client.ApiHawk/obj
/BizHawk.Client.DBMan/obj
/BizHawk.Client.DiscoHawk/obj
/BizHawk.Client.DiscoHawk/Properties/svnrev.cs
@@ -247,7 +249,7 @@
/References/*.xml
/output/ELFSharp.dll
/output/dll/ELFSharp.dll
-/output/ExternalTools/*.*
+/output/ExternalTools
*.opensdf
*.user
*.suo
@@ -263,3 +265,4 @@
/LuaInterface/Lua/src/.libs
/LuaInterface/Lua/src/Release-LUAPERKS
/LuaInterface/Release-LUAPERKS
+output/BizHawk.Client.ApiHawk.dll
diff --git a/BizHawk.Client.ApiHawk/Attributes/ConfigPersistAttribute.cs b/BizHawk.Client.ApiHawk/Attributes/ConfigPersistAttribute.cs
new file mode 100644
index 0000000000..ed1fbb1148
--- /dev/null
+++ b/BizHawk.Client.ApiHawk/Attributes/ConfigPersistAttribute.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Client.EmuHawk
+{
+ ///
+ /// Define if the property has to be persisted in config
+ ///
+ [AttributeUsage(AttributeTargets.Property)]
+ public class ConfigPersistAttribute : Attribute
+ {
+ }
+}
diff --git a/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj b/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj
new file mode 100644
index 0000000000..040a7ad46f
--- /dev/null
+++ b/BizHawk.Client.ApiHawk/BizHawk.Client.ApiHawk.csproj
@@ -0,0 +1,77 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}
+ Library
+ Properties
+ BizHawk.Client.ApiHawk
+ BizHawk.Client.ApiHawk
+ v4.0
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {24a0aa3c-b25f-4197-b23d-476d6462dba0}
+ BizHawk.Client.Common
+
+
+ {866f8d13-0678-4ff9-80a4-a3993fd4d8a3}
+ BizHawk.Common
+
+
+ {e1a23168-b571-411c-b360-2229e7225e0e}
+ BizHawk.Emulation.Common
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BizHawk.Client.EmuHawk/tools/IExternalToolForm.cs b/BizHawk.Client.ApiHawk/Interfaces/IExternalToolForm.cs
similarity index 100%
rename from BizHawk.Client.EmuHawk/tools/IExternalToolForm.cs
rename to BizHawk.Client.ApiHawk/Interfaces/IExternalToolForm.cs
diff --git a/BizHawk.Client.EmuHawk/tools/IToolForm.cs b/BizHawk.Client.ApiHawk/Interfaces/IToolForm.cs
similarity index 84%
rename from BizHawk.Client.EmuHawk/tools/IToolForm.cs
rename to BizHawk.Client.ApiHawk/Interfaces/IToolForm.cs
index e743ca98df..02ca163b93 100644
--- a/BizHawk.Client.EmuHawk/tools/IToolForm.cs
+++ b/BizHawk.Client.ApiHawk/Interfaces/IToolForm.cs
@@ -1,61 +1,50 @@
-using System;
-using System.Linq;
-using System.Collections.Generic;
-
-namespace BizHawk.Client.EmuHawk
-{
- public interface IToolForm
- {
- ///
- /// Will be called by the client anytime an Update needs to occur, such as after an emulated frame, a loadstate, or a related dialog has made a relevant change
- ///
- void UpdateValues();
-
- ///
- /// Will be called by the client when performance is critical,
- /// The tool should only do the minimum to still function,
- /// Drawing should not occur if possible, during a fast update
- ///
- void FastUpdate();
-
- ///
- /// Will be called anytime the dialog needs to be restarted, such as when a new ROM is loaded
- /// The tool implementing this needs to account for a Game and Core change
- ///
- void Restart();
-
- ///
- /// This gives the opportunity for the tool dialog to ask the user to save changes (such is necessary when
- /// This tool dialog edits a file. Returning false will tell the client the user wants to cancel the given action,
- /// Return false to tell the client to back out of an action (such as closing the emulator)
- ///
- ///
- bool AskSaveChanges();
-
- ///
- /// Indicates whether the tool should be updated before a frame loop or after.
- /// In general, tools that draw graphics from the core should update before the loop,
- /// Information tools such as those that display core ram values should be after.
- ///
- bool UpdateBefore { get; }
-
- //Necessary winform calls
- bool Focus();
- void Show();
- void Close();
- bool IsDisposed { get; }
- bool IsHandleCreated { get; }
- }
-
- ///
- /// toolform that takes automatic common configuration infrastructure
- ///
- public interface IToolFormAutoConfig : IToolForm
- {
- }
-
- [AttributeUsage(AttributeTargets.Property)]
- public class ConfigPersistAttribute : Attribute
- {
- }
-}
+using System;
+using System.Linq;
+using System.Collections.Generic;
+
+namespace BizHawk.Client.EmuHawk
+{
+ public interface IToolForm
+ {
+ ///
+ /// Will be called by the client anytime an Update needs to occur, such as after an emulated frame, a loadstate, or a related dialog has made a relevant change
+ ///
+ void UpdateValues();
+
+ ///
+ /// Will be called by the client when performance is critical,
+ /// The tool should only do the minimum to still function,
+ /// Drawing should not occur if possible, during a fast update
+ ///
+ void FastUpdate();
+
+ ///
+ /// Will be called anytime the dialog needs to be restarted, such as when a new ROM is loaded
+ /// The tool implementing this needs to account for a Game and Core change
+ ///
+ void Restart();
+
+ ///
+ /// This gives the opportunity for the tool dialog to ask the user to save changes (such is necessary when
+ /// This tool dialog edits a file. Returning false will tell the client the user wants to cancel the given action,
+ /// Return false to tell the client to back out of an action (such as closing the emulator)
+ ///
+ ///
+ bool AskSaveChanges();
+
+ ///
+ /// Indicates whether the tool should be updated before a frame loop or after.
+ /// In general, tools that draw graphics from the core should update before the loop,
+ /// Information tools such as those that display core ram values should be after.
+ ///
+ bool UpdateBefore { get; }
+
+ //Necessary winform calls
+ bool Focus();
+ void Show();
+ void Close();
+ bool IsDisposed { get; }
+ bool IsHandleCreated { get; }
+ }
+}
+
diff --git a/BizHawk.Client.ApiHawk/Interfaces/IToolFormAutoConfig.cs b/BizHawk.Client.ApiHawk/Interfaces/IToolFormAutoConfig.cs
new file mode 100644
index 0000000000..5def3b37be
--- /dev/null
+++ b/BizHawk.Client.ApiHawk/Interfaces/IToolFormAutoConfig.cs
@@ -0,0 +1,15 @@
+using BizHawk.Client.EmuHawk;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Client.EmuHawk
+{
+ ///
+ /// toolform that takes automatic common configuration infrastructure
+ ///
+ public interface IToolFormAutoConfig : IToolForm
+ {
+ }
+}
diff --git a/BizHawk.Client.ApiHawk/Properties/AssemblyInfo.cs b/BizHawk.Client.ApiHawk/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..66ceacbb35
--- /dev/null
+++ b/BizHawk.Client.ApiHawk/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("BizHawk.Client.ApiHawk")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("BizHawk.Client.ApiHawk")]
+[assembly: AssemblyCopyright("Copyright © 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("8e2f11f2-3955-4382-8c3a-ceba1276caea")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/BizHawk.Client.ApiHawk/Resources/ApiClassDiagram.cd b/BizHawk.Client.ApiHawk/Resources/ApiClassDiagram.cd
new file mode 100644
index 0000000000..721fa5defc
--- /dev/null
+++ b/BizHawk.Client.ApiHawk/Resources/ApiClassDiagram.cd
@@ -0,0 +1,79 @@
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Attributes\ConfigPersistAttribute.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Interfaces\IExternalToolForm.cs
+
+
+
+
+
+ ECAAAAAAAABACAAgAAEAABAAAAAEAAAAAAAAAACAQAA=
+ Interfaces\IToolForm.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
+ Interfaces\IToolFormAutoConfig.cs
+
+
+
+
\ No newline at end of file
diff --git a/BizHawk.Client.Common/BizHawk.Client.Common.csproj b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
index c35c7ad9d1..c4dc2d0063 100644
--- a/BizHawk.Client.Common/BizHawk.Client.Common.csproj
+++ b/BizHawk.Client.Common/BizHawk.Client.Common.csproj
@@ -232,9 +232,16 @@
+
+
+
+
-
-
+
+
+
+
+
@@ -267,6 +274,7 @@
BizHawk.Bizware.BizwareGL
+
diff --git a/BizHawk.Client.Common/tools/Watch.cs b/BizHawk.Client.Common/tools/Watch.cs
deleted file mode 100644
index 87786391d9..0000000000
--- a/BizHawk.Client.Common/tools/Watch.cs
+++ /dev/null
@@ -1,1235 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-
-using BizHawk.Common;
-using BizHawk.Common.NumberExtensions;
-using BizHawk.Common.StringExtensions;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Client.Common
-{
- public abstract class Watch
- {
- public enum WatchSize { Byte = 1, Word = 2, DWord = 4, Separator = 0 }
- public enum DisplayType { Separator, Signed, Unsigned, Hex, Binary, FixedPoint_12_4, FixedPoint_20_12, FixedPoint_16_16, Float }
- public enum PreviousType { Original = 0, LastSearch = 1, LastFrame = 2, LastChange = 3 }
-
- public static Watch FromString(string line, IMemoryDomains domains)
- {
- try
- {
- var parts = line.Split(new[] { '\t' }, 6);
-
- if (parts.Length < 6)
- {
- if (parts.Length >= 3 && parts[2] == "_")
- {
- return SeparatorWatch.Instance;
- }
-
- return null;
- }
-
- var address = long.Parse(parts[0], NumberStyles.HexNumber);
- var size = Watch.SizeFromChar(parts[1][0]);
- var type = Watch.DisplayTypeFromChar(parts[2][0]);
- var bigEndian = parts[3] == "0" ? false : true;
- var domain = domains[parts[4]];
- var notes = parts[5].Trim(new[] { '\r', '\n' });
-
- return Watch.GenerateWatch(
- domain,
- address,
- size,
- type,
- notes,
- bigEndian
- );
- }
- catch
- {
- return null;
- }
- }
-
- public static string ToString(Watch watch, MemoryDomain domain)
- {
- var numDigits = (domain.Size - 1).NumHexDigits();
-
- var sb = new StringBuilder();
-
- sb
- .Append((watch.Address ?? 0).ToHexString(numDigits)).Append('\t')
- .Append(watch.SizeAsChar).Append('\t')
- .Append(watch.TypeAsChar).Append('\t')
- .Append(watch.BigEndian ? '1' : '0').Append('\t')
- .Append(watch.DomainName).Append('\t')
- .Append(watch.Notes.Trim(new[] { '\r', '\n' }));
-
- return sb.ToString();
- }
-
- public static string DisplayTypeToString(DisplayType type)
- {
- switch (type)
- {
- default:
- return type.ToString();
- case DisplayType.FixedPoint_12_4:
- return "Fixed Point 12.4";
- case DisplayType.FixedPoint_20_12:
- return "Fixed Point 20.12";
- case DisplayType.FixedPoint_16_16:
- return "Fixed Point 16.16";
- }
- }
-
- public static DisplayType StringToDisplayType(string name)
- {
- switch (name)
- {
- default:
- return (DisplayType)Enum.Parse(typeof(DisplayType), name);
- case "Fixed Point 12.4":
- return DisplayType.FixedPoint_12_4;
- case "Fixed Point 20.12":
- return DisplayType.FixedPoint_20_12;
- case "Fixed Point 16.16":
- return DisplayType.FixedPoint_16_16;
- }
- }
-
- protected long _address;
- protected MemoryDomain _domain;
- protected DisplayType _type;
- protected bool _bigEndian;
- protected int _changecount;
- protected string _notes = string.Empty;
-
- public abstract int? Value { get; }
- public abstract string ValueString { get; }
- public abstract WatchSize Size { get; }
-
- //zero 15-nov-2015 - bypass LIAR LOGIC, see fdc9ea2aa922876d20ba897fb76909bf75fa6c92 https://github.com/TASVideos/BizHawk/issues/326
- public abstract int? ValueNoFreeze { get; }
-
- public abstract uint MaxValue { get; }
-
- public abstract int? Previous { get; }
- public abstract string PreviousStr { get; }
- public abstract void ResetPrevious();
-
- public abstract bool Poke(string value);
-
- public virtual DisplayType Type { get { return _type; } set { _type = value; } }
- public virtual bool BigEndian { get { return _bigEndian; } set { _bigEndian = value; } }
-
- public MemoryDomain Domain { get { return _domain; } set { _domain = value; } }
-
- public string DomainName { get { return _domain != null ? _domain.Name : string.Empty; } }
-
- public virtual long? Address { get { return _address; } }
-
- public virtual string AddressString { get { return _address.ToString(AddressFormatStr); } }
-
- public virtual bool IsSeparator { get { return false; } }
-
- public char SizeAsChar
- {
- get
- {
- switch (Size)
- {
- default:
- case WatchSize.Separator:
- return 'S';
- case WatchSize.Byte:
- return 'b';
- case WatchSize.Word:
- return 'w';
- case WatchSize.DWord:
- return 'd';
- }
- }
- }
-
- public static WatchSize SizeFromChar(char c)
- {
- switch (c)
- {
- default:
- case 'S':
- return WatchSize.Separator;
- case 'b':
- return WatchSize.Byte;
- case 'w':
- return WatchSize.Word;
- case 'd':
- return WatchSize.DWord;
- }
- }
-
- public char TypeAsChar
- {
- get
- {
- switch (Type)
- {
- default:
- case DisplayType.Separator:
- return '_';
- case DisplayType.Unsigned:
- return 'u';
- case DisplayType.Signed:
- return 's';
- case DisplayType.Hex:
- return 'h';
- case DisplayType.Binary:
- return 'b';
- case DisplayType.FixedPoint_12_4:
- return '1';
- case DisplayType.FixedPoint_20_12:
- return '2';
- case DisplayType.FixedPoint_16_16:
- return '3';
- case DisplayType.Float:
- return 'f';
- }
- }
- }
-
- public static DisplayType DisplayTypeFromChar(char c)
- {
- switch (c)
- {
- default:
- case '_':
- return DisplayType.Separator;
- case 'u':
- return DisplayType.Unsigned;
- case 's':
- return DisplayType.Signed;
- case 'h':
- return DisplayType.Hex;
- case 'b':
- return DisplayType.Binary;
- case '1':
- return DisplayType.FixedPoint_12_4;
- case '2':
- return DisplayType.FixedPoint_20_12;
- case '3':
- return DisplayType.FixedPoint_16_16;
- case 'f':
- return DisplayType.Float;
- }
- }
-
- public string AddressFormatStr
- {
- get
- {
- if (_domain != null)
- {
- return "X" + (_domain.Size - 1).NumHexDigits();
- }
-
- return string.Empty;
- }
- }
-
- protected byte GetByte(bool bypassFreeze = false)
- {
- if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
- {
- //LIAR logic
- return Global.CheatList.GetByteValue(_domain, _address).Value;
- }
- else
- {
- if (_domain.Size == 0)
- {
- return _domain.PeekByte(_address);
- }
- else
- {
- return _domain.PeekByte(_address % _domain.Size);
- }
- }
- }
-
- protected ushort GetWord(bool bypassFreeze = false)
- {
- if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
- {
- //LIAR logic
- return (ushort)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.Word).Value;
- }
- else
- {
- if (_domain.Size == 0)
- {
- return _domain.PeekWord(_address, _bigEndian);
- }
- else
- {
- return _domain.PeekWord(_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)
- {
- if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
- {
- //LIAR logic
- return (uint)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.DWord).Value;
- }
- else
- {
- if (_domain.Size == 0)
- {
- return _domain.PeekDWord(_address, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
- }
- else
- {
- return _domain.PeekDWord(_address % _domain.Size, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
- }
- }
- }
-
- protected void PokeByte(byte val)
- {
- if(_domain.Size == 0)
- _domain.PokeByte(_address, val);
- else _domain.PokeByte(_address % _domain.Size, val);
- }
-
- protected void PokeWord(ushort val)
- {
- if (_domain.Size == 0)
- _domain.PokeWord(_address, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
- else _domain.PokeWord(_address % _domain.Size, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
- }
-
- protected void PokeDWord(uint val)
- {
- if (_domain.Size == 0)
- _domain.PokeDWord(_address, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
- else _domain.PokeDWord(_address % _domain.Size, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
- }
-
- public void ClearChangeCount() { _changecount = 0; }
-
- public bool IsOutOfRange
- {
- get
- {
- return !IsSeparator && (Domain.Size != 0 && Address.Value >= Domain.Size);
- }
- }
-
- public string Notes { get { return _notes; } set { _notes = value; } }
-
- public static Watch GenerateWatch(MemoryDomain domain, long address, WatchSize size, DisplayType type, string notes, bool bigEndian)
- {
- switch (size)
- {
- default:
- case WatchSize.Separator:
- return SeparatorWatch.Instance;
- case WatchSize.Byte:
- return new ByteWatch(domain, address, type, bigEndian, notes);
- case WatchSize.Word:
- return new WordWatch(domain, address, type, bigEndian, notes);
- case WatchSize.DWord:
- return new DWordWatch(domain, address, type, bigEndian, notes);
- }
- }
-
- public static Watch GenerateWatch(MemoryDomain domain, long address, WatchSize size, DisplayType type, bool bigendian, long prev, int changecount)
- {
- switch (size)
- {
- default:
- case WatchSize.Separator:
- return SeparatorWatch.Instance;
- case WatchSize.Byte:
- return new ByteWatch(domain, address, type, bigendian, (byte)prev, changecount);
- case WatchSize.Word:
- return new WordWatch(domain, address, type, bigendian, (ushort)prev, changecount);
- case WatchSize.DWord:
- return new DWordWatch(domain, address, type, bigendian, (uint)prev, changecount);
- }
- }
-
- public static List AvailableTypes(WatchSize size)
- {
- switch (size)
- {
- default:
- case WatchSize.Separator:
- return SeparatorWatch.ValidTypes;
- case WatchSize.Byte:
- return ByteWatch.ValidTypes;
- case WatchSize.Word:
- return WordWatch.ValidTypes;
- case WatchSize.DWord:
- return DWordWatch.ValidTypes;
- }
- }
-
- public int ChangeCount { get { return _changecount; } }
-
- public abstract string Diff { get; }
-
- public abstract void Update();
-
- public override bool Equals(object obj)
- {
- if (obj is Watch)
- {
- var watch = obj as Watch;
-
- return this.Domain == watch.Domain &&
- this.Address == watch.Address &&
- this.Size == watch.Size &&
- this.Type == watch.Type &&
- this.Notes == watch.Notes;
- }
-
- if (obj is Cheat)
- {
- var cheat = obj as Cheat;
- return this.Domain == cheat.Domain && this.Address == cheat.Address;
- }
-
- return base.Equals(obj);
- }
-
- public override int GetHashCode()
- {
- return this.Domain.GetHashCode() + (int)(this.Address ?? 0);
- }
-
- public static bool operator ==(Watch a, Watch b)
- {
- // If one is null, but not both, return false.
- if (((object)a == null) || ((object)b == null))
- {
- return false;
- }
-
- return a.Equals(b);
- }
-
- public static bool operator !=(Watch a, Watch b)
- {
- return !a.Equals(b);
- }
-
- public static bool operator ==(Watch a, Cheat b)
- {
- // If one is null, but not both, return false.
- if (((object)a == null) || ((object)b == null))
- {
- return false;
- }
-
- return a.Domain == b.Domain && a.Address == b.Address;
- }
-
- public static bool operator !=(Watch a, Cheat b)
- {
- return !(a == b);
- }
- }
-
- public sealed class SeparatorWatch : Watch
- {
- public static SeparatorWatch Instance
- {
- get { return new SeparatorWatch(); }
- }
-
- public override long? Address
- {
- get { return null; }
- }
-
- public override int? Value
- {
- get { return null; }
- }
-
- public override int? ValueNoFreeze
- {
- get { return null; }
- }
-
- public override int? Previous
- {
- get { return null; }
- }
-
- public override string AddressString
- {
- get { return string.Empty; }
- }
-
- public override string ValueString
- {
- get { return string.Empty; }
- }
-
- public override string PreviousStr
- {
- get { return string.Empty; }
- }
-
- public override string ToString()
- {
- return "----";
- }
-
- public override bool IsSeparator
- {
- get { return true; }
- }
-
- public override WatchSize Size
- {
- get { return WatchSize.Separator; }
- }
-
- public static List ValidTypes
- {
- get { return new List { DisplayType.Separator }; }
- }
-
- public override DisplayType Type
- {
- get { return DisplayType.Separator; }
- }
-
- public override bool Poke(string value)
- {
- return false;
- }
-
- public override void ResetPrevious()
- {
- return;
- }
-
- public override string Diff { get { return string.Empty; } }
-
- public override uint MaxValue
- {
- get { return 0; }
- }
-
- public override void Update() { return; }
- }
-
- public sealed class ByteWatch : Watch
- {
- private byte _previous;
- private byte _value;
-
- public ByteWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string notes)
- {
- _address = address;
- _domain = domain;
- _value = _previous = GetByte();
- if (AvailableTypes(WatchSize.Byte).Contains(type))
- {
- _type = type;
- }
-
- _bigEndian = bigEndian;
- if (notes != null)
- {
- Notes = notes;
- }
- }
-
- public ByteWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, byte prev, int changeCount, string notes = null)
- : this(domain, address, type, bigEndian, notes)
- {
- _previous = prev;
- _changecount = changeCount;
- }
-
- public override long? Address
- {
- get { return _address; }
- }
-
- public override int? Value
- {
- get { return GetByte(); }
- }
-
- public override int? ValueNoFreeze
- {
- get { return GetByte(true); }
- }
-
- public override string ValueString
- {
- get { return FormatValue(GetByte()); }
- }
-
- public override int? Previous
- {
- get { return _previous; }
- }
-
- public override string PreviousStr
- {
- get { return FormatValue(_previous); }
- }
-
- public override void ResetPrevious()
- {
- _previous = GetByte();
- }
-
- public override string ToString()
- {
- return Notes + ": " + ValueString;
- }
-
- public override bool IsSeparator
- {
- get { return false; }
- }
-
- public override WatchSize Size
- {
- get { return WatchSize.Byte; }
- }
-
- public static List ValidTypes
- {
- get
- {
- return new List
- {
- DisplayType.Unsigned, DisplayType.Signed, DisplayType.Hex, DisplayType.Binary
- };
- }
- }
-
- public override uint MaxValue
- {
- get { return byte.MaxValue; }
- }
-
- 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, " ");
- }
- }
-
- public override bool Poke(string value)
- {
- try
- {
- byte val = 0;
- switch (Type)
- {
- case DisplayType.Unsigned:
- if ( value.IsUnsigned())
- {
- val = (byte)int.Parse(value);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.Signed:
- if (value.IsSigned())
- {
- val = (byte)(sbyte)int.Parse(value);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.Hex:
- if (value.IsHex())
- {
- val = (byte)int.Parse(value, NumberStyles.HexNumber);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.Binary:
- if (value.IsBinary())
- {
- val = (byte)Convert.ToInt32(value, 2);
- }
- else
- {
- return false;
- }
-
- break;
- }
-
- if (Global.CheatList.Contains(Domain, _address))
- {
- var cheat = Global.CheatList.FirstOrDefault(c => c.Address == _address && c.Domain == Domain);
-
- if (cheat != (Cheat)null)
- {
- cheat.PokeValue(val);
- PokeByte(val);
- return true;
- }
- }
-
- PokeByte(val);
- return true;
- }
- catch
- {
- return false;
- }
- }
-
- public override string Diff
- {
- get
- {
- var diff = string.Empty;
- var diffVal = _value - _previous;
- if (diffVal > 0)
- {
- diff = "+";
- }
- else if (diffVal < 0)
- {
- diff = "-";
- }
-
- return diff + FormatValue((byte)(_previous - _value));
- }
- }
-
- 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;
- }
- }
- }
-
- public sealed class WordWatch : Watch
- {
- private ushort _previous;
- private ushort _value;
-
- public WordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string notes)
- {
- _domain = domain;
- _address = address;
- _value = _previous = GetWord();
-
- if (AvailableTypes(WatchSize.Word).Contains(type))
- {
- _type = type;
- }
-
- _bigEndian = bigEndian;
-
- if (notes != null)
- {
- Notes = notes;
- }
- }
-
- public WordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, ushort prev, int changeCount, string notes = null)
- : this(domain, address, type, bigEndian, notes)
- {
- _previous = prev;
- _changecount = changeCount;
- }
-
- 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); }
- }
-
- public override void ResetPrevious()
- {
- _previous = GetWord();
- }
-
- public override WatchSize Size
- {
- get { return WatchSize.Word; }
- }
-
- public static List ValidTypes
- {
- get
- {
- return new List
- {
- DisplayType.Unsigned, DisplayType.Signed, DisplayType.Hex, DisplayType.FixedPoint_12_4, DisplayType.Binary
- };
- }
- }
-
- 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, " ");
- }
- }
-
- public override bool Poke(string value)
- {
- try
- {
- ushort val = 0;
- switch (Type)
- {
- case DisplayType.Unsigned:
- if (value.IsUnsigned())
- {
- val = (ushort)int.Parse(value);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.Signed:
- if (value.IsSigned())
- {
- val = (ushort)(short)int.Parse(value);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.Hex:
- if (value.IsHex())
- {
- val = (ushort)int.Parse(value, NumberStyles.HexNumber);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.Binary:
- if (value.IsBinary())
- {
- val = (ushort)Convert.ToInt32(value, 2);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.FixedPoint_12_4:
- if (value.IsFixedPoint())
- {
- val = (ushort)(double.Parse(value) * 16.0);
- }
- else
- {
- return false;
- }
-
- break;
- }
-
- if (Global.CheatList.Contains(Domain, _address))
- {
- var cheat = Global.CheatList.FirstOrDefault(c => c.Address == _address && c.Domain == Domain);
- if (cheat != (Cheat)null)
- {
- cheat.PokeValue(val);
- PokeWord(val);
- return true;
- }
- }
-
- PokeWord(val);
- return true;
- }
- catch
- {
- return false;
- }
- }
-
- public override string Diff
- {
- get { return FormatValue((ushort)(_previous - _value)); }
- }
-
- public override void Update()
- {
- switch (Global.Config.RamWatchDefinePrevious)
- {
- case PreviousType.Original:
- return;
- case PreviousType.LastChange:
- var temp = _value;
- _value = GetWord();
-
- if (_value != temp)
- {
- _previous = temp;
- _changecount++;
- }
-
- break;
- case PreviousType.LastFrame:
- _previous = _value;
- _value = GetWord();
- if (_value != Previous)
- {
- _changecount++;
- }
-
- break;
- }
- }
- }
-
- public sealed class DWordWatch : Watch
- {
- private uint _value;
- private uint _previous;
-
- public DWordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string notes)
- {
- _domain = domain;
- _address = address;
- _value = _previous = GetDWord();
-
- if (AvailableTypes(WatchSize.DWord).Contains(type))
- {
- _type = type;
- }
-
- _bigEndian = bigEndian;
-
- if (notes != null)
- {
- Notes = notes;
- }
- }
-
- public DWordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, uint prev, int changeCount, string notes = null)
- : this(domain, address, type, bigEndian, notes)
- {
- _previous = prev;
- _changecount = changeCount;
- _type = type;
- _bigEndian = bigEndian;
- }
-
- 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); }
- }
-
- public override void ResetPrevious()
- {
- _previous = GetWord();
- }
-
- public override WatchSize Size
- {
- get { return WatchSize.DWord; }
- }
-
- public static List ValidTypes
- {
- get
- {
- return new List
- {
- DisplayType.Unsigned, DisplayType.Signed, DisplayType.Hex, DisplayType.FixedPoint_20_12, DisplayType.FixedPoint_16_16, DisplayType.Float
- };
- }
- }
-
- 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
- }
- }
-
- public override bool Poke(string value)
- {
- try
- {
- uint val = 0;
- switch (Type)
- {
- case DisplayType.Unsigned:
- if (value.IsUnsigned())
- {
- val = (uint)int.Parse(value);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.Signed:
- if (value.IsSigned())
- {
- val = (uint)int.Parse(value);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.Hex:
- if (value.IsHex())
- {
- val = (uint)int.Parse(value, NumberStyles.HexNumber);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.FixedPoint_20_12:
- if (value.IsFixedPoint())
- {
- val = (uint)(int)(double.Parse(value) * 4096.0);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.FixedPoint_16_16:
- if (value.IsFixedPoint())
- {
- val = (uint)(int)(double.Parse(value) * 65536.0);
- }
- else
- {
- return false;
- }
-
- break;
- case DisplayType.Float:
- if (value.IsFloat())
- {
- var bytes = BitConverter.GetBytes(float.Parse(value));
- val = BitConverter.ToUInt32(bytes, 0);
- }
- else
- {
- return false;
- }
-
- break;
- }
-
- if (Global.CheatList.Contains(Domain, _address))
- {
- var cheat = Global.CheatList.FirstOrDefault(c => c.Address == _address && c.Domain == Domain);
- if (cheat != (Cheat)null)
- {
- cheat.PokeValue((int)val);
- PokeDWord(val);
- return true;
- }
- }
-
- PokeDWord(val);
- return true;
- }
- catch
- {
- return false;
- }
- }
-
- public override string Diff
- {
- get { return FormatValue(_previous - _value); }
- }
-
- public override void Update()
- {
- switch (Global.Config.RamWatchDefinePrevious)
- {
- case PreviousType.Original:
- return;
- case PreviousType.LastChange:
- var temp = _value;
- _value = GetDWord();
- if (_value != temp)
- {
- _previous = _value;
- _changecount++;
- }
-
- break;
- case PreviousType.LastFrame:
- _previous = _value;
- _value = GetDWord();
- if (_value != Previous)
- {
- _changecount++;
- }
-
- break;
- }
- }
- }
-}
diff --git a/BizHawk.Client.Common/tools/Watch/ByteWatch.cs b/BizHawk.Client.Common/tools/Watch/ByteWatch.cs
new file mode 100644
index 0000000000..9bfe89a6e4
--- /dev/null
+++ b/BizHawk.Client.Common/tools/Watch/ByteWatch.cs
@@ -0,0 +1,243 @@
+using BizHawk.Common.NumberExtensions;
+using BizHawk.Common.StringExtensions;
+using BizHawk.Emulation.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+
+namespace BizHawk.Client.Common
+{
+ public sealed class ByteWatch : Watch
+ {
+ private byte _previous;
+ private byte _value;
+
+ public ByteWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string notes)
+ {
+ _address = address;
+ _domain = domain;
+ _value = _previous = GetByte();
+ if (AvailableTypes(WatchSize.Byte).Contains(type))
+ {
+ _type = type;
+ }
+
+ _bigEndian = bigEndian;
+ if (notes != null)
+ {
+ Notes = notes;
+ }
+ }
+
+ public ByteWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, byte prev, int changeCount, string notes = null)
+ : this(domain, address, type, bigEndian, notes)
+ {
+ _previous = prev;
+ _changecount = changeCount;
+ }
+
+ public override long? Address
+ {
+ get { return _address; }
+ }
+
+ public override int? Value
+ {
+ get { return GetByte(); }
+ }
+
+ public override int? ValueNoFreeze
+ {
+ get { return GetByte(true); }
+ }
+
+ public override string ValueString
+ {
+ get { return FormatValue(GetByte()); }
+ }
+
+ public override int? Previous
+ {
+ get { return _previous; }
+ }
+
+ public override string PreviousStr
+ {
+ get { return FormatValue(_previous); }
+ }
+
+ public override void ResetPrevious()
+ {
+ _previous = GetByte();
+ }
+
+ public override string ToString()
+ {
+ return Notes + ": " + ValueString;
+ }
+
+ public override bool IsSeparator
+ {
+ get { return false; }
+ }
+
+ public override WatchSize Size
+ {
+ get { return WatchSize.Byte; }
+ }
+
+ public static List ValidTypes
+ {
+ get
+ {
+ return new List
+ {
+ DisplayType.Unsigned, DisplayType.Signed, DisplayType.Hex, DisplayType.Binary
+ };
+ }
+ }
+
+ public override uint MaxValue
+ {
+ get { return byte.MaxValue; }
+ }
+
+ 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, " ");
+ }
+ }
+
+ public override bool Poke(string value)
+ {
+ try
+ {
+ byte val = 0;
+ switch (Type)
+ {
+ case DisplayType.Unsigned:
+ if (value.IsUnsigned())
+ {
+ val = (byte)int.Parse(value);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.Signed:
+ if (value.IsSigned())
+ {
+ val = (byte)(sbyte)int.Parse(value);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.Hex:
+ if (value.IsHex())
+ {
+ val = (byte)int.Parse(value, NumberStyles.HexNumber);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.Binary:
+ if (value.IsBinary())
+ {
+ val = (byte)Convert.ToInt32(value, 2);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ }
+
+ if (Global.CheatList.Contains(Domain, _address))
+ {
+ var cheat = Global.CheatList.FirstOrDefault(c => c.Address == _address && c.Domain == Domain);
+
+ if (cheat != (Cheat)null)
+ {
+ cheat.PokeValue(val);
+ PokeByte(val);
+ return true;
+ }
+ }
+
+ PokeByte(val);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public override string Diff
+ {
+ get
+ {
+ var diff = string.Empty;
+ var diffVal = _value - _previous;
+ if (diffVal > 0)
+ {
+ diff = "+";
+ }
+ else if (diffVal < 0)
+ {
+ diff = "-";
+ }
+
+ return diff + FormatValue((byte)(_previous - _value));
+ }
+ }
+
+ 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;
+ }
+ }
+ }
+}
diff --git a/BizHawk.Client.Common/tools/Watch/DisplayType.cs b/BizHawk.Client.Common/tools/Watch/DisplayType.cs
new file mode 100644
index 0000000000..16f9835364
--- /dev/null
+++ b/BizHawk.Client.Common/tools/Watch/DisplayType.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Client.Common
+{
+ public abstract partial class Watch
+ {
+ ///
+ /// This enum is used to specify how you want your to be displayed
+ ///
+ public enum DisplayType
+ {
+ ///
+ /// Separator, only used by
+ ///
+ Separator,
+ ///
+ /// Display the value as a signed integer
+ /// Used by , and
+ ///
+ Signed,
+ ///
+ /// Display the value as an unsigned integer
+ /// Used by , and
+ ///
+ Unsigned,
+ ///
+ /// Raw hexadecimal display
+ /// Used by , and
+ ///
+ Hex,
+ ///
+ /// Raw binary display
+ /// Used by , and
+ /// If you can read it easily, you're probably a computer
+ ///
+ Binary,
+ ///
+ /// Display the value as fractionnal number. 12 before coma and 4 after
+ /// Used only by as it is 16 bits length
+ ///
+ FixedPoint_12_4,
+ ///
+ /// Display the value as fractionnal number. 20 before coma and 12 after
+ /// Used only by as it is 32 bits length
+ ///
+ FixedPoint_20_12,
+ ///
+ /// Display the value as fractionnal number. 16 before coma and 16 after
+ /// Used only by as it is 32 bits length
+ ///
+ FixedPoint_16_16,
+ ///
+ /// The traditionnal float type as in C++
+ /// Used only by as it is 32 bits length
+ ///
+ Float
+ }
+ }
+}
diff --git a/BizHawk.Client.Common/tools/Watch/DwordWatch.cs b/BizHawk.Client.Common/tools/Watch/DwordWatch.cs
new file mode 100644
index 0000000000..e0a2c2f717
--- /dev/null
+++ b/BizHawk.Client.Common/tools/Watch/DwordWatch.cs
@@ -0,0 +1,253 @@
+using BizHawk.Common.NumberExtensions;
+using BizHawk.Common.StringExtensions;
+using BizHawk.Emulation.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Client.Common
+{
+ public sealed class DWordWatch : Watch
+ {
+ private uint _value;
+ private uint _previous;
+
+ public DWordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string notes)
+ {
+ _domain = domain;
+ _address = address;
+ _value = _previous = GetDWord();
+
+ if (AvailableTypes(WatchSize.DWord).Contains(type))
+ {
+ _type = type;
+ }
+
+ _bigEndian = bigEndian;
+
+ if (notes != null)
+ {
+ Notes = notes;
+ }
+ }
+
+ public DWordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, uint prev, int changeCount, string notes = null)
+ : this(domain, address, type, bigEndian, notes)
+ {
+ _previous = prev;
+ _changecount = changeCount;
+ _type = type;
+ _bigEndian = bigEndian;
+ }
+
+ 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); }
+ }
+
+ public override void ResetPrevious()
+ {
+ _previous = GetWord();
+ }
+
+ public override WatchSize Size
+ {
+ get { return WatchSize.DWord; }
+ }
+
+ public static List ValidTypes
+ {
+ get
+ {
+ return new List
+ {
+ DisplayType.Unsigned, DisplayType.Signed, DisplayType.Hex, DisplayType.FixedPoint_20_12, DisplayType.FixedPoint_16_16, DisplayType.Float
+ };
+ }
+ }
+
+ 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
+ }
+ }
+
+ public override bool Poke(string value)
+ {
+ try
+ {
+ uint val = 0;
+ switch (Type)
+ {
+ case DisplayType.Unsigned:
+ if (value.IsUnsigned())
+ {
+ val = (uint)int.Parse(value);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.Signed:
+ if (value.IsSigned())
+ {
+ val = (uint)int.Parse(value);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.Hex:
+ if (value.IsHex())
+ {
+ val = (uint)int.Parse(value, NumberStyles.HexNumber);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.FixedPoint_20_12:
+ if (value.IsFixedPoint())
+ {
+ val = (uint)(int)(double.Parse(value) * 4096.0);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.FixedPoint_16_16:
+ if (value.IsFixedPoint())
+ {
+ val = (uint)(int)(double.Parse(value) * 65536.0);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.Float:
+ if (value.IsFloat())
+ {
+ var bytes = BitConverter.GetBytes(float.Parse(value));
+ val = BitConverter.ToUInt32(bytes, 0);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ }
+
+ if (Global.CheatList.Contains(Domain, _address))
+ {
+ var cheat = Global.CheatList.FirstOrDefault(c => c.Address == _address && c.Domain == Domain);
+ if (cheat != (Cheat)null)
+ {
+ cheat.PokeValue((int)val);
+ PokeDWord(val);
+ return true;
+ }
+ }
+
+ PokeDWord(val);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public override string Diff
+ {
+ get { return FormatValue(_previous - _value); }
+ }
+
+ public override void Update()
+ {
+ switch (Global.Config.RamWatchDefinePrevious)
+ {
+ case PreviousType.Original:
+ return;
+ case PreviousType.LastChange:
+ var temp = _value;
+ _value = GetDWord();
+ if (_value != temp)
+ {
+ _previous = _value;
+ _changecount++;
+ }
+
+ break;
+ case PreviousType.LastFrame:
+ _previous = _value;
+ _value = GetDWord();
+ if (_value != Previous)
+ {
+ _changecount++;
+ }
+
+ break;
+ }
+ }
+ }
+}
diff --git a/BizHawk.Client.Common/tools/Watch/PreviousType.cs b/BizHawk.Client.Common/tools/Watch/PreviousType.cs
new file mode 100644
index 0000000000..05e38ca406
--- /dev/null
+++ b/BizHawk.Client.Common/tools/Watch/PreviousType.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Client.Common
+{
+ public abstract partial class Watch
+ {
+ public enum PreviousType
+ {
+ Original = 0,
+ LastSearch = 1,
+ LastFrame = 2,
+ LastChange = 3
+ }
+ }
+}
diff --git a/BizHawk.Client.Common/tools/Watch/SeparatorWatch.cs b/BizHawk.Client.Common/tools/Watch/SeparatorWatch.cs
new file mode 100644
index 0000000000..7b6d0d5cc8
--- /dev/null
+++ b/BizHawk.Client.Common/tools/Watch/SeparatorWatch.cs
@@ -0,0 +1,91 @@
+using System.Collections.Generic;
+
+namespace BizHawk.Client.Common
+{
+ public sealed class SeparatorWatch : Watch
+ {
+ public static SeparatorWatch Instance
+ {
+ get { return new SeparatorWatch(); }
+ }
+
+ public override long? Address
+ {
+ get { return null; }
+ }
+
+ public override int? Value
+ {
+ get { return null; }
+ }
+
+ public override int? ValueNoFreeze
+ {
+ get { return null; }
+ }
+
+ public override int? Previous
+ {
+ get { return null; }
+ }
+
+ public override string AddressString
+ {
+ get { return string.Empty; }
+ }
+
+ public override string ValueString
+ {
+ get { return string.Empty; }
+ }
+
+ public override string PreviousStr
+ {
+ get { return string.Empty; }
+ }
+
+ public override string ToString()
+ {
+ return "----";
+ }
+
+ public override bool IsSeparator
+ {
+ get { return true; }
+ }
+
+ public override WatchSize Size
+ {
+ get { return WatchSize.Separator; }
+ }
+
+ public static List ValidTypes
+ {
+ get { return new List { DisplayType.Separator }; }
+ }
+
+ public override DisplayType Type
+ {
+ get { return DisplayType.Separator; }
+ }
+
+ public override bool Poke(string value)
+ {
+ return false;
+ }
+
+ public override void ResetPrevious()
+ {
+ return;
+ }
+
+ public override string Diff { get { return string.Empty; } }
+
+ public override uint MaxValue
+ {
+ get { return 0; }
+ }
+
+ public override void Update() { return; }
+ }
+}
diff --git a/BizHawk.Client.Common/tools/Watch/Watch.cs b/BizHawk.Client.Common/tools/Watch/Watch.cs
new file mode 100644
index 0000000000..005f8d8b76
--- /dev/null
+++ b/BizHawk.Client.Common/tools/Watch/Watch.cs
@@ -0,0 +1,548 @@
+using BizHawk.Common.NumberExtensions;
+using BizHawk.Emulation.Common;
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+
+namespace BizHawk.Client.Common
+{
+ public abstract partial class Watch
+ {
+ #region Fields
+
+ protected long _address;
+ protected MemoryDomain _domain;
+ protected DisplayType _type;
+ protected bool _bigEndian;
+ protected int _changecount;
+ protected string _notes = string.Empty;
+
+ #endregion
+
+ #region Methods
+
+ #region Static
+
+ ///
+ /// Generate a from a given string
+ /// String is tab separate
+ ///
+ /// Entire string, tab seperated for each value Order is:
+ ///
+ /// -
+ /// 0x00
+ /// Address in hexadecimal
+ ///
+ /// -
+ /// b,w or d
+ /// The , byte, word or double word
+ /// s, u, h, b, 1, 2, 3, f
+ /// The signed, unsigned,etc...
+ ///
+ /// -
+ /// 0 or 1
+ /// Big endian or not
+ ///
+ /// -
+ /// RDRAM,ROM,...
+ /// The
+ ///
+ /// -
+ /// Plain text
+ /// Notes
+ ///
+ ///
+ ///
+ /// 's memory domain
+ ///
+ public static Watch FromString(string line, IMemoryDomains domains)
+ {
+ string[] parts = line.Split(new char[] { '\t' }, 6);
+
+ if (parts.Length < 6)
+ {
+ if (parts.Length >= 3 && parts[2] == "_")
+ {
+ return SeparatorWatch.Instance;
+ }
+
+ return null;
+ }
+ long address;
+
+ if (long.TryParse(parts[0], NumberStyles.HexNumber, CultureInfo.CurrentCulture, out address))
+ {
+ WatchSize size = Watch.SizeFromChar(parts[1][0]);
+ DisplayType type = Watch.DisplayTypeFromChar(parts[2][0]);
+ bool bigEndian = parts[3] == "0" ? false : true;
+ MemoryDomain domain = domains[parts[4]];
+ string notes = parts[5].Trim(new char[] { '\r', '\n' });
+
+ return Watch.GenerateWatch(
+ domain,
+ address,
+ size,
+ type,
+ notes,
+ bigEndian
+ );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ #endregion Static
+
+ ///
+ /// Transform the current instance into a string
+ ///
+ /// A representation of the current
+ 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())
+ , SizeAsChar
+ , TypeAsChar
+ , BigEndian
+ , DomainName
+ , Notes.Trim('\r', '\n')
+ );
+ }
+
+ #endregion
+
+ #region Properties
+
+ #region Abstracts
+
+ public abstract uint MaxValue { get; }
+ public abstract int? Value { get; }
+ //zero 15-nov-2015 - bypass LIAR LOGIC, see fdc9ea2aa922876d20ba897fb76909bf75fa6c92 https://github.com/TASVideos/BizHawk/issues/326
+ public abstract int? ValueNoFreeze { get; }
+ public abstract string ValueString { get; }
+ public abstract WatchSize Size { get; }
+ public abstract bool Poke(string value);
+ public abstract int? Previous { get; }
+ public abstract string PreviousStr { get; }
+ public abstract void ResetPrevious();
+
+ #endregion Abstracts
+
+ #region Virtual
+
+ ///
+ /// Gets the address in the
+ ///
+ public virtual long? Address
+ {
+ get
+ {
+ return _address;
+ }
+ }
+
+ ///
+ /// Gets or sets the endianess of current
+ /// True for big endian, flase for little endian
+ ///
+ public virtual bool BigEndian
+ {
+ get
+ {
+ return _bigEndian;
+ }
+ set
+ {
+ _bigEndian = value;
+ }
+ }
+
+ ///
+ /// Gets or set the way current is displayed
+ ///
+ public virtual DisplayType Type
+ {
+ get
+ {
+ return _type;
+ }
+ set
+ {
+ _type = value;
+ }
+ }
+
+ ///
+ /// Gets the address in the formatted as string
+ ///
+ public virtual string AddressString
+ {
+ get
+ {
+ return _address.ToString(AddressFormatStr);
+ }
+ }
+
+ ///
+ /// Gets a value that defined if the current is actually a
+ ///
+ public virtual bool IsSeparator
+ {
+ get
+ {
+ return false;
+ }
+ }
+
+ #endregion Virtual
+
+
+ public MemoryDomain Domain { get { return _domain; } set { _domain = value; } }
+
+ public string DomainName { get { return _domain != null ? _domain.Name : string.Empty; } }
+
+ #endregion
+
+ public static string DisplayTypeToString(DisplayType type)
+ {
+ switch (type)
+ {
+ default:
+ return type.ToString();
+ case DisplayType.FixedPoint_12_4:
+ return "Fixed Point 12.4";
+ case DisplayType.FixedPoint_20_12:
+ return "Fixed Point 20.12";
+ case DisplayType.FixedPoint_16_16:
+ return "Fixed Point 16.16";
+ }
+ }
+
+ public static DisplayType StringToDisplayType(string name)
+ {
+ switch (name)
+ {
+ default:
+ return (DisplayType)Enum.Parse(typeof(DisplayType), name);
+ case "Fixed Point 12.4":
+ return DisplayType.FixedPoint_12_4;
+ case "Fixed Point 20.12":
+ return DisplayType.FixedPoint_20_12;
+ case "Fixed Point 16.16":
+ return DisplayType.FixedPoint_16_16;
+ }
+ }
+
+ public char SizeAsChar
+ {
+ get
+ {
+ switch (Size)
+ {
+ default:
+ case WatchSize.Separator:
+ return 'S';
+ case WatchSize.Byte:
+ return 'b';
+ case WatchSize.Word:
+ return 'w';
+ case WatchSize.DWord:
+ return 'd';
+ }
+ }
+ }
+
+ public static WatchSize SizeFromChar(char c)
+ {
+ switch (c)
+ {
+ default:
+ case 'S':
+ return WatchSize.Separator;
+ case 'b':
+ return WatchSize.Byte;
+ case 'w':
+ return WatchSize.Word;
+ case 'd':
+ return WatchSize.DWord;
+ }
+ }
+
+ public char TypeAsChar
+ {
+ get
+ {
+ switch (Type)
+ {
+ default:
+ case DisplayType.Separator:
+ return '_';
+ case DisplayType.Unsigned:
+ return 'u';
+ case DisplayType.Signed:
+ return 's';
+ case DisplayType.Hex:
+ return 'h';
+ case DisplayType.Binary:
+ return 'b';
+ case DisplayType.FixedPoint_12_4:
+ return '1';
+ case DisplayType.FixedPoint_20_12:
+ return '2';
+ case DisplayType.FixedPoint_16_16:
+ return '3';
+ case DisplayType.Float:
+ return 'f';
+ }
+ }
+ }
+
+ public static DisplayType DisplayTypeFromChar(char c)
+ {
+ switch (c)
+ {
+ default:
+ case '_':
+ return DisplayType.Separator;
+ case 'u':
+ return DisplayType.Unsigned;
+ case 's':
+ return DisplayType.Signed;
+ case 'h':
+ return DisplayType.Hex;
+ case 'b':
+ return DisplayType.Binary;
+ case '1':
+ return DisplayType.FixedPoint_12_4;
+ case '2':
+ return DisplayType.FixedPoint_20_12;
+ case '3':
+ return DisplayType.FixedPoint_16_16;
+ case 'f':
+ return DisplayType.Float;
+ }
+ }
+
+ public string AddressFormatStr
+ {
+ get
+ {
+ if (_domain != null)
+ {
+ return "X" + (_domain.Size - 1).NumHexDigits();
+ }
+
+ return string.Empty;
+ }
+ }
+
+ protected byte GetByte(bool bypassFreeze = false)
+ {
+ if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
+ {
+ //LIAR logic
+ return Global.CheatList.GetByteValue(_domain, _address).Value;
+ }
+ else
+ {
+ if (_domain.Size == 0)
+ {
+ return _domain.PeekByte(_address);
+ }
+ else
+ {
+ return _domain.PeekByte(_address % _domain.Size);
+ }
+ }
+ }
+
+ protected ushort GetWord(bool bypassFreeze = false)
+ {
+ if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
+ {
+ //LIAR logic
+ return (ushort)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.Word).Value;
+ }
+ else
+ {
+ if (_domain.Size == 0)
+ {
+ return _domain.PeekWord(_address, _bigEndian);
+ }
+ else
+ {
+ return _domain.PeekWord(_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)
+ {
+ if (!bypassFreeze && Global.CheatList.IsActive(_domain, _address))
+ {
+ //LIAR logic
+ return (uint)Global.CheatList.GetCheatValue(_domain, _address, WatchSize.DWord).Value;
+ }
+ else
+ {
+ if (_domain.Size == 0)
+ {
+ return _domain.PeekDWord(_address, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
+ }
+ else
+ {
+ return _domain.PeekDWord(_address % _domain.Size, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
+ }
+ }
+ }
+
+ protected void PokeByte(byte val)
+ {
+ if (_domain.Size == 0)
+ _domain.PokeByte(_address, val);
+ else _domain.PokeByte(_address % _domain.Size, val);
+ }
+
+ protected void PokeWord(ushort val)
+ {
+ if (_domain.Size == 0)
+ _domain.PokeWord(_address, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
+ else _domain.PokeWord(_address % _domain.Size, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
+ }
+
+ protected void PokeDWord(uint val)
+ {
+ if (_domain.Size == 0)
+ _domain.PokeDWord(_address, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
+ else _domain.PokeDWord(_address % _domain.Size, val, _bigEndian); // TODO: % size stil lisn't correct since it could be the last byte of the domain
+ }
+
+ public void ClearChangeCount() { _changecount = 0; }
+
+ public bool IsOutOfRange
+ {
+ get
+ {
+ return !IsSeparator && (Domain.Size != 0 && Address.Value >= Domain.Size);
+ }
+ }
+
+ public string Notes { get { return _notes; } set { _notes = value; } }
+
+ public static Watch GenerateWatch(MemoryDomain domain, long address, WatchSize size, DisplayType type, string notes, bool bigEndian)
+ {
+ switch (size)
+ {
+ default:
+ case WatchSize.Separator:
+ return SeparatorWatch.Instance;
+ case WatchSize.Byte:
+ return new ByteWatch(domain, address, type, bigEndian, notes);
+ case WatchSize.Word:
+ return new WordWatch(domain, address, type, bigEndian, notes);
+ case WatchSize.DWord:
+ return new DWordWatch(domain, address, type, bigEndian, notes);
+ }
+ }
+
+ public static Watch GenerateWatch(MemoryDomain domain, long address, WatchSize size, DisplayType type, bool bigendian, long prev, int changecount)
+ {
+ switch (size)
+ {
+ default:
+ case WatchSize.Separator:
+ return SeparatorWatch.Instance;
+ case WatchSize.Byte:
+ return new ByteWatch(domain, address, type, bigendian, (byte)prev, changecount);
+ case WatchSize.Word:
+ return new WordWatch(domain, address, type, bigendian, (ushort)prev, changecount);
+ case WatchSize.DWord:
+ return new DWordWatch(domain, address, type, bigendian, (uint)prev, changecount);
+ }
+ }
+
+ public static List AvailableTypes(WatchSize size)
+ {
+ switch (size)
+ {
+ default:
+ case WatchSize.Separator:
+ return SeparatorWatch.ValidTypes;
+ case WatchSize.Byte:
+ return ByteWatch.ValidTypes;
+ case WatchSize.Word:
+ return WordWatch.ValidTypes;
+ case WatchSize.DWord:
+ return DWordWatch.ValidTypes;
+ }
+ }
+
+ public int ChangeCount { get { return _changecount; } }
+
+ public abstract string Diff { get; }
+
+ public abstract void Update();
+
+ public override bool Equals(object obj)
+ {
+ if (obj is Watch)
+ {
+ var watch = obj as Watch;
+
+ return this.Domain == watch.Domain &&
+ this.Address == watch.Address &&
+ this.Size == watch.Size &&
+ this.Type == watch.Type &&
+ this.Notes == watch.Notes;
+ }
+
+ if (obj is Cheat)
+ {
+ var cheat = obj as Cheat;
+ return this.Domain == cheat.Domain && this.Address == cheat.Address;
+ }
+
+ return base.Equals(obj);
+ }
+
+ public override int GetHashCode()
+ {
+ return this.Domain.GetHashCode() + (int)(this.Address ?? 0);
+ }
+
+ public static bool operator ==(Watch a, Watch b)
+ {
+ // If one is null, but not both, return false.
+ if (((object)a == null) || ((object)b == null))
+ {
+ return false;
+ }
+
+ return a.Equals(b);
+ }
+
+ public static bool operator !=(Watch a, Watch b)
+ {
+ return !a.Equals(b);
+ }
+
+ public static bool operator ==(Watch a, Cheat b)
+ {
+ // If one is null, but not both, return false.
+ if (((object)a == null) || ((object)b == null))
+ {
+ return false;
+ }
+
+ return a.Domain == b.Domain && a.Address == b.Address;
+ }
+
+ public static bool operator !=(Watch a, Cheat b)
+ {
+ return !(a == b);
+ }
+ }
+}
diff --git a/BizHawk.Client.Common/tools/WatchList.cs b/BizHawk.Client.Common/tools/Watch/WatchList.cs
similarity index 95%
rename from BizHawk.Client.Common/tools/WatchList.cs
rename to BizHawk.Client.Common/tools/Watch/WatchList.cs
index 8641b729a4..0e690bfd4a 100644
--- a/BizHawk.Client.Common/tools/WatchList.cs
+++ b/BizHawk.Client.Common/tools/Watch/WatchList.cs
@@ -1,560 +1,560 @@
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-
-using BizHawk.Common.NumberExtensions;
-using BizHawk.Common.StringExtensions;
-using BizHawk.Emulation.Common;
-
-namespace BizHawk.Client.Common
-{
- public class WatchList : IList
- {
- private IMemoryDomains _memoryDomains;
- private List _watchList = new List();
- private MemoryDomain _domain;
- private string _currentFilename = string.Empty;
- private string _systemid;
-
- public const string ADDRESS = "AddressColumn";
- public const string VALUE = "ValueColumn";
- public const string PREV = "PrevColumn";
- public const string CHANGES = "ChangesColumn";
- public const string DIFF = "DiffColumn";
- public const string DOMAIN = "DomainColumn";
- public const string NOTES = "NotesColumn";
-
- public WatchList(IMemoryDomains core, MemoryDomain domain, string systemid)
- {
- _memoryDomains = core;
- _domain = domain;
- _systemid = systemid;
- }
-
- public void RefreshDomans(IMemoryDomains core, MemoryDomain domain)
- {
- _memoryDomains = core;
- _domain = domain;
-
- _watchList.ForEach(w =>
- {
- if (w.Domain != null)
- {
- w.Domain = _memoryDomains[w.Domain.Name];
- }
- });
- }
-
- public enum WatchPrevDef { LastSearch, Original, LastFrame, LastChange }
-
- public string AddressFormatStr // TODO: this is probably compensating for not using the ToHex string extension
- {
- get
- {
- if (_domain != null)
- {
- return "{0:X" + (_domain.Size - 1).NumHexDigits() + "}";
- }
-
- return string.Empty;
- }
- }
-
- public int Count
- {
- get { return _watchList.Count; }
- }
-
- public int WatchCount
- {
- get { return _watchList.Count(w => !w.IsSeparator); }
- }
-
- public int ItemCount
- {
- get { return _watchList.Count; }
- }
-
- public MemoryDomain Domain
- {
- get { return _domain; }
- set { _domain = value; }
- }
-
- public bool IsReadOnly { get { return false; } }
-
- public string CurrentFileName
- {
- get { return _currentFilename; }
- set { _currentFilename = value; }
- }
-
- public bool Changes { get; set; }
-
- public Watch this[int index]
- {
- get { return _watchList[index]; }
- set { _watchList[index] = value; }
- }
-
- public IEnumerator GetEnumerator()
- {
- return _watchList.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
-
- public void OrderWatches(string column, bool reverse)
- {
- switch (column)
- {
- case ADDRESS:
- if (reverse)
- {
- _watchList = _watchList
- .OrderByDescending(x => x.Address ?? 0)
- .ThenBy(x => x.Domain.Name)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ThenBy(x => x.BigEndian)
- .ToList();
- }
- else
- {
- _watchList = _watchList
- .OrderBy(x => x.Address ?? 0)
- .ThenBy(x => x.Domain.Name)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ThenBy(x => x.BigEndian)
- .ToList();
- }
-
- break;
- case VALUE:
- if (reverse)
- {
- _watchList = _watchList
- .OrderByDescending(x => x.Value ?? 0)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ThenBy(x => x.BigEndian)
- .ToList();
- }
- else
- {
- _watchList = _watchList
- .OrderBy(x => x.Value ?? 0)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ThenBy(x => x.BigEndian)
- .ToList();
- }
-
- break;
- case PREV: // Note: these only work if all entries are detailed objects!
- if (reverse)
- {
- _watchList = _watchList
- .OrderByDescending(x => x.PreviousStr)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ToList();
- }
- else
- {
- _watchList = _watchList
- .OrderBy(x => x.PreviousStr)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ToList();
- }
-
- break;
- case DIFF:
- if (reverse)
- {
- _watchList = _watchList
- .OrderByDescending(x => x.Diff)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ToList();
- }
- else
- {
- _watchList = _watchList
- .OrderBy(x => x.Diff)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ToList();
- }
-
- break;
- case CHANGES:
- if (reverse)
- {
- _watchList = _watchList
- .OrderByDescending(x => x.ChangeCount)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ToList();
- }
- else
- {
- _watchList = _watchList
- .OrderBy(x => x.ChangeCount)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ToList();
- }
-
- break;
- 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();
- }
- 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();
- }
-
- break;
- case NOTES:
- if (reverse)
- {
- _watchList = _watchList
- .OrderByDescending(x => x.Notes)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ToList();
- }
- else
- {
- _watchList = _watchList
- .OrderBy(x => x.Notes)
- .ThenBy(x => x.Address ?? 0)
- .ThenBy(x => x.Size)
- .ThenBy(x => x.Type)
- .ToList();
- }
-
- break;
- }
- }
-
- public void Clear()
- {
- _watchList.Clear();
- Changes = false;
- _currentFilename = string.Empty;
- }
-
- public void UpdateValues()
- {
- foreach (var watch in _watchList)
- {
- watch.Update();
- }
- }
-
- public void Add(Watch watch)
- {
- _watchList.Add(watch);
- Changes = true;
- }
-
- public void AddRange(IList watches)
- {
- _watchList.AddRange(watches);
- Changes = true;
- }
-
- public bool Remove(Watch watch)
- {
- var result = _watchList.Remove(watch);
- if (result)
- {
- Changes = true;
- }
-
- return result;
- }
-
- public void Insert(int index, Watch watch)
- {
- _watchList.Insert(index, watch);
- }
-
- public void ClearChangeCounts()
- {
- foreach (var watch in _watchList)
- {
- watch.ClearChangeCount();
- }
- }
-
- public bool Contains(Watch watch)
- {
- return _watchList.Any(w =>
- w.Size == watch.Size &&
- w.Type == watch.Type &&
- w.Domain == watch.Domain &&
- w.Address == watch.Address &&
- w.BigEndian == watch.BigEndian);
- }
-
- public void CopyTo(Watch[] array, int arrayIndex)
- {
- _watchList.CopyTo(array, arrayIndex);
- }
-
- public int IndexOf(Watch watch)
- {
- return _watchList.IndexOf(watch);
- }
-
- public void RemoveAt(int index)
- {
- _watchList.RemoveAt(index);
- Changes = true;
- }
-
- #region File handling logic - probably needs to be its own class
-
- public bool Load(string path, bool append)
- {
- var result = LoadFile(path, append);
-
- if (result)
- {
- if (append)
- {
- Changes = true;
- }
- else
- {
- CurrentFileName = path;
- Changes = false;
- }
- }
-
- return result;
- }
-
- public void Reload()
- {
- if (!string.IsNullOrWhiteSpace(CurrentFileName))
- {
- LoadFile(CurrentFileName, append: false);
- Changes = false;
- }
- }
-
- public bool Save()
- {
- if (string.IsNullOrWhiteSpace(CurrentFileName))
- {
- return false;
- }
-
- using (var sw = new StreamWriter(CurrentFileName))
- {
- var sb = new StringBuilder();
- sb
- .Append("Domain ").AppendLine(_domain.Name)
- .Append("SystemID ").AppendLine(_systemid);
-
- foreach (var watch in _watchList)
- {
- sb.AppendLine(Watch.ToString(watch, _domain));
- }
-
- sw.WriteLine(sb.ToString());
- }
-
- Global.Config.RecentWatches.Add(CurrentFileName);
- Changes = false;
- return true;
- }
-
- public bool SaveAs(FileInfo file)
- {
- if (file != null)
- {
- CurrentFileName = file.FullName;
- return Save();
- }
-
- return false;
- }
-
- private bool LoadFile(string path, bool append)
- {
- var domain = string.Empty;
- var file = new FileInfo(path);
- if (file.Exists == false)
- {
- return false;
- }
-
- var isBizHawkWatch = true; // Hack to support .wch files from other emulators
- var isOldBizHawkWatch = false;
- using (var sr = file.OpenText())
- {
- string line;
-
- if (!append)
- {
- Clear();
- }
-
- while ((line = sr.ReadLine()) != null)
- {
- // .wch files from other emulators start with a number representing the number of watch, that line can be discarded here
- // Any properly formatted line couldn't possibly be this short anyway, this also takes care of any garbage lines that might be in a file
- if (line.Length < 5)
- {
- isBizHawkWatch = false;
- continue;
- }
-
- if (line.Length >= 6 && line.Substring(0, 6) == "Domain")
- {
- domain = line.Substring(7, line.Length - 7);
- isBizHawkWatch = true;
- }
-
- if (line.Length >= 8 && line.Substring(0, 8) == "SystemID")
- {
- continue;
- }
-
- var numColumns = line.HowMany('\t');
- int startIndex;
- if (numColumns == 5)
- {
- // If 5, then this is a post 1.0.5 .wch file
- if (isBizHawkWatch)
- {
- // Do nothing here
- }
- else
- {
- startIndex = line.IndexOf('\t') + 1;
- line = line.Substring(startIndex, line.Length - startIndex); // 5 digit value representing the watch position number
- }
- }
- else if (numColumns == 4)
- {
- isOldBizHawkWatch = true; // This supports the legacy .wch format from 1.0.5 and earlier
- }
- else
- {
- continue; // If not 4, something is wrong with this line, ignore it
- }
-
- // Temporary, rename if kept
- int addr;
- var memDomain = _memoryDomains.MainMemory;
-
- var temp = line.Substring(0, line.IndexOf('\t'));
- try
- {
- addr = int.Parse(temp, NumberStyles.HexNumber);
- }
- catch
- {
- continue;
- }
-
- startIndex = line.IndexOf('\t') + 1;
- line = line.Substring(startIndex, line.Length - startIndex); // Type
- var size = Watch.SizeFromChar(line[0]);
-
- startIndex = line.IndexOf('\t') + 1;
- line = line.Substring(startIndex, line.Length - startIndex); // Signed
- var type = Watch.DisplayTypeFromChar(line[0]);
-
- startIndex = line.IndexOf('\t') + 1;
- line = line.Substring(startIndex, line.Length - startIndex); // Endian
- try
- {
- startIndex = short.Parse(line[0].ToString());
- }
- catch
- {
- continue;
- }
-
- var bigEndian = startIndex != 0;
-
- if (isBizHawkWatch && !isOldBizHawkWatch)
- {
- startIndex = line.IndexOf('\t') + 1;
- line = line.Substring(startIndex, line.Length - startIndex); // Domain
- temp = line.Substring(0, line.IndexOf('\t'));
- memDomain = _memoryDomains[temp] ?? _memoryDomains.MainMemory;
- }
-
- startIndex = line.IndexOf('\t') + 1;
- var notes = line.Substring(startIndex, line.Length - startIndex);
-
- _watchList.Add(
- Watch.GenerateWatch(
- memDomain,
- addr,
- size,
- type,
- notes,
- bigEndian));
- _domain = _memoryDomains[domain];
- }
-
- Domain = _memoryDomains[domain] ?? _memoryDomains.MainMemory;
- _currentFilename = path;
- }
-
- if (!append)
- {
- Global.Config.RecentWatches.Add(path);
- Changes = false;
- }
- else
- {
- Changes = true;
- }
-
- return true;
- }
-
- #endregion
- }
-}
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+using BizHawk.Common.NumberExtensions;
+using BizHawk.Common.StringExtensions;
+using BizHawk.Emulation.Common;
+
+namespace BizHawk.Client.Common
+{
+ public class WatchList : IList
+ {
+ private IMemoryDomains _memoryDomains;
+ private List _watchList = new List();
+ private MemoryDomain _domain;
+ private string _currentFilename = string.Empty;
+ private string _systemid;
+
+ public const string ADDRESS = "AddressColumn";
+ public const string VALUE = "ValueColumn";
+ public const string PREV = "PrevColumn";
+ public const string CHANGES = "ChangesColumn";
+ public const string DIFF = "DiffColumn";
+ public const string DOMAIN = "DomainColumn";
+ public const string NOTES = "NotesColumn";
+
+ public WatchList(IMemoryDomains core, MemoryDomain domain, string systemid)
+ {
+ _memoryDomains = core;
+ _domain = domain;
+ _systemid = systemid;
+ }
+
+ public void RefreshDomans(IMemoryDomains core, MemoryDomain domain)
+ {
+ _memoryDomains = core;
+ _domain = domain;
+
+ _watchList.ForEach(w =>
+ {
+ if (w.Domain != null)
+ {
+ w.Domain = _memoryDomains[w.Domain.Name];
+ }
+ });
+ }
+
+ public enum WatchPrevDef { LastSearch, Original, LastFrame, LastChange }
+
+ public string AddressFormatStr // TODO: this is probably compensating for not using the ToHex string extension
+ {
+ get
+ {
+ if (_domain != null)
+ {
+ return "{0:X" + (_domain.Size - 1).NumHexDigits() + "}";
+ }
+
+ return string.Empty;
+ }
+ }
+
+ public int Count
+ {
+ get { return _watchList.Count; }
+ }
+
+ public int WatchCount
+ {
+ get { return _watchList.Count(w => !w.IsSeparator); }
+ }
+
+ public int ItemCount
+ {
+ get { return _watchList.Count; }
+ }
+
+ public MemoryDomain Domain
+ {
+ get { return _domain; }
+ set { _domain = value; }
+ }
+
+ public bool IsReadOnly { get { return false; } }
+
+ public string CurrentFileName
+ {
+ get { return _currentFilename; }
+ set { _currentFilename = value; }
+ }
+
+ public bool Changes { get; set; }
+
+ public Watch this[int index]
+ {
+ get { return _watchList[index]; }
+ set { _watchList[index] = value; }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return _watchList.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ public void OrderWatches(string column, bool reverse)
+ {
+ switch (column)
+ {
+ case ADDRESS:
+ if (reverse)
+ {
+ _watchList = _watchList
+ .OrderByDescending(x => x.Address ?? 0)
+ .ThenBy(x => x.Domain.Name)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ThenBy(x => x.BigEndian)
+ .ToList();
+ }
+ else
+ {
+ _watchList = _watchList
+ .OrderBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Domain.Name)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ThenBy(x => x.BigEndian)
+ .ToList();
+ }
+
+ break;
+ case VALUE:
+ if (reverse)
+ {
+ _watchList = _watchList
+ .OrderByDescending(x => x.Value ?? 0)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ThenBy(x => x.BigEndian)
+ .ToList();
+ }
+ else
+ {
+ _watchList = _watchList
+ .OrderBy(x => x.Value ?? 0)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ThenBy(x => x.BigEndian)
+ .ToList();
+ }
+
+ break;
+ case PREV: // Note: these only work if all entries are detailed objects!
+ if (reverse)
+ {
+ _watchList = _watchList
+ .OrderByDescending(x => x.PreviousStr)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ToList();
+ }
+ else
+ {
+ _watchList = _watchList
+ .OrderBy(x => x.PreviousStr)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ToList();
+ }
+
+ break;
+ case DIFF:
+ if (reverse)
+ {
+ _watchList = _watchList
+ .OrderByDescending(x => x.Diff)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ToList();
+ }
+ else
+ {
+ _watchList = _watchList
+ .OrderBy(x => x.Diff)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ToList();
+ }
+
+ break;
+ case CHANGES:
+ if (reverse)
+ {
+ _watchList = _watchList
+ .OrderByDescending(x => x.ChangeCount)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ToList();
+ }
+ else
+ {
+ _watchList = _watchList
+ .OrderBy(x => x.ChangeCount)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ToList();
+ }
+
+ break;
+ 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();
+ }
+ 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();
+ }
+
+ break;
+ case NOTES:
+ if (reverse)
+ {
+ _watchList = _watchList
+ .OrderByDescending(x => x.Notes)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ToList();
+ }
+ else
+ {
+ _watchList = _watchList
+ .OrderBy(x => x.Notes)
+ .ThenBy(x => x.Address ?? 0)
+ .ThenBy(x => x.Size)
+ .ThenBy(x => x.Type)
+ .ToList();
+ }
+
+ break;
+ }
+ }
+
+ public void Clear()
+ {
+ _watchList.Clear();
+ Changes = false;
+ _currentFilename = string.Empty;
+ }
+
+ public void UpdateValues()
+ {
+ foreach (var watch in _watchList)
+ {
+ watch.Update();
+ }
+ }
+
+ public void Add(Watch watch)
+ {
+ _watchList.Add(watch);
+ Changes = true;
+ }
+
+ public void AddRange(IList watches)
+ {
+ _watchList.AddRange(watches);
+ Changes = true;
+ }
+
+ public bool Remove(Watch watch)
+ {
+ var result = _watchList.Remove(watch);
+ if (result)
+ {
+ Changes = true;
+ }
+
+ return result;
+ }
+
+ public void Insert(int index, Watch watch)
+ {
+ _watchList.Insert(index, watch);
+ }
+
+ public void ClearChangeCounts()
+ {
+ foreach (var watch in _watchList)
+ {
+ watch.ClearChangeCount();
+ }
+ }
+
+ public bool Contains(Watch watch)
+ {
+ return _watchList.Any(w =>
+ w.Size == watch.Size &&
+ w.Type == watch.Type &&
+ w.Domain == watch.Domain &&
+ w.Address == watch.Address &&
+ w.BigEndian == watch.BigEndian);
+ }
+
+ public void CopyTo(Watch[] array, int arrayIndex)
+ {
+ _watchList.CopyTo(array, arrayIndex);
+ }
+
+ public int IndexOf(Watch watch)
+ {
+ return _watchList.IndexOf(watch);
+ }
+
+ public void RemoveAt(int index)
+ {
+ _watchList.RemoveAt(index);
+ Changes = true;
+ }
+
+ #region File handling logic - probably needs to be its own class
+
+ public bool Load(string path, bool append)
+ {
+ var result = LoadFile(path, append);
+
+ if (result)
+ {
+ if (append)
+ {
+ Changes = true;
+ }
+ else
+ {
+ CurrentFileName = path;
+ Changes = false;
+ }
+ }
+
+ return result;
+ }
+
+ public void Reload()
+ {
+ if (!string.IsNullOrWhiteSpace(CurrentFileName))
+ {
+ LoadFile(CurrentFileName, append: false);
+ Changes = false;
+ }
+ }
+
+ public bool Save()
+ {
+ if (string.IsNullOrWhiteSpace(CurrentFileName))
+ {
+ return false;
+ }
+
+ using (var sw = new StreamWriter(CurrentFileName))
+ {
+ var sb = new StringBuilder();
+ sb
+ .Append("Domain ").AppendLine(_domain.Name)
+ .Append("SystemID ").AppendLine(_systemid);
+
+ foreach (var watch in _watchList)
+ {
+ sb.AppendLine(watch.ToString());
+ }
+
+ sw.WriteLine(sb.ToString());
+ }
+
+ Global.Config.RecentWatches.Add(CurrentFileName);
+ Changes = false;
+ return true;
+ }
+
+ public bool SaveAs(FileInfo file)
+ {
+ if (file != null)
+ {
+ CurrentFileName = file.FullName;
+ return Save();
+ }
+
+ return false;
+ }
+
+ private bool LoadFile(string path, bool append)
+ {
+ var domain = string.Empty;
+ var file = new FileInfo(path);
+ if (file.Exists == false)
+ {
+ return false;
+ }
+
+ var isBizHawkWatch = true; // Hack to support .wch files from other emulators
+ var isOldBizHawkWatch = false;
+ using (var sr = file.OpenText())
+ {
+ string line;
+
+ if (!append)
+ {
+ Clear();
+ }
+
+ while ((line = sr.ReadLine()) != null)
+ {
+ // .wch files from other emulators start with a number representing the number of watch, that line can be discarded here
+ // Any properly formatted line couldn't possibly be this short anyway, this also takes care of any garbage lines that might be in a file
+ if (line.Length < 5)
+ {
+ isBizHawkWatch = false;
+ continue;
+ }
+
+ if (line.Length >= 6 && line.Substring(0, 6) == "Domain")
+ {
+ domain = line.Substring(7, line.Length - 7);
+ isBizHawkWatch = true;
+ }
+
+ if (line.Length >= 8 && line.Substring(0, 8) == "SystemID")
+ {
+ continue;
+ }
+
+ var numColumns = line.HowMany('\t');
+ int startIndex;
+ if (numColumns == 5)
+ {
+ // If 5, then this is a post 1.0.5 .wch file
+ if (isBizHawkWatch)
+ {
+ // Do nothing here
+ }
+ else
+ {
+ startIndex = line.IndexOf('\t') + 1;
+ line = line.Substring(startIndex, line.Length - startIndex); // 5 digit value representing the watch position number
+ }
+ }
+ else if (numColumns == 4)
+ {
+ isOldBizHawkWatch = true; // This supports the legacy .wch format from 1.0.5 and earlier
+ }
+ else
+ {
+ continue; // If not 4, something is wrong with this line, ignore it
+ }
+
+ // Temporary, rename if kept
+ int addr;
+ var memDomain = _memoryDomains.MainMemory;
+
+ var temp = line.Substring(0, line.IndexOf('\t'));
+ try
+ {
+ addr = int.Parse(temp, NumberStyles.HexNumber);
+ }
+ catch
+ {
+ continue;
+ }
+
+ startIndex = line.IndexOf('\t') + 1;
+ line = line.Substring(startIndex, line.Length - startIndex); // Type
+ var size = Watch.SizeFromChar(line[0]);
+
+ startIndex = line.IndexOf('\t') + 1;
+ line = line.Substring(startIndex, line.Length - startIndex); // Signed
+ var type = Watch.DisplayTypeFromChar(line[0]);
+
+ startIndex = line.IndexOf('\t') + 1;
+ line = line.Substring(startIndex, line.Length - startIndex); // Endian
+ try
+ {
+ startIndex = short.Parse(line[0].ToString());
+ }
+ catch
+ {
+ continue;
+ }
+
+ var bigEndian = startIndex != 0;
+
+ if (isBizHawkWatch && !isOldBizHawkWatch)
+ {
+ startIndex = line.IndexOf('\t') + 1;
+ line = line.Substring(startIndex, line.Length - startIndex); // Domain
+ temp = line.Substring(0, line.IndexOf('\t'));
+ memDomain = _memoryDomains[temp] ?? _memoryDomains.MainMemory;
+ }
+
+ startIndex = line.IndexOf('\t') + 1;
+ var notes = line.Substring(startIndex, line.Length - startIndex);
+
+ _watchList.Add(
+ Watch.GenerateWatch(
+ memDomain,
+ addr,
+ size,
+ type,
+ notes,
+ bigEndian));
+ _domain = _memoryDomains[domain];
+ }
+
+ Domain = _memoryDomains[domain] ?? _memoryDomains.MainMemory;
+ _currentFilename = path;
+ }
+
+ if (!append)
+ {
+ Global.Config.RecentWatches.Add(path);
+ Changes = false;
+ }
+ else
+ {
+ Changes = true;
+ }
+
+ return true;
+ }
+
+ #endregion
+ }
+}
diff --git a/BizHawk.Client.Common/tools/Watch/WatchSize.cs b/BizHawk.Client.Common/tools/Watch/WatchSize.cs
new file mode 100644
index 0000000000..f1274eb666
--- /dev/null
+++ b/BizHawk.Client.Common/tools/Watch/WatchSize.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace BizHawk.Client.Common
+{
+ public abstract partial class Watch
+ {
+ ///
+ /// This enum specify the size of a
+ ///
+ public enum WatchSize
+ {
+ ///
+ /// One byte (8 bits)
+ /// Use this for
+ ///
+ Byte = 1,
+ ///
+ /// 2 bytes (16 bits)
+ /// Use this for
+ ///
+ Word = 2,
+ ///
+ /// 4 bytes (32 bits)
+ /// Use this for
+ ///
+ DWord = 4,
+ ///
+ /// Special case used for a separator in ramwatch
+ /// Use this for
+ ///
+ Separator = 0
+ }
+ }
+}
diff --git a/BizHawk.Client.Common/tools/Watch/WordWatch.cs b/BizHawk.Client.Common/tools/Watch/WordWatch.cs
new file mode 100644
index 0000000000..53bf20765d
--- /dev/null
+++ b/BizHawk.Client.Common/tools/Watch/WordWatch.cs
@@ -0,0 +1,234 @@
+using BizHawk.Common.NumberExtensions;
+using BizHawk.Common.StringExtensions;
+using BizHawk.Emulation.Common;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+
+namespace BizHawk.Client.Common
+{
+ public sealed class WordWatch : Watch
+ {
+ private ushort _previous;
+ private ushort _value;
+
+ public WordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string notes)
+ {
+ _domain = domain;
+ _address = address;
+ _value = _previous = GetWord();
+
+ if (AvailableTypes(WatchSize.Word).Contains(type))
+ {
+ _type = type;
+ }
+
+ _bigEndian = bigEndian;
+
+ if (notes != null)
+ {
+ Notes = notes;
+ }
+ }
+
+ public WordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, ushort prev, int changeCount, string notes = null)
+ : this(domain, address, type, bigEndian, notes)
+ {
+ _previous = prev;
+ _changecount = changeCount;
+ }
+
+ 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); }
+ }
+
+ public override void ResetPrevious()
+ {
+ _previous = GetWord();
+ }
+
+ public override WatchSize Size
+ {
+ get { return WatchSize.Word; }
+ }
+
+ public static List ValidTypes
+ {
+ get
+ {
+ return new List
+ {
+ DisplayType.Unsigned, DisplayType.Signed, DisplayType.Hex, DisplayType.FixedPoint_12_4, DisplayType.Binary
+ };
+ }
+ }
+
+ 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, " ");
+ }
+ }
+
+ public override bool Poke(string value)
+ {
+ try
+ {
+ ushort val = 0;
+ switch (Type)
+ {
+ case DisplayType.Unsigned:
+ if (value.IsUnsigned())
+ {
+ val = (ushort)int.Parse(value);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.Signed:
+ if (value.IsSigned())
+ {
+ val = (ushort)(short)int.Parse(value);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.Hex:
+ if (value.IsHex())
+ {
+ val = (ushort)int.Parse(value, NumberStyles.HexNumber);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.Binary:
+ if (value.IsBinary())
+ {
+ val = (ushort)Convert.ToInt32(value, 2);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ case DisplayType.FixedPoint_12_4:
+ if (value.IsFixedPoint())
+ {
+ val = (ushort)(double.Parse(value) * 16.0);
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ }
+
+ if (Global.CheatList.Contains(Domain, _address))
+ {
+ var cheat = Global.CheatList.FirstOrDefault(c => c.Address == _address && c.Domain == Domain);
+ if (cheat != (Cheat)null)
+ {
+ cheat.PokeValue(val);
+ PokeWord(val);
+ return true;
+ }
+ }
+
+ PokeWord(val);
+ return true;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ public override string Diff
+ {
+ get { return FormatValue((ushort)(_previous - _value)); }
+ }
+
+ public override void Update()
+ {
+ switch (Global.Config.RamWatchDefinePrevious)
+ {
+ case PreviousType.Original:
+ return;
+ case PreviousType.LastChange:
+ var temp = _value;
+ _value = GetWord();
+
+ if (_value != temp)
+ {
+ _previous = temp;
+ _changecount++;
+ }
+
+ break;
+ case PreviousType.LastFrame:
+ _previous = _value;
+ _value = GetWord();
+ if (_value != Previous)
+ {
+ _changecount++;
+ }
+
+ break;
+ }
+ }
+ }
+}
diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
index e1ba614d41..852c8809ab 100644
--- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
+++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj
@@ -531,9 +531,7 @@
Component
-
- Component
-
+
@@ -807,8 +805,6 @@
HexFind.cs
-
-
@@ -1566,6 +1562,10 @@
+
+ {8e2f11f2-3955-4382-8c3a-ceba1276caea}
+ BizHawk.Client.ApiHawk
+
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}
BizHawk.Client.Common
diff --git a/BizHawk.Client.EmuHawk/tools/ToolManager.cs b/BizHawk.Client.EmuHawk/tools/ToolManager.cs
index bf2e5f3381..c724746669 100644
--- a/BizHawk.Client.EmuHawk/tools/ToolManager.cs
+++ b/BizHawk.Client.EmuHawk/tools/ToolManager.cs
@@ -562,7 +562,8 @@ namespace BizHawk.Client.EmuHawk
IToolForm tool;
//Specific case for custom tools
- //TODO: Use AppDomain in order to be able to unload the assembly
+ //TODO: Use AppDomain in order to be able to unload the assembly
+ //Hard stuff as we need a proxy object that inherit from MarshalByRefObject.
if (toolType == typeof(IExternalToolForm))
{
if (MessageBox.Show(@"Are you sure want to load this external tool?\r\nAccept ONLY if you trust the source and if you know what you're doing. In any other case, choose no."
@@ -571,7 +572,7 @@ namespace BizHawk.Client.EmuHawk
try
{
tool = Activator.CreateInstanceFrom(dllPath, "BizHawk.Client.EmuHawk.CustomMainForm").Unwrap() as IExternalToolForm;
- if (tool == null)
+ if (tool == null)
{
MessageBox.Show("It seems that the object CustomMainForm does not implement IExternalToolForm. Please review the code.", "No, no, no. Wrong Way !", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
return null;
@@ -683,7 +684,7 @@ namespace BizHawk.Client.EmuHawk
}
var tool = Assembly
- .GetAssembly(typeof(IToolForm))
+ .GetExecutingAssembly()
.GetTypes()
.FirstOrDefault(type => type == t);
diff --git a/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs b/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
index d1bfdfe875..f8a70b9b91 100644
--- a/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
+++ b/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
@@ -1511,7 +1511,7 @@ namespace BizHawk.Client.EmuHawk
var sb = new StringBuilder();
foreach (var watch in SelectedItems)
{
- sb.AppendLine(Watch.ToString(watch, _searches.Domain));
+ sb.AppendLine(watch.ToString());
}
if (sb.Length > 0)
diff --git a/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs b/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs
index d0137d2490..0eadd6252d 100644
--- a/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs
+++ b/BizHawk.Client.EmuHawk/tools/Watch/RamWatch.cs
@@ -352,7 +352,7 @@ namespace BizHawk.Client.EmuHawk
var sb = new StringBuilder();
foreach (var watch in SelectedItems)
{
- sb.AppendLine(Watch.ToString(watch, _watches.Domain));
+ sb.AppendLine(watch.ToString());
}
if (sb.Length > 0)
diff --git a/BizHawk.sln b/BizHawk.sln
index 20621e4314..b7d95323c1 100644
--- a/BizHawk.sln
+++ b/BizHawk.sln
@@ -58,179 +58,228 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Bizware.BizwareGL.S
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Client.MultiHawk", "BizHawk.Client.MultiHawk\BizHawk.Client.MultiHawk.csproj", "{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BizHawk.Client.ApiHawk", "BizHawk.Client.ApiHawk\BizHawk.Client.ApiHawk.csproj", "{8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32
Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|Any CPU.ActiveCfg = Debug|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|Mixed Platforms.Build.0 = Debug|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|Win32.ActiveCfg = Debug|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|x86.ActiveCfg = Debug|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Debug|x86.Build.0 = Debug|x86
+ {0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|Any CPU.ActiveCfg = Release|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|Mixed Platforms.ActiveCfg = Release|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|Mixed Platforms.Build.0 = Release|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|Win32.ActiveCfg = Release|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|x86.ActiveCfg = Release|x86
{0CE8B337-08E3-4602-BF10-C4D4C75D2F13}.Release|x86.Build.0 = Release|x86
+ {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|Any CPU.ActiveCfg = Debug|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|Mixed Platforms.Build.0 = Debug|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|Win32.ActiveCfg = Debug|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|x86.ActiveCfg = Debug|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Debug|x86.Build.0 = Debug|x86
+ {24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|Any CPU.ActiveCfg = Release|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|Mixed Platforms.ActiveCfg = Release|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|Mixed Platforms.Build.0 = Release|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|Win32.ActiveCfg = Release|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|x86.ActiveCfg = Release|x86
{24A0AA3C-B25F-4197-B23D-476D6462DBA0}.Release|x86.Build.0 = Release|x86
+ {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|Any CPU.ActiveCfg = Debug|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|Mixed Platforms.Build.0 = Debug|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|Win32.ActiveCfg = Debug|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|x86.ActiveCfg = Debug|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Debug|x86.Build.0 = Debug|x86
+ {866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|Any CPU.ActiveCfg = Release|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|Mixed Platforms.ActiveCfg = Release|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|Mixed Platforms.Build.0 = Release|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|Win32.ActiveCfg = Release|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|x86.ActiveCfg = Release|x86
{866F8D13-0678-4FF9-80A4-A3993FD4D8A3}.Release|x86.Build.0 = Release|x86
+ {DD448B37-BA3F-4544-9754-5406E8094723}.Debug|Any CPU.ActiveCfg = Debug|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Debug|Mixed Platforms.Build.0 = Debug|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Debug|Win32.ActiveCfg = Debug|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Debug|Win32.Build.0 = Debug|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Debug|x86.ActiveCfg = Debug|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Debug|x86.Build.0 = Debug|x86
+ {DD448B37-BA3F-4544-9754-5406E8094723}.Release|Any CPU.ActiveCfg = Release|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Release|Mixed Platforms.ActiveCfg = Release|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Release|Mixed Platforms.Build.0 = Release|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Release|Win32.ActiveCfg = Release|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Release|Win32.Build.0 = Release|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Release|x86.ActiveCfg = Release|x86
{DD448B37-BA3F-4544-9754-5406E8094723}.Release|x86.Build.0 = Release|x86
+ {C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|Any CPU.ActiveCfg = Debug|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|Mixed Platforms.Build.0 = Debug|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|Win32.ActiveCfg = Debug|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|Win32.Build.0 = Debug|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|x86.ActiveCfg = Debug|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Debug|x86.Build.0 = Debug|x86
+ {C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|Any CPU.ActiveCfg = Release|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|Mixed Platforms.ActiveCfg = Release|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|Mixed Platforms.Build.0 = Release|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|Win32.ActiveCfg = Release|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|Win32.Build.0 = Release|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|x86.ActiveCfg = Release|x86
{C4366030-6D03-424B-AE53-F4F43BB217C3}.Release|x86.Build.0 = Release|x86
+ {F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|Any CPU.ActiveCfg = Debug|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|Mixed Platforms.Build.0 = Debug|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|Win32.ActiveCfg = Debug|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|x86.ActiveCfg = Debug|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Debug|x86.Build.0 = Debug|x86
+ {F51946EA-827F-4D82-B841-1F2F6D060312}.Release|Any CPU.ActiveCfg = Release|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Release|Mixed Platforms.ActiveCfg = Release|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Release|Mixed Platforms.Build.0 = Release|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Release|Win32.ActiveCfg = Release|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Release|x86.ActiveCfg = Release|x86
{F51946EA-827F-4D82-B841-1F2F6D060312}.Release|x86.Build.0 = Release|x86
+ {E1A23168-B571-411C-B360-2229E7225E0E}.Debug|Any CPU.ActiveCfg = Debug|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Debug|Mixed Platforms.Build.0 = Debug|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Debug|Win32.ActiveCfg = Debug|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Debug|x86.ActiveCfg = Debug|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Debug|x86.Build.0 = Debug|x86
+ {E1A23168-B571-411C-B360-2229E7225E0E}.Release|Any CPU.ActiveCfg = Release|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Release|Mixed Platforms.ActiveCfg = Release|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Release|Mixed Platforms.Build.0 = Release|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Release|Win32.ActiveCfg = Release|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Release|x86.ActiveCfg = Release|x86
{E1A23168-B571-411C-B360-2229E7225E0E}.Release|x86.Build.0 = Release|x86
+ {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|Any CPU.ActiveCfg = Debug|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|Mixed Platforms.Build.0 = Debug|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|Win32.ActiveCfg = Debug|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|x86.ActiveCfg = Debug|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Debug|x86.Build.0 = Debug|x86
+ {197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|Any CPU.ActiveCfg = Release|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|Mixed Platforms.ActiveCfg = Release|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|Mixed Platforms.Build.0 = Release|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|Win32.ActiveCfg = Release|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|x86.ActiveCfg = Release|x86
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA}.Release|x86.Build.0 = Release|x86
+ {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|Any CPU.ActiveCfg = Debug|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|Mixed Platforms.Build.0 = Debug|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|Win32.ActiveCfg = Debug|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|x86.ActiveCfg = Debug|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Debug|x86.Build.0 = Debug|x86
+ {9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|Any CPU.ActiveCfg = Release|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|Mixed Platforms.ActiveCfg = Release|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|Mixed Platforms.Build.0 = Release|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|Win32.ActiveCfg = Release|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|x86.ActiveCfg = Release|x86
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465}.Release|x86.Build.0 = Release|x86
+ {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|Any CPU.ActiveCfg = Debug|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|Mixed Platforms.Build.0 = Debug|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|Win32.ActiveCfg = Debug|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|x86.ActiveCfg = Debug|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Debug|x86.Build.0 = Debug|x86
+ {5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|Any CPU.ActiveCfg = Release|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|Mixed Platforms.ActiveCfg = Release|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|Mixed Platforms.Build.0 = Release|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|Win32.ActiveCfg = Release|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|x86.ActiveCfg = Release|x86
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE}.Release|x86.Build.0 = Release|x86
+ {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Any CPU.ActiveCfg = Debug|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Mixed Platforms.Build.0 = Debug|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Win32.ActiveCfg = Debug|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|Win32.Build.0 = Debug|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|x86.ActiveCfg = Debug|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Debug|x86.Build.0 = Debug|x86
+ {2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Any CPU.ActiveCfg = Release|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Mixed Platforms.ActiveCfg = Release|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Mixed Platforms.Build.0 = Release|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Win32.ActiveCfg = Release|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|Win32.Build.0 = Release|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|x86.ActiveCfg = Release|x86
{2D2890A8-C338-4439-AD8B-CB9EE85A94F9}.Release|x86.Build.0 = Release|x86
+ {337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|Any CPU.ActiveCfg = Debug|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|Mixed Platforms.Build.0 = Debug|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|Win32.ActiveCfg = Debug|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|x86.ActiveCfg = Debug|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Debug|x86.Build.0 = Debug|x86
+ {337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|Any CPU.ActiveCfg = Release|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|Mixed Platforms.ActiveCfg = Release|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|Mixed Platforms.Build.0 = Release|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|Win32.ActiveCfg = Release|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|x86.ActiveCfg = Release|x86
{337CA23E-65E7-44E1-9411-97EE08BB8116}.Release|x86.Build.0 = Release|x86
+ {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|Any CPU.ActiveCfg = Debug|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|Mixed Platforms.Build.0 = Debug|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|Win32.ActiveCfg = Debug|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|x86.ActiveCfg = Debug|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Debug|x86.Build.0 = Debug|x86
+ {E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|Any CPU.ActiveCfg = Release|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|Mixed Platforms.ActiveCfg = Release|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|Mixed Platforms.Build.0 = Release|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|Win32.ActiveCfg = Release|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|x86.ActiveCfg = Release|x86
{E6B436B1-A3CD-4C9A-8F76-5D7154726884}.Release|x86.Build.0 = Release|x86
+ {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|Any CPU.ActiveCfg = Debug|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|Mixed Platforms.Build.0 = Debug|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|Win32.ActiveCfg = Debug|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|x86.ActiveCfg = Debug|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Debug|x86.Build.0 = Debug|x86
+ {B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|Any CPU.ActiveCfg = Release|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|Mixed Platforms.ActiveCfg = Release|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|Mixed Platforms.Build.0 = Release|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|Win32.ActiveCfg = Release|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|x86.ActiveCfg = Release|x86
{B95649F5-A0AE-41EB-B62B-578A2AFF5E18}.Release|x86.Build.0 = Release|x86
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|Win32.ActiveCfg = Debug|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|Win32.Build.0 = Debug|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Debug|x86.Build.0 = Debug|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|Win32.ActiveCfg = Release|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|Win32.Build.0 = Release|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|x86.ActiveCfg = Release|Any CPU
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
+ {24A0AA3C-B25F-4197-B23D-476D6462DBA0} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA}
{DD448B37-BA3F-4544-9754-5406E8094723} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA}
{C4366030-6D03-424B-AE53-F4F43BB217C3} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA}
- {24A0AA3C-B25F-4197-B23D-476D6462DBA0} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA}
- {2D2890A8-C338-4439-AD8B-CB9EE85A94F9} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA}
- {B95649F5-A0AE-41EB-B62B-578A2AFF5E18} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA}
- {E1A23168-B571-411C-B360-2229E7225E0E} = {3627C08B-3E43-4224-9DA4-40BD69495FBC}
{F51946EA-827F-4D82-B841-1F2F6D060312} = {3627C08B-3E43-4224-9DA4-40BD69495FBC}
+ {E1A23168-B571-411C-B360-2229E7225E0E} = {3627C08B-3E43-4224-9DA4-40BD69495FBC}
{197D4314-8A9F-49BA-977D-54ACEFAEB6BA} = {3627C08B-3E43-4224-9DA4-40BD69495FBC}
{9F84A0B2-861E-4EF4-B89B-5E2A3F38A465} = {0540A9A6-977E-466D-8BD3-1D8590BD5282}
{5160CFB1-5389-47C1-B7F6-8A0DC97641EE} = {0540A9A6-977E-466D-8BD3-1D8590BD5282}
+ {2D2890A8-C338-4439-AD8B-CB9EE85A94F9} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA}
{337CA23E-65E7-44E1-9411-97EE08BB8116} = {0540A9A6-977E-466D-8BD3-1D8590BD5282}
{E6B436B1-A3CD-4C9A-8F76-5D7154726884} = {0540A9A6-977E-466D-8BD3-1D8590BD5282}
+ {B95649F5-A0AE-41EB-B62B-578A2AFF5E18} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA}
+ {8E2F11F2-3955-4382-8C3A-CEBA1276CAEA} = {B51F1139-3D2C-41BE-A762-EF1F9B41EACA}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = BizHawk.Client.EmuHawk\BizHawk.Client.EmuHawk.csproj