Draft of API

So, I create a new dll named BizHawk.Client.ApiHawk and moved few stuff
to it.
Also moved some stuff to BizHawk.Client.Common. Don't think it can be
desiociated.

I started comment Watch and rearrange code (put some #region etc...

It compiles and it seems working :)
This commit is contained in:
Hathor86 2015-11-26 23:05:29 +01:00
parent 1928d04137
commit d4b4c06f0c
24 changed files with 2396 additions and 1873 deletions

5
.gitignore vendored
View File

@ -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

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// Define if the property has to be persisted in config
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class ConfigPersistAttribute : Attribute
{
}
}

View File

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8E2F11F2-3955-4382-8C3A-CEBA1276CAEA}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BizHawk.Client.ApiHawk</RootNamespace>
<AssemblyName>BizHawk.Client.ApiHawk</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Attributes\ConfigPersistAttribute.cs" />
<Compile Include="Interfaces\IToolFormAutoConfig.cs" />
<Compile Include="Interfaces\IExternalToolForm.cs" />
<Compile Include="Interfaces\IToolForm.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BizHawk.Client.Common\BizHawk.Client.Common.csproj">
<Project>{24a0aa3c-b25f-4197-b23d-476d6462dba0}</Project>
<Name>BizHawk.Client.Common</Name>
</ProjectReference>
<ProjectReference Include="..\BizHawk.Common\BizHawk.Common.csproj">
<Project>{866f8d13-0678-4ff9-80a4-a3993fd4d8a3}</Project>
<Name>BizHawk.Common</Name>
</ProjectReference>
<ProjectReference Include="..\BizHawk.Emulation.Common\BizHawk.Emulation.Common.csproj">
<Project>{e1a23168-b571-411c-b360-2229e7225e0e}</Project>
<Name>BizHawk.Emulation.Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="Classes\" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\ApiClassDiagram.cd" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,61 +1,50 @@
using System;
using System.Linq;
using System.Collections.Generic;
namespace BizHawk.Client.EmuHawk
{
public interface IToolForm
{
/// <summary>
/// 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
/// </summary>
void UpdateValues();
/// <summary>
/// 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
/// </summary>
void FastUpdate();
/// <summary>
/// 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
/// </summary>
void Restart();
/// <summary>
/// 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)
/// </summary>
/// <returns></returns>
bool AskSaveChanges();
/// <summary>
/// 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.
/// </summary>
bool UpdateBefore { get; }
//Necessary winform calls
bool Focus();
void Show();
void Close();
bool IsDisposed { get; }
bool IsHandleCreated { get; }
}
/// <summary>
/// toolform that takes automatic common configuration infrastructure
/// </summary>
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
{
/// <summary>
/// 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
/// </summary>
void UpdateValues();
/// <summary>
/// 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
/// </summary>
void FastUpdate();
/// <summary>
/// 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
/// </summary>
void Restart();
/// <summary>
/// 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)
/// </summary>
/// <returns></returns>
bool AskSaveChanges();
/// <summary>
/// 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.
/// </summary>
bool UpdateBefore { get; }
//Necessary winform calls
bool Focus();
void Show();
void Close();
bool IsDisposed { get; }
bool IsHandleCreated { get; }
}
}

View File

@ -0,0 +1,15 @@
using BizHawk.Client.EmuHawk;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BizHawk.Client.EmuHawk
{
/// <summary>
/// toolform that takes automatic common configuration infrastructure
/// </summary>
public interface IToolFormAutoConfig : IToolForm
{
}
}

View File

@ -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")]

View File

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram MajorVersion="1" MinorVersion="1" MembersFormat="FullSignature">
<Class Name="BizHawk.Client.EmuHawk.ConfigPersistAttribute">
<Position X="11.5" Y="0.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Attributes\ConfigPersistAttribute.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="BizHawk.Client.Common.Watch">
<Position X="17" Y="0.75" Width="8.75" />
<Compartments>
<Compartment Name="Nested Types" Collapsed="false" />
</Compartments>
<NestedTypes>
<Enum Name="BizHawk.Client.Common.Watch.DisplayType">
<TypeIdentifier />
</Enum>
<Enum Name="BizHawk.Client.Common.Watch.PreviousType">
<TypeIdentifier />
</Enum>
<Enum Name="BizHawk.Client.Common.Watch.WatchSize">
<TypeIdentifier />
</Enum>
</NestedTypes>
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.Common.SeparatorWatch">
<Position X="6" Y="19" Width="2.75" />
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.Common.ByteWatch">
<Position X="28.5" Y="19" Width="8.5" />
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.Common.WordWatch">
<Position X="9.5" Y="19" Width="8.75" />
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.Common.DWordWatch">
<Position X="19" Y="19" Width="8.75" />
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.Common.WatchList">
<Position X="27.25" Y="1" Width="5" />
<Compartments>
<Compartment Name="Nested Types" Collapsed="false" />
</Compartments>
<NestedTypes>
<Enum Name="BizHawk.Client.Common.WatchList.WatchPrevDef">
<TypeIdentifier />
</Enum>
</NestedTypes>
<TypeIdentifier />
<Lollipop Orientation="Right" Position="0.1" />
</Class>
<Interface Name="BizHawk.Client.EmuHawk.IExternalToolForm">
<Position X="4.5" Y="4.5" Width="2.75" />
<TypeIdentifier>
<HashCode>gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Interfaces\IExternalToolForm.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="BizHawk.Client.EmuHawk.IToolForm">
<Position X="6" Y="0.75" Width="2.25" />
<TypeIdentifier>
<HashCode>ECAAAAAAAABACAAgAAEAABAAAAAEAAAAAAAAAACAQAA=</HashCode>
<FileName>Interfaces\IToolForm.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="BizHawk.Client.EmuHawk.IToolFormAutoConfig">
<Position X="8" Y="4.5" Width="1.75" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Interfaces\IToolFormAutoConfig.cs</FileName>
</TypeIdentifier>
</Interface>
<Font Name="Segoe UI" Size="9" />
</ClassDiagram>

View File

@ -232,9 +232,16 @@
<Compile Include="SystemInfo.cs" />
<Compile Include="tools\Cheat.cs" />
<Compile Include="tools\CheatList.cs" />
<Compile Include="tools\Watch\ByteWatch.cs" />
<Compile Include="tools\Watch\DisplayType.cs" />
<Compile Include="tools\Watch\DwordWatch.cs" />
<Compile Include="tools\Watch\PreviousType.cs" />
<Compile Include="tools\RamSearchEngine.cs" />
<Compile Include="tools\Watch.cs" />
<Compile Include="tools\WatchList.cs" />
<Compile Include="tools\Watch\SeparatorWatch.cs" />
<Compile Include="tools\Watch\Watch.cs" />
<Compile Include="tools\Watch\WatchList.cs" />
<Compile Include="tools\Watch\WatchSize.cs" />
<Compile Include="tools\Watch\WordWatch.cs" />
<Compile Include="XmlGame.cs" />
</ItemGroup>
<ItemGroup>
@ -267,6 +274,7 @@
<Name>BizHawk.Bizware.BizwareGL</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PreBuildEvent>

File diff suppressed because it is too large Load Diff

View File

@ -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<DisplayType> ValidTypes
{
get
{
return new List<DisplayType>
{
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;
}
}
}
}

View File

@ -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
{
/// <summary>
/// This enum is used to specify how you want your <see cref="Watch"/> to be displayed
/// </summary>
public enum DisplayType
{
/// <summary>
/// Separator, only used by <see cref="SeparatorWatch"/>
/// </summary>
Separator,
/// <summary>
/// Display the value as a signed integer
/// Used by <see cref="ByteWatch"/>, <see cref="WordWatch"/> and <see cref="DWordWatch"/>
/// </summary>
Signed,
/// <summary>
/// Display the value as an unsigned integer
/// Used by <see cref="ByteWatch"/>, <see cref="WordWatch"/> and <see cref="DWordWatch"/>
/// </summary>
Unsigned,
/// <summary>
/// Raw hexadecimal display
/// Used by <see cref="ByteWatch"/>, <see cref="WordWatch"/> and <see cref="DWordWatch"/>
/// </summary>
Hex,
/// <summary>
/// Raw binary display
/// Used by <see cref="ByteWatch"/>, <see cref="WordWatch"/> and <see cref="DWordWatch"/>
/// If you can read it easily, you're probably a computer
/// </summary>
Binary,
/// <summary>
/// Display the value as fractionnal number. 12 before coma and 4 after
/// Used only by <see cref="WordWatch"/> as it is 16 bits length
/// </summary>
FixedPoint_12_4,
/// <summary>
/// Display the value as fractionnal number. 20 before coma and 12 after
/// Used only by <see cref="DWordWatch"/> as it is 32 bits length
/// </summary>
FixedPoint_20_12,
/// <summary>
/// Display the value as fractionnal number. 16 before coma and 16 after
/// Used only by <see cref="DWordWatch"/> as it is 32 bits length
/// </summary>
FixedPoint_16_16,
/// <summary>
/// The traditionnal float type as in C++ <seealso cref="float"/>
/// Used only by <see cref="DWordWatch"/> as it is 32 bits length
/// </summary>
Float
}
}
}

View File

@ -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<DisplayType> ValidTypes
{
get
{
return new List<DisplayType>
{
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;
}
}
}
}

View File

@ -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
}
}
}

View File

@ -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<DisplayType> ValidTypes
{
get { return new List<DisplayType> { 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; }
}
}

View File

@ -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
/// <summary>
/// Generate a <see cref="Watch"/> from a given string
/// String is tab separate
/// </summary>
/// <param name="line">Entire string, tab seperated for each value Order is:
/// <list type="number">
/// <item>
/// <term>0x00</term>
/// <description>Address in hexadecimal</description>
/// </item>
/// <item>
/// <term>b,w or d</term>
/// <description>The <see cref="WatchSize"/>, byte, word or double word</description>
/// <term>s, u, h, b, 1, 2, 3, f</term>
/// <description>The <see cref="DisplayType"/> signed, unsigned,etc...</description>
/// </item>
/// <item>
/// <term>0 or 1</term>
/// <description>Big endian or not</description>
/// </item>
/// <item>
/// <term>RDRAM,ROM,...</term>
/// <description>The <see cref="IMemoryDomains"/></description>
/// </item>
/// <item>
/// <term>Plain text</term>
/// <description>Notes</description>
/// </item>
/// </list>
/// </param>
/// <param name="domains"><see cref="Watch"/>'s memory domain</param>
/// <returns></returns>
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
/// <summary>
/// Transform the current instance into a string
/// </summary>
/// <returns>A <see cref="string"/> representation of the current <see cref="Watch"/></returns>
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
/// <summary>
/// Gets the address in the <see cref="IMemoryDomains"/>
/// </summary>
public virtual long? Address
{
get
{
return _address;
}
}
/// <summary>
/// Gets or sets the endianess of current <see cref="Watch"/>
/// True for big endian, flase for little endian
/// </summary>
public virtual bool BigEndian
{
get
{
return _bigEndian;
}
set
{
_bigEndian = value;
}
}
/// <summary>
/// Gets or set the way current <see cref="Watch"/> is displayed
/// </summary>
public virtual DisplayType Type
{
get
{
return _type;
}
set
{
_type = value;
}
}
/// <summary>
/// Gets the address in the <see cref="IMemoryDomains"/> formatted as string
/// </summary>
public virtual string AddressString
{
get
{
return _address.ToString(AddressFormatStr);
}
}
/// <summary>
/// Gets a value that defined if the current <see cref="Watch"/> is actually a <see cref="SeparatorWatch"/>
/// </summary>
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<DisplayType> 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);
}
}
}

View File

@ -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
{
/// <summary>
/// This enum specify the size of a <see cref="Watch"/>
/// </summary>
public enum WatchSize
{
/// <summary>
/// One byte (8 bits)
/// Use this for <see cref="ByteWatch"/>
/// </summary>
Byte = 1,
/// <summary>
/// 2 bytes (16 bits)
/// Use this for <see cref="WordWatch"/>
/// </summary>
Word = 2,
/// <summary>
/// 4 bytes (32 bits)
/// Use this for <see cref="DWordWatch"/>
/// </summary>
DWord = 4,
/// <summary>
/// Special case used for a separator in ramwatch
/// Use this for <see cref="SeparatorWatch"/>
/// </summary>
Separator = 0
}
}
}

View File

@ -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<DisplayType> ValidTypes
{
get
{
return new List<DisplayType>
{
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;
}
}
}
}

View File

@ -531,9 +531,7 @@
<Compile Include="CustomControls\ViewportPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CustomControls\VirtualListView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CustomControls\VirtualListView.cs" />
<Compile Include="CustomControls\Win32.cs" />
<Compile Include="DisplayManager\DisplayManager.cs" />
<Compile Include="DisplayManager\DisplaySurface.cs" />
@ -807,8 +805,6 @@
<Compile Include="tools\HexEditor\HexFind.Designer.cs">
<DependentUpon>HexFind.cs</DependentUpon>
</Compile>
<Compile Include="tools\IExternalToolForm.cs" />
<Compile Include="tools\IToolForm.cs" />
<Compile Include="tools\Lua\EnvironmentSandbox.cs" />
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Client.cs" />
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Console.cs" />
@ -1566,6 +1562,10 @@
<EmbeddedResource Include="Resources\courier16px.fnt" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BizHawk.Client.ApiHawk\BizHawk.Client.ApiHawk.csproj">
<Project>{8e2f11f2-3955-4382-8c3a-ceba1276caea}</Project>
<Name>BizHawk.Client.ApiHawk</Name>
</ProjectReference>
<ProjectReference Include="..\BizHawk.Client.Common\BizHawk.Client.Common.csproj">
<Project>{24A0AA3C-B25F-4197-B23D-476D6462DBA0}</Project>
<Name>BizHawk.Client.Common</Name>

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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