This commit is contained in:
Suuper 2016-01-29 12:30:04 -06:00
commit 6f95431637
165 changed files with 8975 additions and 3346 deletions

View File

@ -0,0 +1,92 @@
using System;
namespace BizHawk.Client.ApiHawk
{
/// <summary>
/// This class hold logic interraction for the ExternalToolAttribute
/// This attribute helps BizHawk to handle ExternalTools
/// </summary>
[AttributeUsage(AttributeTargets.Assembly)]
public sealed class BizHawkExternalToolAttribute : Attribute
{
#region Fields
private string _Name;
private string _Description;
private string _IconResourceName;
#endregion
#region cTor(s)
/// <summary>
/// Initialize a new instance of <see cref="BizHawkExternalToolAttribute"/>
/// </summary>
/// <param name="name">Tool's name</param>
/// <param name="description">Small description about the tool itself</param>
/// <param name="iconResourceName">Icon embedded resource name</param>
public BizHawkExternalToolAttribute(string name, string description, string iconResourceName)
{
_Name = name;
_Description = description;
_IconResourceName = iconResourceName;
}
/// <summary>
/// Initialize a new instance of <see cref="BizHawkExternalToolAttribute"/>
/// </summary>
/// <param name="name">Tool's name</param>
/// <param name="description">Small description about the tool itself</param>
public BizHawkExternalToolAttribute(string name, string description)
: this(name, description, string.Empty)
{ }
/// <summary>
/// Initialize a new instance of <see cref="BizHawkExternalToolAttribute"/>
/// </summary>
/// <param name="name">Tool's name</param>
public BizHawkExternalToolAttribute(string name)
:this(name, string.Empty, string.Empty)
{}
#endregion
#region Properties
/// <summary>
/// Gets tool's friendly name
/// </summary>
public string Name
{
get
{
return _Name;
}
}
/// <summary>
/// Gets tool's descriptino
/// </summary>
public string Description
{
get
{
return _Description;
}
}
/// <summary>
/// Get the name of the embedded resource icon
/// </summary>
/// <remarks>Don't forget to set compile => Embedded reource to the icon file in your project</remarks>
public string IconResourceName
{
get
{
return _IconResourceName;
}
}
#endregion
}
}

View File

@ -1,96 +1,102 @@
<?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>
<PlatformTarget>x86</PlatformTarget>
</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>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\output\dll\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\output\dll\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</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" />
<?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>
<PlatformTarget>x86</PlatformTarget>
<DocumentationFile>
</DocumentationFile>
</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>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\output\dll\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\output\dll\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<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\ExternalToolAttribute.cs" />
<Compile Include="Classes\ExternalToolManager.cs" />
<Compile Include="Interfaces\IExternalToolForm.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 />
<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

@ -0,0 +1,174 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk;
namespace BizHawk.Client.ApiHawk
{
/// <summary>
/// This static class handle all ExternalTools
/// </summary>
public static class ExternalToolManager
{
#region Fields
private static FileSystemWatcher directoryMonitor;
private static List<ToolStripMenuItem> menuItems = new List<ToolStripMenuItem>();
#endregion
#region cTor(s)
/// <summary>
/// Initilization
/// </summary>
static ExternalToolManager()
{
if(!Directory.Exists(Global.Config.PathEntries["Global", "External Tools"].Path))
{
Directory.CreateDirectory(Global.Config.PathEntries["Global", "External Tools"].Path);
}
directoryMonitor = new FileSystemWatcher(Global.Config.PathEntries["Global", "External Tools"].Path, "*.dll");
directoryMonitor.IncludeSubdirectories = false;
directoryMonitor.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName;
directoryMonitor.Filter = "*.dll";
directoryMonitor.Created += new FileSystemEventHandler(DirectoryMonitor_Created);
directoryMonitor.EnableRaisingEvents = true;
BuildToolStrip();
}
#endregion
#region Methods
/// <summary>
/// Build the toolstrip menu
/// </summary>
private static void BuildToolStrip()
{
menuItems.Clear();
if (Directory.Exists(directoryMonitor.Path))
{
DirectoryInfo dInfo = new DirectoryInfo(directoryMonitor.Path);
foreach (FileInfo fi in dInfo.GetFiles("*.dll"))
{
menuItems.Add(GenerateToolTipFromFileName(fi.FullName));
}
}
}
/// <summary>
/// Generate a <see cref="ToolStripMenuItem"/> from an
/// external tool dll.
/// The assembly must have <see cref="BizHawkExternalToolAttribute"/> in its
/// assembly attributes
/// </summary>
/// <param name="fileName">File that will be reflected</param>
/// <returns>A new <see cref="ToolStripMenuItem"/>; assembly path can be found in the Tag property</returns>
/// <remarks>For the moment, you could only load a dll that have a form (which implements <see cref="IExternalToolForm"/>)</remarks>
private static ToolStripMenuItem GenerateToolTipFromFileName(string fileName)
{
Type customFormType;
Assembly externalToolFile;
ToolStripMenuItem item = null;
try
{
externalToolFile = Assembly.LoadFrom(fileName);
object[] attributes = externalToolFile.GetCustomAttributes(typeof(BizHawkExternalToolAttribute), false);
if (attributes != null && attributes.Count() == 1)
{
BizHawkExternalToolAttribute attribute = (BizHawkExternalToolAttribute)attributes[0];
item = new ToolStripMenuItem(attribute.Name);
item.ToolTipText = attribute.Description;
if (attribute.IconResourceName != string.Empty)
{
Stream s = externalToolFile.GetManifestResourceStream(string.Format("{0}.{1}", externalToolFile.GetName().Name, attribute.IconResourceName));
if (s != null)
{
item.Image = new Bitmap(s);
}
}
customFormType = externalToolFile.GetTypes().FirstOrDefault<Type>(t => t != null && t.FullName == "BizHawk.Client.EmuHawk.CustomMainForm");
if (customFormType == null)
{
item.ToolTipText = "Does not have a CustomMainForm";
item.Enabled = false;
}
item.Tag = fileName;
}
else
{
item = new ToolStripMenuItem(externalToolFile.GetName().Name);
item.ToolTipText = "BizHawkExternalTool attribute hasn't been found";
item.Enabled = false;
}
}
catch (BadImageFormatException)
{
item = new ToolStripMenuItem(fileName);
item.ToolTipText = "This is not an assembly";
item.Enabled = false;
}
#if DEBUG //I added special debug stuff to get additionnal informations. Don(t think it can be usefull for released versions
catch (ReflectionTypeLoadException ex)
{
foreach (Exception e in ex.LoaderExceptions)
{
Debug.WriteLine(e.Message);
}
item.ToolTipText = "Something goes wrong while trying to load";
item.Enabled = false;
}
#else
catch (ReflectionTypeLoadException)
{
item.ToolTipText = "Something goes wrong while trying to load";
item.Enabled = false;
}
#endif
return item;
}
/// <summary>
/// This event is raised when we add a dll file into
/// the external tools path.
/// It will automatically load the assembly and add it into the list
/// </summary>
/// <param name="sender">Object that raised the event</param>
/// <param name="e">Event arguments</param>
private static void DirectoryMonitor_Created(object sender, FileSystemEventArgs e)
{
menuItems.Add(GenerateToolTipFromFileName(e.FullPath));
}
#endregion
#region Properties
/// <summary>
/// Gets a prebuild <see cref="ToolStripMenuItem"/>
/// This list auto-updated by the <see cref="ExternalToolManager"/> itself
/// </summary>
public static IEnumerable<ToolStripMenuItem> ToolStripMenu
{
get
{
return menuItems;
}
}
#endregion
}
}

View File

@ -1,14 +1,7 @@
<?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.75" />
<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" />
<Position X="17" Y="0.75" Width="10" />
<Compartments>
<Compartment Name="Nested Types" Collapsed="false" />
</Compartments>
@ -16,19 +9,19 @@
<Lollipop Orientation="Left" Position="0.1" />
</Class>
<Class Name="BizHawk.Client.Common.SeparatorWatch">
<Position X="6" Y="19" Width="2.75" />
<Position X="6" Y="19" Width="3.25" />
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.Common.ByteWatch">
<Position X="28.5" Y="19" Width="8.5" />
<Position X="28.5" Y="19" Width="3.25" />
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.Common.WordWatch">
<Position X="9.5" Y="19" Width="8.75" />
<Position X="9.5" Y="19" Width="3.25" />
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.Common.DWordWatch">
<Position X="19" Y="19" Width="8.75" />
<Position X="19" Y="19" Width="3.25" />
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.Common.WatchList">
@ -36,14 +29,27 @@
<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>
<Class Name="BizHawk.Client.EmuHawk.ConfigPersistAttribute">
<Position X="11.5" Y="0.75" Width="2" />
<TypeIdentifier />
</Class>
<Class Name="BizHawk.Client.ApiHawk.ExternalToolManager">
<Position X="4.75" Y="6.75" Width="4.75" />
<TypeIdentifier>
<HashCode>AAAAAQAAAAAAAAAAAAAQAAAAAAgBAAAAAAACAAAAAAI=</HashCode>
<FileName>Classes\ExternalToolManager.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="BizHawk.Client.ApiHawk.BizHawkExternalToolAttribute">
<Position X="11" Y="2.25" Width="5.75" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAgAAAAIAAAIAQAAAAAACAEAAAAAAAAAAA=</HashCode>
<FileName>Attributes\ExternalToolAttribute.cs</FileName>
</TypeIdentifier>
</Class>
<Interface Name="BizHawk.Client.EmuHawk.IExternalToolForm">
<Position X="4.5" Y="4.5" Width="2.75" />
<TypeIdentifier>
@ -53,24 +59,18 @@
</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>
<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>
<TypeIdentifier />
</Interface>
<Enum Name="BizHawk.Client.Common.WatchSize">
<Position X="26.5" Y="3.75" Width="1.5" />
<Position X="28.5" Y="5.5" Width="1.5" />
<TypeIdentifier />
</Enum>
<Enum Name="BizHawk.Client.Common.DisplayType">
<Position X="26.5" Y="1" Width="1.5" />
<Position X="28.5" Y="2.75" Width="1.5" />
<TypeIdentifier />
</Enum>
<Enum Name="BizHawk.Client.Common.PreviousType">

View File

@ -105,6 +105,7 @@
<Compile Include="BitmapBufferVideoProvider.cs" />
<Compile Include="config\Binding.cs" />
<Compile Include="config\Config.cs" />
<Compile Include="config\ConfigPersistAttribute.cs" />
<Compile Include="config\ConfigService.cs" />
<Compile Include="config\PathEntry.cs" />
<Compile Include="config\ToolDialogSettings.cs" />
@ -232,6 +233,8 @@
<Compile Include="SystemInfo.cs" />
<Compile Include="tools\Cheat.cs" />
<Compile Include="tools\CheatList.cs" />
<Compile Include="tools\Interfaces\IToolForm.cs" />
<Compile Include="tools\Interfaces\IToolFormAutoConfig.cs" />
<Compile Include="tools\Watch\ByteWatch.cs" />
<Compile Include="tools\Watch\DisplayType.cs" />
<Compile Include="tools\Watch\DWordWatch.cs" />
@ -239,9 +242,15 @@
<Compile Include="tools\RamSearchEngine.cs" />
<Compile Include="tools\Watch\SeparatorWatch.cs" />
<Compile Include="tools\Watch\Watch.cs" />
<Compile Include="tools\Watch\WatchList\WatchChangeCountComparer.cs" />
<Compile Include="tools\Watch\WatchList\WatchEqualityComparer.cs" />
<Compile Include="tools\Watch\WatchList\WatchDomainComparer.cs" />
<Compile Include="tools\Watch\WatchList\WatchAddressComparer.cs" />
<Compile Include="tools\Watch\WatchList\WatchList.cs" />
<Compile Include="tools\Watch\WatchList\WatchNoteComparer.cs" />
<Compile Include="tools\Watch\WatchList\WatchPreviousValueComparer.cs" />
<Compile Include="tools\Watch\WatchList\WatchValueComparer.cs" />
<Compile Include="tools\Watch\WatchList\WatchValueDifferenceComparer.cs" />
<Compile Include="tools\Watch\WatchSize.cs" />
<Compile Include="tools\Watch\WordWatch.cs" />
<Compile Include="XmlGame.cs" />

View File

@ -652,13 +652,16 @@ namespace BizHawk.Client.Common
rom = new RomGame(file);
game = rom.GameInfo;
}
else if(ext != null) // most extensions
else if (ext != null) // most extensions
{
rom = new RomGame(file);
//hacky for now
if (file.Extension.ToLowerInvariant() == ".exe")
rom.GameInfo.System = "PSX";
else if (file.Extension.ToLowerInvariant() == ".nsf")
rom.GameInfo.System = "NES";
if (string.IsNullOrEmpty(rom.GameInfo.System))
{

View File

@ -159,7 +159,7 @@ namespace BizHawk.Client.Common
[LuaMethodAttributes(
"islagged",
"returns whether or not the current frame is a lag frame"
"Returns whether or not the current frame is a lag frame"
)]
public bool IsLagged()
{
@ -174,6 +174,22 @@ namespace BizHawk.Client.Common
}
}
[LuaMethodAttributes(
"setislagged",
"Sets the lag flag for the current frame. If no value is provided, it will default to true"
)]
public void SetIsLagged(bool value = true)
{
if (InputPollableCore != null)
{
InputPollableCore.IsLagFrame = value;
}
else
{
Log(string.Format("Can not set lag information, {0} does not implement IInputPollable", Emulator.Attributes().CoreName));
}
}
[LuaMethodAttributes(
"lagcount",
"Returns the current lag count"

View File

@ -7,7 +7,7 @@ using BizHawk.Emulation.Common.IEmulatorExtensions;
namespace BizHawk.Client.Common
{
[Description("These functions behavior identically to the mainmemory functions but the user can set the memory domain to read and write from. The default domain is main memory. Use getcurrentmemorydomain(), and setcurrentmemorydomain() to control which domain is used. Each core has its own set of valid memory domains. Use getmemorydomainlist() to get a list of memory domains for the current core loaded.")]
[Description("These functions behavior identically to the mainmemory functions but the user can set the memory domain to read and write from. The default domain is main memory. Use getcurrentmemorydomain(), and usememorydomain() to control which domain is used. Each core has its own set of valid memory domains. Use getmemorydomainlist() to get a list of memory domains for the current core loaded.")]
public sealed class MemoryLuaLibrary : LuaMemoryBase
{
//private int _currentMemoryDomain; // Main memory by default probably (index 0 is currently always main memory but may never be)

View File

@ -219,7 +219,7 @@ namespace BizHawk.Client.Common
{
if (Movie.IsActive)
{
writer.Write(Movie.GetInputLog());
Movie.WriteInputLog(writer);
}
}

View File

@ -67,7 +67,7 @@ namespace BizHawk.Client.Common
{
if (value)
{
Header.Add(HeaderKeys.STARTSFROMSAVESTATE, "True");
Header[HeaderKeys.STARTSFROMSAVESTATE] = "True";
}
else
{

View File

@ -183,7 +183,7 @@ namespace BizHawk.Client.Common
bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString()));
bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(_syncSettingsJson));
bs.PutLump(BinaryStateLump.Input, tw => tw.WriteLine(RawInputLog()));
bs.PutLump(BinaryStateLump.Input, tw => WriteInputLog(tw));
if (StartsFromSavestate)
{

View File

@ -14,14 +14,19 @@ namespace BizHawk.Client.Common
public string GetInputLog()
{
var sb = new StringBuilder();
sb.AppendLine("[Input]");
sb.Append(RawInputLog());
sb.AppendLine("[/Input]");
var writer = new StringWriter(sb);
WriteInputLog(writer);
writer.Flush();
return sb.ToString();
}
public void WriteInputLog(TextWriter writer)
{
writer.WriteLine("[Input]");
WriteRawInputLog(writer);
writer.WriteLine("[/Input]");
}
public string GetInputLogEntry(int frame)
{
if (frame < FrameCount && frame >= 0)
@ -294,19 +299,17 @@ namespace BizHawk.Client.Common
return true;
}
protected StringBuilder RawInputLog()
protected void WriteRawInputLog(TextWriter writer)
{
var lg = new Bk2LogEntryGenerator(LogKey);
lg.SetSource(Global.MovieOutputHardpoint);
var sb = new StringBuilder();
sb.AppendLine(lg.GenerateLogKey());
writer.WriteLine(lg.GenerateLogKey());
foreach (var record in _log)
{
sb.AppendLine(record);
writer.WriteLine(record);
}
return sb;
}
/// <summary>

View File

@ -143,7 +143,7 @@ namespace BizHawk.Client.Common
class Enumerator : IEnumerator<string>
{
public DiskStringLog log;
int index;
int index = -1;
public string Current { get { return log[index]; } }
object System.Collections.IEnumerator.Current { get { return log[index]; } }
bool System.Collections.IEnumerator.MoveNext()
@ -156,7 +156,7 @@ namespace BizHawk.Client.Common
}
return true;
}
void System.Collections.IEnumerator.Reset() { index = 0; }
void System.Collections.IEnumerator.Reset() { index = -1; }
public void Dispose() { }
}

View File

@ -13,17 +13,22 @@ namespace BizHawk.Client.Common
public string GetInputLog()
{
var sb = new StringBuilder();
var writer = new StringWriter(sb);
WriteInputLog(writer);
writer.Flush();
return sb.ToString();
}
sb.AppendLine("[Input]");
public void WriteInputLog(TextWriter writer)
{
writer.WriteLine("[Input]");
foreach (var record in _log)
{
sb.AppendLine(record);
writer.WriteLine(record);
}
sb.AppendLine("[/Input]");
return sb.ToString();
writer.WriteLine("[/Input]");
}
public string GetInputLogEntry(int frame)

View File

@ -114,6 +114,11 @@ namespace BizHawk.Client.Common
/// <returns>returns a string represntation of the input log in its current state</returns>
string GetInputLog();
/// <summary>
/// Writes the input log directly to the stream, bypassing the need to load it all into ram as a string
/// </summary>
void WriteInputLog(TextWriter writer);
/// <summary>
/// Gets one frame from the input log.
/// </summary>

View File

@ -283,6 +283,11 @@ namespace BizHawk.Client.Common
{
if (IsRecording || force)
{
if (oldPosition == -1)
name = "Set Marker at frame " + newMarker.Frame;
else
name = "Remove Marker at frame " + oldPosition;
AddMovieAction(name);
History.Last().Add(new MovieActionMarker(newMarker, oldPosition, old_message));
}

View File

@ -17,23 +17,8 @@ namespace BizHawk.Client.Common
public Func<string> ClientSettingsForSave { get; set; }
public Action<string> GetClientSettingsOnLoad { get; set; }
private const double PROGRESS_STEP = 100 / 12; // TODO hardcoded for now, there might be a better way of doing this
private double _totalProgress = 0;
private void ReportProgress(double percent)
{
if (_progressReportWorker != null)
{
_totalProgress += percent;
_progressReportWorker.ReportProgress((int)_totalProgress);
}
}
protected override void Write(string fn)
{
_totalProgress = 0;
var file = new FileInfo(fn);
if (!file.Directory.Exists)
{
@ -43,29 +28,21 @@ namespace BizHawk.Client.Common
using (var bs = new BinaryStateSaver(fn, false))
{
bs.PutLump(BinaryStateLump.Movieheader, tw => tw.WriteLine(Header.ToString()));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Comments, tw => tw.WriteLine(CommentsString()));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Subtitles, tw => tw.WriteLine(Subtitles.ToString()));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.SyncSettings, tw => tw.WriteLine(SyncSettingsJson));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Input, tw => tw.WriteLine(RawInputLog()));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Input, tw => WriteInputLog(tw));
// TasProj extras
bs.PutLump(BinaryStateLump.StateHistorySettings, tw => tw.WriteLine(StateManager.Settings.ToString()));
ReportProgress(PROGRESS_STEP);
if (StateManager.Settings.SaveStateHistory)
{
bs.PutLump(BinaryStateLump.StateHistory, (BinaryWriter bw) => StateManager.Save(bw));
}
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.LagLog, (BinaryWriter bw) => LagLog.Save(bw));
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Markers, tw => tw.WriteLine(Markers.ToString()));
ReportProgress(PROGRESS_STEP);
if (StartsFromSavestate)
{
@ -82,14 +59,12 @@ namespace BizHawk.Client.Common
{
bs.PutLump(BinaryStateLump.MovieSaveRam, (BinaryWriter bw) => bw.Write(SaveRam));
}
ReportProgress(PROGRESS_STEP);
if (ClientSettingsForSave != null)
{
var clientSettingsJson = ClientSettingsForSave();
bs.PutLump(BinaryStateLump.ClientSettings, (TextWriter tw) => tw.Write(clientSettingsJson));
}
ReportProgress(PROGRESS_STEP);
if (VerificationLog.Any())
{
@ -104,7 +79,6 @@ namespace BizHawk.Client.Common
bs.PutLump(BinaryStateLump.BranchStateHistory, (BinaryWriter bw) => StateManager.SaveBranchStates(bw));
}
}
ReportProgress(PROGRESS_STEP);
bs.PutLump(BinaryStateLump.Session, tw => tw.WriteLine(Session.ToString()));
}

View File

@ -24,7 +24,7 @@ namespace BizHawk.Client.Common
public readonly IStringLog VerificationLog = StringLogUtil.MakeStringLog(); // For movies that do not begin with power-on, this is the input required to get into the initial state
public readonly TasBranchCollection Branches = new TasBranchCollection();
private BackgroundWorker _progressReportWorker = null;
public BackgroundWorker _progressReportWorker = null;
public void NewBGWorker(BackgroundWorker newWorker)
{
_progressReportWorker = newWorker;
@ -149,6 +149,16 @@ namespace BizHawk.Client.Common
}
}
public void ReportProgress(double percent)
{
if (percent > 100d)
return;
if (_progressReportWorker != null)
{
_progressReportWorker.ReportProgress((int)percent);
}
}
#region Events and Handlers
public event PropertyChangedEventHandler PropertyChanged;

View File

@ -169,7 +169,7 @@ namespace BizHawk.Client.Common
public new void Remove(TasMovieMarker item)
{
if (item == null) // TODO: Don't do this.
if (item == null || item.Frame == 0) // TODO: Don't do this.
return;
_movie.ChangeLog.AddMarkerChange(null, item.Frame, item.Message);
base.Remove(item);

View File

@ -138,6 +138,10 @@ namespace BizHawk.Client.Common
{
get
{
if (frame == 0) {
return new KeyValuePair<int, byte[]>(0, InitialState);
}
if (States.ContainsKey(frame))
{
StateAccessed(frame);
@ -316,7 +320,7 @@ namespace BizHawk.Client.Common
for (int i = from; i < upTo; i++)
{
if (!_movie[i].Lagged.Value)
if (_movie[i].Lagged == null)
return false;
}
@ -561,6 +565,7 @@ namespace BizHawk.Client.Common
bw.Write(kvp.Key);
bw.Write(kvp.Value.Length);
bw.Write(kvp.Value.State);
_movie.ReportProgress((double)100d / States.Count * i);
}
}

View File

@ -38,14 +38,21 @@ namespace BizHawk.Client.Common
internal ByteWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note, byte value, byte previous, int changeCount)
: base(domain, address, WatchSize.Byte, type, bigEndian, note)
{
this._value = value;
if (value == 0)
{
this._value = GetByte();
}
else
{
this._value = value;
}
this._previous = previous;
this._changecount = changeCount;
}
#endregion
#region Methods
#region Methods
/// <summary>
/// Enumerate wich <see cref="DisplayType"/> are valid for a <see cref="ByteWatch"/>
@ -281,7 +288,7 @@ namespace BizHawk.Client.Common
{
get
{
return FormatValue(_value);
return FormatValue(GetByte());
}
}

View File

@ -38,7 +38,14 @@ namespace BizHawk.Client.Common
internal DWordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note, uint value, uint previous, int changeCount)
: base(domain, address, WatchSize.DWord, type, bigEndian, note)
{
this._value = value;
if (value == 0)
{
this._value = GetDWord();
}
else
{
this._value = value;
}
this._previous = previous;
this._changecount = changeCount;
}

View File

@ -74,8 +74,13 @@ namespace BizHawk.Client.Common
{
get { return string.Empty; }
}
public override string ToString()
/// <summary>
/// TTransform the current instance into a displayable (short representation) string
/// It's used by the "Display on screen" option in the RamWatch window
/// </summary>
/// <returns>A well formatted string representation</returns>
public override string ToDisplayString()
{
return "----";
}

View File

@ -232,7 +232,18 @@ namespace BizHawk.Client.Common
/// <returns>True if they are equals; otherwise, false</returns>
public static bool operator ==(Watch a, Cheat b)
{
return a.Equals(b);
if (object.ReferenceEquals(a, null) || object.ReferenceEquals(b, null))
{
return false;
}
else if (object.ReferenceEquals(a, b))
{
return true;
}
else
{
return a.Equals(b);
}
}
/// <summary>
@ -547,7 +558,7 @@ namespace BizHawk.Client.Common
public override string ToString()
{
return string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}"
, Address.ToHexString((Domain.Size - 1).NumHexDigits())
, Domain == null && Address == 0 ? "0" : Address.ToHexString((Domain.Size - 1).NumHexDigits())
, SizeAsChar
, TypeAsChar
, Convert.ToInt32(BigEndian)
@ -556,6 +567,16 @@ namespace BizHawk.Client.Common
);
}
/// <summary>
/// Transform the current instance into a displayable (short representation) string
/// It's used by the "Display on screen" option in the RamWatch window
/// </summary>
/// <returns>A well formatted string representation</returns>
public virtual string ToDisplayString()
{
return string.Format("{0}: {1}", Notes, ValueString);
}
#endregion
#region Properties

View File

@ -12,83 +12,40 @@ namespace BizHawk.Client.Common
/// Netsed private class that define how to compare two <see cref="Watch"/>
/// based on their address
/// </summary>
private struct WatchAddressComparer
: IEqualityComparer<Watch>,
private sealed class WatchAddressComparer
: WatchEqualityComparer,
IComparer<Watch>
{
/// <summary>
/// Compare two <see cref="Watch"/> between them
/// and determine wich one comes first.
/// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first.
/// If they are equals, comapraison will done one the domain and next on size
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
/// <returns>True if <see cref="Watch"/> are equal; otherwise, false</returns>
/// <returns></returns>
/// <param name="y">Second <see cref="Watch"/></param>
/// <returns>0 for equality, 1 if x comes first; -1 if y comes first</returns>
public int Compare(Watch x, Watch y)
{
if (Equals(x, y))
{
return 0;
}
else if (x.Address.Equals(y.Address))
{
if (x.Domain.Name.Equals(y.Domain.Name))
if (Equals(x, y))
{
return x.Size.CompareTo(y.Size);
return 0;
}
else if (x.Address.Equals(y.Address))
{
if (x.Domain.Name.Equals(y.Domain.Name))
{
return x.Size.CompareTo(y.Size);
}
else
{
return x.Domain.Name.CompareTo(y.Domain.Name);
}
}
else
{
return x.Domain.Name.CompareTo(y.Domain.Name);
return x.Address.CompareTo(y.Address);
}
}
else
{
return x.Address.CompareTo(y.Address);
}
}
/// <summary>
/// Determine if two <see cref="Watch"/> are equals
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param>
/// <returns>True if <see cref="Watch"/> are equal; otherwise, false</returns>
public bool Equals(Watch x, Watch y)
{
if (object.ReferenceEquals(x, null))
{
if (object.ReferenceEquals(y, null))
{
return true;
}
else
{
return false;
}
}
else if (object.ReferenceEquals(y, null))
{
return false;
}
else if (object.ReferenceEquals(x, y))
{
return true;
}
else
{
return x.Address.Equals(y.Address);
}
}
/// <summary>
/// Get the hash value of specified <see cref="Watch"/>
/// </summary>
/// <param name="obj">Watch to get hash</param>
/// <returns>int that can serves as a unique representation of current Watch</returns>
public int GetHashCode(Watch obj)
{
return obj.GetHashCode();
}
}
}
}

View File

@ -0,0 +1,51 @@
using System.Collections.Generic;
namespace BizHawk.Client.Common
{
/// <summary>
/// This class hold a collection <see cref="Watch"/>
/// Different memory domain can be mixed
/// </summary>
public sealed partial class WatchList
{
/// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/>
/// based on the number of changes
/// </summary>
private sealed class WatchChangeCountComparer
:WatchEqualityComparer
,IComparer<Watch>
{
/// <summary>
/// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first.
/// If they are equals, comapraison will done one the address and next on size
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param>
/// <returns>0 for equality, 1 if x comes first; -1 if y comes first</returns>
public int Compare(Watch x, Watch y)
{
if (Equals(x, y))
{
return 0;
}
else if (x.ChangeCount.Equals(y.ChangeCount))
{
if (x.Address.Equals(y.Address))
{
return x.Size.CompareTo(y.Size);
}
else
{
return x.Address.CompareTo(y.Address);
}
}
else
{
return x.ChangeCount.CompareTo(y.ChangeCount);
}
}
}
}
}

View File

@ -12,25 +12,25 @@ namespace BizHawk.Client.Common
/// Netsed private class that define how to compare two <see cref="Watch"/>
/// based on their domain
/// </summary>
private struct WatchDomainComparer
: IEqualityComparer<Watch>,
private sealed class WatchDomainComparer
: WatchEqualityComparer,
IComparer<Watch>
{
/// <summary>
/// Compare two <see cref="Watch"/> between them
/// and determine wich one comes first.
/// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first.
/// If they are equals, comapraison will done one the address and next on size
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
/// <returns>True if <see cref="Watch"/> are equal; otherwise, false</returns>
/// <returns></returns>
///<param name="y">Second <see cref="Watch"/></param>
/// <returns>0 for equality, 1 if x comes first; -1 if y comes first</returns>
public int Compare(Watch x, Watch y)
{
if(Equals(x, y))
if (Equals(x, y))
{
return 0;
}
else if(x.Domain.Name.Equals(y.Domain.Name))
else if (x.Domain.Name.Equals(y.Domain.Name))
{
if (x.Address.Equals(y.Address))
{
@ -46,49 +46,6 @@ namespace BizHawk.Client.Common
return x.Domain.Name.CompareTo(y.Domain.Name);
}
}
/// <summary>
/// Determine if two <see cref="Watch"/> are equals
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param>
/// <returns>True if <see cref="Watch"/> are equal; otherwise, false</returns>
public bool Equals(Watch x, Watch y)
{
if(object.ReferenceEquals(x, null))
{
if(object.ReferenceEquals(y, null))
{
return true;
}
else
{
return false;
}
}
else if(object.ReferenceEquals(y, null))
{
return false;
}
else if(object.ReferenceEquals(x,y))
{
return true;
}
else
{
return x.Domain.Name.Equals(y.Domain.Name);
}
}
/// <summary>
/// Get the hash value of specified <see cref="Watch"/>
/// </summary>
/// <param name="obj">Watch to get hash</param>
/// <returns>int that can serves as a unique representation of current Watch</returns>
public int GetHashCode(Watch obj)
{
return obj.GetHashCode();
}
}
}
}

View File

@ -0,0 +1,58 @@
using System.Collections.Generic;
namespace BizHawk.Client.Common
{
/// <summary>
/// This class hold a collection <see cref="Watch"/>
/// Different memory domain can be mixed
/// </summary>
public sealed partial class WatchList
{
private class WatchEqualityComparer
: IEqualityComparer<Watch>
{
/// <summary>
/// Determines if two <see cref="Watch"/> are equals
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param>
/// <returns>True if <see cref="Watch"/> are equal; otherwise, false</returns>
public bool Equals(Watch x, Watch y)
{
if (ReferenceEquals(x, null))
{
if (ReferenceEquals(y, null))
{
return true;
}
else
{
return false;
}
}
else if (ReferenceEquals(y, null))
{
return false;
}
else if (ReferenceEquals(x, y))
{
return true;
}
else
{
return false;
}
}
/// <summary>
/// Gets the hash value of specified <see cref="Watch"/>
/// </summary>
/// <param name="obj">Watch to get hash</param>
/// <returns>int that can serves as a unique representation of current Watch</returns>
public int GetHashCode(Watch obj)
{
return obj.GetHashCode();
}
}
}
}

View File

@ -33,6 +33,11 @@ namespace BizHawk.Client.Common
private static readonly WatchDomainComparer domainComparer = new WatchDomainComparer();
private static readonly WatchAddressComparer addressComparer = new WatchAddressComparer();
private static readonly WatchValueComparer valueComparer = new WatchValueComparer();
private static readonly WatchPreviousValueComparer previousValueComparer = new WatchPreviousValueComparer();
private static readonly WatchValueDifferenceComparer valueDifferenceComparer = new WatchValueDifferenceComparer();
private static readonly WatchChangeCountComparer changeCountComparer = new WatchChangeCountComparer();
private static readonly WatchNoteComparer noteComparer = new WatchNoteComparer();
private static IMemoryDomains _memoryDomains;
@ -256,92 +261,58 @@ namespace BizHawk.Client.Common
}
break;
case VALUE:
if (reverse)
{
_watchList = _watchList
.OrderByDescending(x => x.Value)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ThenBy(x => x.BigEndian)
.ToList();
_watchList.Sort(valueComparer);
_watchList.Reverse();
}
else
{
_watchList = _watchList
.OrderBy(x => x.Value)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ThenBy(x => x.BigEndian)
.ToList();
_watchList.Sort(valueComparer);
}
break;
case PREV: // Note: these only work if all entries are detailed objects!
case PREV:
if (reverse)
{
_watchList = _watchList
.OrderByDescending(x => x.PreviousStr)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ToList();
_watchList.Sort(previousValueComparer);
_watchList.Reverse();
}
else
{
_watchList = _watchList
.OrderBy(x => x.PreviousStr)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ToList();
_watchList.Sort(previousValueComparer);
}
break;
case DIFF:
if (reverse)
{
_watchList = _watchList
.OrderByDescending(x => x.Diff)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ToList();
_watchList.Sort(valueDifferenceComparer);
_watchList.Reverse();
}
else
{
_watchList = _watchList
.OrderBy(x => x.Diff)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ToList();
_watchList.Sort(valueDifferenceComparer);
}
break;
case CHANGES:
if (reverse)
{
_watchList = _watchList
.OrderByDescending(x => x.ChangeCount)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ToList();
_watchList.Sort(changeCountComparer);
_watchList.Reverse();
}
else
{
_watchList = _watchList
.OrderBy(x => x.ChangeCount)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ToList();
_watchList.Sort(changeCountComparer);
}
break;
case DOMAIN:
if (reverse)
{
@ -354,24 +325,16 @@ namespace BizHawk.Client.Common
}
break;
case NOTES:
if (reverse)
{
_watchList = _watchList
.OrderByDescending(x => x.Notes)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ToList();
_watchList.Sort(noteComparer);
_watchList.Reverse();
}
else
{
_watchList = _watchList
.OrderBy(x => x.Notes)
.ThenBy(x => x.Address)
.ThenBy(x => x.Size)
.ThenBy(x => x.Type)
.ToList();
_watchList.Sort(noteComparer);
}
break;
@ -521,7 +484,14 @@ namespace BizHawk.Client.Common
});
}
[Obsolete("Use count property instead")]
[Obsolete("Use domain from individual watch instead")]
public MemoryDomain Domain
{
get { return _domain; }
set { _domain = value; }
}
[Obsolete("Use count property instead", true)]
public int ItemCount
{
get
@ -530,13 +500,6 @@ namespace BizHawk.Client.Common
}
}
[Obsolete("Use domain from individual watch instead")]
public MemoryDomain Domain
{
get { return _domain; }
set { _domain = value; }
}
#region File handling logic - probably needs to be its own class
public bool Load(string path, bool append)

View File

@ -0,0 +1,51 @@
using System.Collections.Generic;
namespace BizHawk.Client.Common
{
/// <summary>
/// This class hold a collection <see cref="Watch"/>
/// Different memory domain can be mixed
/// </summary>
public sealed partial class WatchList
{
/// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/>
/// based on their note
/// </summary>
private sealed class WatchNoteComparer
:WatchEqualityComparer,
IComparer<Watch>
{
/// <summary>
/// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first.
/// If they are equals, comapraison will done one the address and next on size
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param>
/// <returns>0 for equality, 1 if x comes first; -1 if y comes first</returns>
public int Compare(Watch x, Watch y)
{
if (Equals(x, y))
{
return 0;
}
else if (string.Compare(x.Notes, y.Notes, true) == 0)
{
if (x.Address.Equals(y.Address))
{
return x.Size.CompareTo(y.Size);
}
else
{
return x.Address.CompareTo(y.Address);
}
}
else
{
return string.Compare(x.Notes, y.Notes, true);
}
}
}
}
}

View File

@ -0,0 +1,51 @@
using System.Collections.Generic;
namespace BizHawk.Client.Common
{
/// <summary>
/// This class hold a collection <see cref="Watch"/>
/// Different memory domain can be mixed
/// </summary>
public sealed partial class WatchList
{
/// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/>
/// based on their previous value
/// </summary>
private sealed class WatchPreviousValueComparer
: WatchEqualityComparer,
IComparer<Watch>
{
/// <summary>
/// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first.
/// If they are equals, comapraison will done one the address and next on size
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param>
/// <returns>0 for equality, 1 if x comes first; -1 if y comes first</returns>
public int Compare(Watch x, Watch y)
{
if (Equals(x, y))
{
return 0;
}
else if (x.Previous.Equals(y.Previous))
{
if (x.Address.Equals(y.Address))
{
return x.Size.CompareTo(y.Size);
}
else
{
return x.Address.CompareTo(y.Address);
}
}
else
{
return x.Previous.CompareTo(y.Previous);
}
}
}
}
}

View File

@ -0,0 +1,72 @@
using System.Collections.Generic;
namespace BizHawk.Client.Common
{
/// <summary>
/// This class hold a collection <see cref="Watch"/>
/// Different memory domain can be mixed
/// </summary>
public sealed partial class WatchList
{
/// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/>
/// based on their values
/// </summary>
private sealed class WatchValueComparer
: WatchEqualityComparer,
IComparer<Watch>
{
/// <summary>
/// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first.
/// If they are equals, comapraison will done one the address and next on size
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
///<param name="y">Second <see cref="Watch"/></param>
/// <returns>0 for equality, 1 if x comes first; -1 if y comes first</returns>
public int Compare(Watch x, Watch y)
{
int xValue;
int yValue;
if (x.Type == DisplayType.Signed)
{
int.TryParse(x.ValueString, out xValue);
}
else
{
xValue = x.Value;
}
if (y.Type == DisplayType.Signed)
{
int.TryParse(y.ValueString, out yValue);
}
else
{
yValue = y.Value;
}
if (Equals(x, y))
{
return 0;
}
else if (xValue.Equals(yValue))
{
if (x.Address.Equals(y.Address))
{
return x.Size.CompareTo(y.Size);
}
else
{
return x.Address.CompareTo(y.Address);
}
}
else
{
return xValue.CompareTo(yValue);
}
}
}
}
}

View File

@ -0,0 +1,52 @@
using System.Collections.Generic;
namespace BizHawk.Client.Common
{
/// <summary>
/// This class hold a collection <see cref="Watch"/>
/// Different memory domain can be mixed
/// </summary>
public sealed partial class WatchList
{
/// <summary>
/// Netsed private class that define how to compare two <see cref="Watch"/>
/// based on the diffence between current and previous value
/// </summary>
private sealed class WatchValueDifferenceComparer
: WatchEqualityComparer
, IComparer<Watch>
{
/// <summary>
/// Compares two <see cref="Watch"/> between them
/// and determines wich one comes first.
/// If they are equals, comapraison will done one the address and next on size
/// </summary>
/// <param name="x">First <see cref="Watch"/></param>
/// <param name="y">Second <see cref="Watch"/></param>
/// <returns>0 for equality, 1 if x comes first; -1 if y comes first</returns>
public int Compare(Watch x, Watch y)
{
if (Equals(x, y))
{
return 0;
}
else if (x.Diff.Equals(y.Diff))
{
if (x.Address.Equals(y.Address))
{
return x.Size.CompareTo(y.Size);
}
else
{
return x.Address.CompareTo(y.Address);
}
}
else
{
return x.Diff.CompareTo(y.Diff);
}
}
}
}
}

View File

@ -38,7 +38,14 @@ namespace BizHawk.Client.Common
internal WordWatch(MemoryDomain domain, long address, DisplayType type, bool bigEndian, string note, ushort value, ushort previous, int changeCount)
: base(domain, address, WatchSize.Word, type, bigEndian, note)
{
this._value = value;
if (value == 0)
{
this._value = GetWord();
}
else
{
this._value = value;
}
this._previous = previous;
this._changecount = changeCount;
}

View File

@ -68,25 +68,6 @@ namespace BizHawk.Client.DBMan
DeleteFileW(path + ":Zone.Identifier");
}
//for debugging purposes, this is provided. when we're satisfied everyone understands whats going on, we'll get rid of this
[DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW")]
public static extern System.IntPtr CreateFileW([InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, int dwDesiredAccess, int dwShareMode, [InAttribute()] int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, [InAttribute()] int hTemplateFile);
static void ApplyMOTW(string path)
{
int generic_write = 0x40000000;
int file_share_write = 2;
int create_always = 2;
var adsHandle = CreateFileW(path + ":Zone.Identifier", generic_write, file_share_write, 0, create_always, 0, 0);
using (var sfh = new Microsoft.Win32.SafeHandles.SafeFileHandle(adsHandle, true))
{
var adsStream = new System.IO.FileStream(sfh, FileAccess.Write);
StreamWriter sw = new StreamWriter(adsStream);
sw.Write("[ZoneTransfer]\r\nZoneId=3");
sw.Flush();
adsStream.Close();
}
}
static void WhackAllMOTW(string dllDir)
{
var todo = new Queue<DirectoryInfo>(new[] { new DirectoryInfo(dllDir) });

View File

@ -123,25 +123,6 @@ namespace BizHawk.Client.DiscoHawk
DeleteFileW(path + ":Zone.Identifier");
}
//for debugging purposes, this is provided. when we're satisfied everyone understands whats going on, we'll get rid of this
[DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW")]
public static extern System.IntPtr CreateFileW([InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, int dwDesiredAccess, int dwShareMode, [InAttribute()] int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, [InAttribute()] int hTemplateFile);
static void ApplyMOTW(string path)
{
int generic_write = 0x40000000;
int file_share_write = 2;
int create_always = 2;
var adsHandle = CreateFileW(path + ":Zone.Identifier", generic_write, file_share_write, 0, create_always, 0, 0);
using (var sfh = new Microsoft.Win32.SafeHandles.SafeFileHandle(adsHandle, true))
{
var adsStream = new System.IO.FileStream(sfh, FileAccess.Write);
StreamWriter sw = new StreamWriter(adsStream);
sw.Write("[ZoneTransfer]\r\nZoneId=3");
sw.Flush();
adsStream.Close();
}
}
static void WhackAllMOTW(string dllDir)
{
var todo = new Queue<DirectoryInfo>(new[] { new DirectoryInfo(dllDir) });

View File

@ -228,7 +228,7 @@ namespace BizHawk.Client.EmuHawk
File.Delete(tempfile);
tempfile = Path.ChangeExtension(tempfile, "avi");
temp.OpenFile(tempfile, temp_params, null); //lastToken);
CodecToken token = (CodecToken)temp.AcquireVideoCodecToken(hwnd.Handle);
CodecToken token = (CodecToken)temp.AcquireVideoCodecToken(hwnd.Handle, currVideoCodecToken);
temp.CloseFile();
File.Delete(tempfile);
return token;
@ -346,66 +346,59 @@ namespace BizHawk.Client.EmuHawk
public class CodecToken : IDisposable
{
~CodecToken()
{
Dispose();
}
public static CodecToken TakePossession(Win32.AVICOMPRESSOPTIONS comprOptions)
public void Dispose() { }
private CodecToken() { }
private Win32.AVICOMPRESSOPTIONS comprOptions;
public string codec;
public byte[] Format = new byte[0];
public byte[] Parms = new byte[0];
public static CodecToken CreateFromAVICOMPRESSOPTIONS(ref Win32.AVICOMPRESSOPTIONS opts)
{
CodecToken ret = new CodecToken();
ret.allocated = true;
ret.comprOptions = comprOptions;
ret.codec = Win32.decode_mmioFOURCC(comprOptions.fccHandler);
ret.comprOptions = opts;
ret.codec = Win32.decode_mmioFOURCC(opts.fccHandler);
ret.Format = new byte[opts.cbFormat];
ret.Parms = new byte[opts.cbParms];
if(opts.lpFormat != 0) Marshal.Copy(new IntPtr(opts.lpFormat), ret.Format, 0, opts.cbFormat);
if (opts.lpParms != 0) Marshal.Copy(new IntPtr(opts.lpParms), ret.Parms, 0, opts.cbParms);
return ret;
}
private CodecToken() { }
public Win32.AVICOMPRESSOPTIONS comprOptions;
public string codec;
/// <summary>
/// true if data was allocated by AviSaveOptions and should be freed by AVISaveOptionsFree
/// </summary>
bool allocated = false;
/// <summary>
/// true if data was allocated by AllocHGlobal and should be freed by FreeHGlobal
/// </summary>
bool marshaled = false;
public void Dispose()
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool HeapFree(IntPtr hHeap, uint dwFlags, int lpMem);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetProcessHeap();
[DllImport("kernel32.dll", SetLastError = false)]
public static extern IntPtr HeapAlloc(IntPtr hHeap, uint dwFlags, int dwBytes);
public static void DeallocateAVICOMPRESSOPTIONS(ref Win32.AVICOMPRESSOPTIONS opts)
{
if (allocated)
{
IntPtr[] infPtrs = new IntPtr[1];
IntPtr mem;
// alloc unmanaged memory
mem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Win32.AVICOMPRESSOPTIONS)));
infPtrs[0] = mem;
// copy from managed structure to unmanaged memory
Marshal.StructureToPtr(comprOptions, mem, false);
Win32.AVISaveOptionsFree(1, infPtrs);
Marshal.FreeHGlobal(mem);
codec = null;
comprOptions = new Win32.AVICOMPRESSOPTIONS();
allocated = false;
}
if (marshaled)
{
IntPtr p;
p = (IntPtr)comprOptions.lpFormat;
if (p != IntPtr.Zero)
Marshal.FreeHGlobal(p);
p = (IntPtr)comprOptions.lpParms;
if (p != IntPtr.Zero)
Marshal.FreeHGlobal(p);
codec = null;
comprOptions = new Win32.AVICOMPRESSOPTIONS();
marshaled = false;
}
//test: increase stability by never freeing anything, ever
//if (opts.lpParms != 0) CodecToken.HeapFree(CodecToken.GetProcessHeap(), 0, opts.lpParms);
//if (opts.lpFormat != 0) CodecToken.HeapFree(CodecToken.GetProcessHeap(), 0, opts.lpFormat);
opts.lpParms = 0;
opts.lpFormat = 0;
}
public void AllocateToAVICOMPRESSOPTIONS(ref Win32.AVICOMPRESSOPTIONS opts)
{
opts = comprOptions;
if (opts.cbParms != 0)
{
opts.lpParms = HeapAlloc(GetProcessHeap(), 0, opts.cbParms).ToInt32();
Marshal.Copy(Parms, 0, new IntPtr(opts.lpParms), opts.cbParms);
}
if (opts.cbFormat != 0)
{
opts.lpFormat = HeapAlloc(GetProcessHeap(), 0, opts.cbFormat).ToInt32();
Marshal.Copy(Format, 0, new IntPtr(opts.lpFormat), opts.cbFormat);
}
}
byte[] SerializeToByteArray()
{
var m = new MemoryStream();
@ -422,17 +415,8 @@ namespace BizHawk.Client.EmuHawk
//b.Write(comprOptions.lpParms);
b.Write(comprOptions.cbParms);
b.Write(comprOptions.dwInterleaveEvery);
// make opaque copies of the unmanaged structs pointed to
byte[] Format = new byte[comprOptions.cbFormat];
byte[] Params = new byte[comprOptions.cbParms];
if (comprOptions.lpFormat != 0)
Marshal.Copy(new IntPtr(comprOptions.lpFormat), Format, 0, Format.Length);
if (comprOptions.lpParms != 0)
Marshal.Copy(new IntPtr(comprOptions.lpParms), Params, 0, Params.Length);
b.Write(Format);
b.Write(Params);
b.Write(Parms);
b.Close();
return m.ToArray();
}
@ -445,7 +429,7 @@ namespace BizHawk.Client.EmuHawk
Win32.AVICOMPRESSOPTIONS comprOptions = new Win32.AVICOMPRESSOPTIONS();
byte[] Format;
byte[] Params;
byte[] Parms;
try
{
@ -463,7 +447,7 @@ namespace BizHawk.Client.EmuHawk
comprOptions.dwInterleaveEvery = b.ReadInt32();
Format = b.ReadBytes(comprOptions.cbFormat);
Params = b.ReadBytes(comprOptions.cbParms);
Parms = b.ReadBytes(comprOptions.cbParms);
}
catch (IOException)
{
@ -475,27 +459,10 @@ namespace BizHawk.Client.EmuHawk
b.Close();
}
// create unmanaged copies of Format, Params
if (comprOptions.cbFormat != 0)
{
IntPtr lpFormat = Marshal.AllocHGlobal(comprOptions.cbFormat);
Marshal.Copy(Format, 0, lpFormat, comprOptions.cbFormat);
comprOptions.lpFormat = (int)lpFormat;
}
else
comprOptions.lpFormat = (int)IntPtr.Zero;
if (comprOptions.cbParms != 0)
{
IntPtr lpParms = Marshal.AllocHGlobal(comprOptions.cbParms);
Marshal.Copy(Params, 0, lpParms, comprOptions.cbParms);
comprOptions.lpParms = (int)lpParms;
}
else
comprOptions.lpParms = (int)IntPtr.Zero;
CodecToken ret = new CodecToken();
ret.marshaled = true;
ret.comprOptions = comprOptions;
ret.Format = Format;
ret.Parms = Parms;
ret.codec = Win32.decode_mmioFOURCC(comprOptions.fccHandler);
return ret;
}
@ -573,22 +540,15 @@ namespace BizHawk.Client.EmuHawk
public long GetLengthApproximation() { return outStatus.video_bytes + outStatus.audio_bytes; }
static int AVISaveOptions(IntPtr stream, ref Win32.AVICOMPRESSOPTIONS opts, IntPtr owner)
static unsafe int AVISaveOptions(IntPtr stream, ref Win32.AVICOMPRESSOPTIONS opts, IntPtr owner)
{
IntPtr mem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Win32.AVICOMPRESSOPTIONS)));
Marshal.StructureToPtr(opts, mem, false);
IntPtr[] streams = new[] { stream };
IntPtr[] infPtrs = new[] { mem };
int ret = Win32.AVISaveOptions(owner, 0, 1, streams, infPtrs);
opts = (Win32.AVICOMPRESSOPTIONS)Marshal.PtrToStructure(mem, typeof(Win32.AVICOMPRESSOPTIONS));
Marshal.FreeHGlobal(mem);
return ret;
fixed (Win32.AVICOMPRESSOPTIONS* _popts = &opts)
{
IntPtr* pStream = &stream;
Win32.AVICOMPRESSOPTIONS* popts = _popts;
Win32.AVICOMPRESSOPTIONS** ppopts = &popts;
return Win32.AVISaveOptions(owner, 0, 1, (void*)pStream, (void*)ppopts);
}
}
Parameters parameters;
@ -640,23 +600,40 @@ namespace BizHawk.Client.EmuHawk
IsOpen = true;
}
/// <summary>
/// Acquires a video codec configuration from the user
/// </summary>
public IDisposable AcquireVideoCodecToken(IntPtr hwnd)
public IDisposable AcquireVideoCodecToken(IntPtr hwnd, CodecToken lastCodecToken)
{
if (!IsOpen) throw new InvalidOperationException("File must be opened before acquiring a codec token (or else the stream formats wouldnt be known)");
if (lastCodecToken != null)
currVideoCodecToken = lastCodecToken;
//encoder params
Win32.AVICOMPRESSOPTIONS comprOptions = new Win32.AVICOMPRESSOPTIONS();
if (currVideoCodecToken != null)
{
comprOptions = currVideoCodecToken.comprOptions;
currVideoCodecToken.AllocateToAVICOMPRESSOPTIONS(ref comprOptions);
}
if (AVISaveOptions(pAviRawVideoStream, ref comprOptions, hwnd) != 0)
bool result = AVISaveOptions(pAviRawVideoStream, ref comprOptions, hwnd) != 0;
CodecToken ret = CodecToken.CreateFromAVICOMPRESSOPTIONS(ref comprOptions);
//so, AVISaveOptions may have changed some of the pointers
//if it changed the pointers, did it it free the old ones? we don't know
//let's assume it frees them. if we're wrong, we leak. if we assume otherwise and we're wrong, we may crash.
//so that means any pointers that come in here are either
//1. ones we allocated a minute ago
//2. ones VFW allocated
//guess what? doesn't matter. We'll free them all ourselves.
CodecToken.DeallocateAVICOMPRESSOPTIONS(ref comprOptions);
if(result)
{
CodecToken ret = CodecToken.TakePossession(comprOptions);
// save to config as well
// save to config and return it
Global.Config.AVICodecToken = ret.Serialize();
return ret;
}
@ -673,7 +650,12 @@ namespace BizHawk.Client.EmuHawk
throw new InvalidOperationException("set a video codec token before opening the streams!");
//open compressed video stream
if (Win32.FAILED(Win32.AVIMakeCompressedStream(out pAviCompressedVideoStream, pAviRawVideoStream, ref currVideoCodecToken.comprOptions, IntPtr.Zero)))
Win32.AVICOMPRESSOPTIONS opts = new Win32.AVICOMPRESSOPTIONS();
currVideoCodecToken.AllocateToAVICOMPRESSOPTIONS(ref opts);
bool failed = Win32.FAILED(Win32.AVIMakeCompressedStream(out pAviCompressedVideoStream, pAviRawVideoStream, ref opts, IntPtr.Zero));
CodecToken.DeallocateAVICOMPRESSOPTIONS(ref opts);
if(failed)
{
CloseStreams();
throw new InvalidOperationException("Failed making compressed video stream");

View File

@ -82,7 +82,7 @@ namespace BizHawk.Client.EmuHawk
{
ffmpeg = new Process();
#if WINDOWS
ffmpeg.StartInfo.FileName = System.IO.Path.Combine(PathManager.GetDllDirectory(), "dll", "ffmpeg.exe");
ffmpeg.StartInfo.FileName = System.IO.Path.Combine(PathManager.GetDllDirectory(), "ffmpeg.exe");
#else
ffmpeg.StartInfo.FileName = "ffmpeg"; // expecting native version to be in path
#endif

View File

@ -479,6 +479,9 @@
<Compile Include="CustomControls\HexTextBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CustomControls\HexView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="CustomControls\InputConfigBase.cs">
<SubType>Form</SubType>
</Compile>
@ -501,6 +504,12 @@
<Compile Include="CustomControls\MsgBox.designer.cs">
<DependentUpon>MsgBox.cs</DependentUpon>
</Compile>
<Compile Include="CustomControls\PrereqsAlert.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="CustomControls\PrereqsAlert.Designer.cs">
<DependentUpon>PrereqsAlert.cs</DependentUpon>
</Compile>
<Compile Include="CustomControls\QuickProgressPopup.cs">
<SubType>Form</SubType>
</Compile>
@ -807,6 +816,12 @@
<Compile Include="tools\HexEditor\HexFind.Designer.cs">
<DependentUpon>HexFind.cs</DependentUpon>
</Compile>
<Compile Include="tools\HexEditor\NewHexEditor.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="tools\HexEditor\NewHexEditor.Designer.cs">
<DependentUpon>NewHexEditor.cs</DependentUpon>
</Compile>
<Compile Include="tools\Lua\EnvironmentSandbox.cs" />
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Client.cs" />
<Compile Include="tools\Lua\Libraries\EmuLuaLibrary.Console.cs" />
@ -1318,6 +1333,9 @@
<EmbeddedResource Include="CustomControls\MsgBox.resx">
<DependentUpon>MsgBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="CustomControls\PrereqsAlert.resx">
<DependentUpon>PrereqsAlert.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="CustomControls\QuickProgressPopup.resx">
<DependentUpon>QuickProgressPopup.cs</DependentUpon>
</EmbeddedResource>
@ -1421,6 +1439,9 @@
<EmbeddedResource Include="tools\HexEditor\HexFind.resx">
<DependentUpon>HexFind.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="tools\HexEditor\NewHexEditor.resx">
<DependentUpon>NewHexEditor.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="tools\Lua\LuaCanvas.resx">
<DependentUpon>LuaCanvas.cs</DependentUpon>
</EmbeddedResource>

View File

@ -0,0 +1,116 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.CustomControls;
namespace BizHawk.Client.EmuHawk
{
public class HexView : Control
{
private readonly GDIRenderer Gdi;
private readonly Font NormalFont;
private Size _charSize;
private long _arrayLength;
public HexView()
{
NormalFont = new Font("Courier New", 8); // Only support fixed width
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.Opaque, true);
Gdi = new GDIRenderer();
using (var g = CreateGraphics())
using (var LCK = Gdi.LockGraphics(g))
{
_charSize = Gdi.MeasureString("A", NormalFont); // TODO make this a property so changing it updates other values.
}
}
protected override void Dispose(bool disposing)
{
Gdi.Dispose();
NormalFont.Dispose();
base.Dispose(disposing);
}
#region Paint
protected override void OnPaint(PaintEventArgs e)
{
using (var LCK = Gdi.LockGraphics(e.Graphics))
{
Gdi.StartOffScreenBitmap(Width, Height);
// White Background
Gdi.SetBrush(Color.White);
Gdi.SetSolidPen(Color.White);
Gdi.FillRectangle(0, 0, Width, Height);
Gdi.DrawString("Hello World", new Point(10, 10));
Gdi.CopyToScreen();
Gdi.EndOffScreenBitmap();
}
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the sets the virtual number of the length of the array to display
/// </summary>
[Category("Behavior")]
public long ArrayLength
{
get
{
return _arrayLength;
}
set
{
_arrayLength = value;
RecalculateScrollBars();
}
}
#endregion
#region Event Handlers
[Category("Virtual")]
public event QueryIndexValueHandler QueryIndexValue;
[Category("Virtual")]
public event QueryIndexBkColorHandler QueryIndexBgColor;
[Category("Virtual")]
public event QueryIndexForeColorHandler QueryIndexForeColor;
public delegate void QueryIndexValueHandler(int index, out long value);
public delegate void QueryIndexBkColorHandler(int index, ref Color color);
public delegate void QueryIndexForeColorHandler(int index, ref Color color);
#endregion
private void RecalculateScrollBars()
{
}
}
}

View File

@ -279,6 +279,12 @@ namespace BizHawk.Client.EmuHawk
[Category("Behavior")]
public bool AlwaysScroll { get; set; }
/// <summary>
/// Gets or sets the lowest seek interval to activate the progress bar
/// </summary>
[Category("Behavior")]
public int SeekingCutoffInterval { get; set; }
/// <summary>
/// Returns all columns including those that are not visible
/// </summary>

View File

@ -0,0 +1,168 @@
namespace BizHawk.Client.EmuHawk.CustomControls
{
partial class PrereqsAlert
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PrereqsAlert));
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.linkLabel2 = new System.Windows.Forms.LinkLabel();
this.label3 = new System.Windows.Forms.Label();
this.button1 = new System.Windows.Forms.Button();
this.label4 = new System.Windows.Forms.Label();
this.textBox2 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// linkLabel1
//
this.linkLabel1.AutoSize = true;
this.linkLabel1.Location = new System.Drawing.Point(21, 214);
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new System.Drawing.Size(291, 13);
this.linkLabel1.TabIndex = 0;
this.linkLabel1.TabStop = true;
this.linkLabel1.Text = "https://sourceforge.net/projects/bizhawk/files/Prerequisites";
this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(425, 13);
this.label1.TabIndex = 1;
this.label1.Text = "You\'re missing some of the following prerequisites, which prevents BizHawk from r" +
"unning:";
//
// textBox1
//
this.textBox1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBox1.Location = new System.Drawing.Point(12, 34);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.Size = new System.Drawing.Size(422, 142);
this.textBox1.TabIndex = 2;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(0, 191);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(250, 13);
this.label2.TabIndex = 3;
this.label2.Text = "You should run the latest prerequisites installer from:";
//
// linkLabel2
//
this.linkLabel2.AutoSize = true;
this.linkLabel2.Location = new System.Drawing.Point(21, 261);
this.linkLabel2.Name = "linkLabel2";
this.linkLabel2.Size = new System.Drawing.Size(168, 13);
this.linkLabel2.TabIndex = 4;
this.linkLabel2.TabStop = true;
this.linkLabel2.Text = "http://tasvideos.org/Bizhawk.html";
this.linkLabel2.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel2_LinkClicked);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(3, 238);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(282, 13);
this.label3.TabIndex = 5;
this.label3.Text = "In case that URL is gone, you can get more information at:";
//
// button1
//
this.button1.Location = new System.Drawing.Point(374, 370);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 6;
this.button1.Text = "Close";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(3, 286);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(141, 13);
this.label4.TabIndex = 7;
this.label4.Text = "Here\'s some general advice:";
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(12, 315);
this.textBox2.Multiline = true;
this.textBox2.Name = "textBox2";
this.textBox2.ReadOnly = true;
this.textBox2.Size = new System.Drawing.Size(332, 78);
this.textBox2.TabIndex = 8;
this.textBox2.Text = resources.GetString("textBox2.Text");
//
// PrereqsAlert
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(461, 402);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.label4);
this.Controls.Add(this.button1);
this.Controls.Add(this.label3);
this.Controls.Add(this.linkLabel2);
this.Controls.Add(this.label2);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.label1);
this.Controls.Add(this.linkLabel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "PrereqsAlert";
this.Text = "Prerequisites Missing!";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.LinkLabel linkLabel1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.LinkLabel linkLabel2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button button1;
public System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.TextBox textBox2;
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace BizHawk.Client.EmuHawk.CustomControls
{
public partial class PrereqsAlert : Form
{
public PrereqsAlert()
{
InitializeComponent();
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
linkLabel1.LinkVisited = true;
System.Diagnostics.Process.Start("https://sourceforge.net/projects/bizhawk/files/Prerequisites");
}
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
linkLabel2.LinkVisited = true;
System.Diagnostics.Process.Start("http://tasvideos.org/Bizhawk.html");
}
private void button1_Click(object sender, EventArgs e)
{
Close();
}
}
}

View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="textBox2.Text" xml:space="preserve">
<value>We're not checking the version number of the VC 2010 runtime. Be sure you have the SP1 version installed.
DirectX Web Update is reportedly failing for some people as part of our prereqs installer. Try installing it manually.</value>
</data>
</root>

View File

@ -7,7 +7,7 @@ using Microsoft.Win32.SafeHandles;
namespace BizHawk.Client.EmuHawk
{
public static class Win32
public unsafe static class Win32
{
public static bool Is64BitProcess { get { return (IntPtr.Size == 8); } }
public static bool Is64BitOperatingSystem { get { return Is64BitProcess || InternalCheckIsWow64(); } }
@ -386,12 +386,7 @@ namespace BizHawk.Client.EmuHawk
// Retrieve the save options for a file and returns them in a buffer
[DllImport("avifil32.dll")]
public static extern int AVISaveOptions(
IntPtr hwnd,
int flags,
int streams,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] IntPtr[] ppavi,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] IntPtr[] plpOptions);
public static extern int AVISaveOptions(IntPtr hwnd, int flags, int streams, void* ppAvi, void* plpOptions);
// Free the resources allocated by the AVISaveOptions function
[DllImport("avifil32.dll")]

View File

@ -24,5 +24,7 @@ namespace BizHawk.Client.EmuHawk
public static OSDManager OSD = new OSDManager();
public static DisplayManager DisplayManager;
public static GLManager GLManager;
public static int ExitCode;
}
}

View File

@ -2,6 +2,18 @@
{
public interface IControlMainform
{
bool WantsToControlSavestates { get; }
void SaveState();
void LoadState();
void SaveStateAs();
void LoadStateAs();
void SaveQuickSave(int slot);
void LoadQuickSave(int slot);
void SelectSlot(int slot);
void PreviousSlot();
void NextSlot();
bool WantsToControlReadOnly { get; }
/// <summary>

View File

@ -181,10 +181,10 @@ namespace BizHawk.Client.EmuHawk
AddItem("LStickLeft", () => state.Gamepad.sThumbLX <= dzn);
AddItem("LStickRight", () => state.Gamepad.sThumbLX >= dzp);
AddItem("RStickUp", () => state.Gamepad.sThumbLY >= dzp);
AddItem("RStickDown", () => state.Gamepad.sThumbLY <= dzn);
AddItem("RStickLeft", () => state.Gamepad.sThumbLX <= dzn);
AddItem("RStickRight", () => state.Gamepad.sThumbLX >= dzp);
AddItem("RStickUp", () => state.Gamepad.sThumbRY >= dzp);
AddItem("RStickDown", () => state.Gamepad.sThumbRY <= dzn);
AddItem("RStickLeft", () => state.Gamepad.sThumbRX <= dzn);
AddItem("RStickRight", () => state.Gamepad.sThumbRX >= dzp);
AddItem("LeftTrigger", () => state.Gamepad.bLeftTrigger > dzt);
AddItem("RightTrigger", () => state.Gamepad.bRightTrigger > dzt);

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@ using BizHawk.Client.EmuHawk.CustomControls;
using BizHawk.Client.EmuHawk.WinFormExtensions;
using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Emulation.Cores.Computers.AppleII;
using BizHawk.Client.ApiHawk;
namespace BizHawk.Client.EmuHawk
{
@ -237,6 +238,7 @@ namespace BizHawk.Client.EmuHawk
StopMovieMenuItem.Enabled
= PlayFromBeginningMenuItem.Enabled
= SaveMovieMenuItem.Enabled
= SaveMovieAsMenuItem.Enabled
= Global.MovieSession.Movie.IsActive;
ReadonlyMenuItem.Checked = Global.MovieSession.ReadOnly;
@ -275,18 +277,20 @@ namespace BizHawk.Client.EmuHawk
private void AVSubMenu_DropDownOpened(object sender, EventArgs e)
{
RecordAVMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Record A/V"].Bindings;
ConfigAndRecordAVMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Record A/V"].Bindings;
StopAVIMenuItem.ShortcutKeyDisplayString = Global.Config.HotkeyBindings["Stop A/V"].Bindings;
CaptureOSDMenuItem.Checked = Global.Config.AVI_CaptureOSD;
RecordAVMenuItem.Enabled = !string.IsNullOrEmpty(Global.Config.VideoWriter) && _currAviWriter == null;
if (_currAviWriter == null)
{
RecordAVMenuItem.Enabled = true;
ConfigAndRecordAVMenuItem.Enabled = true;
StopAVIMenuItem.Enabled = false;
}
else
{
RecordAVMenuItem.Enabled = false;
ConfigAndRecordAVMenuItem.Enabled = false;
StopAVIMenuItem.Enabled = true;
}
}
@ -548,8 +552,32 @@ namespace BizHawk.Client.EmuHawk
SaveMovie();
}
private void SaveMovieAsMenuItem_Click(object sender, EventArgs e)
{
var filename = Global.MovieSession.Movie.Filename;
if (string.IsNullOrWhiteSpace(filename))
{
filename = PathManager.FilesystemSafeName(Global.Game);
}
var file = ToolHelpers.SaveFileDialog(
filename,
PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null),
"Movie Files",
Global.MovieSession.Movie.PreferredExtension);
if (file != null)
{
Global.MovieSession.Movie.Filename = file.FullName;
Global.Config.RecentMovies.Add(Global.MovieSession.Movie.Filename);
SaveMovie();
}
}
private void StopMovieWithoutSavingMenuItem_Click(object sender, EventArgs e)
{
if (Global.Config.EnableBackupMovies)
Global.MovieSession.Movie.SaveBackup();
StopMovie(saveChanges: false);
}
@ -583,11 +611,16 @@ namespace BizHawk.Client.EmuHawk
Global.Config.MovieEndAction = MovieEndAction.Pause;
}
private void RecordAVMenuItem_Click(object sender, EventArgs e)
private void ConfigAndRecordAVMenuItem_Click(object sender, EventArgs e)
{
RecordAv();
}
private void RecordAVMenuItem_Click(object sender, EventArgs e)
{
RecordAv(null, null); // force unattended, but allow tradtional setup
}
private void StopAVMenuItem_Click(object sender, EventArgs e)
{
StopAv();
@ -661,6 +694,12 @@ namespace BizHawk.Client.EmuHawk
_exit = true;
}
public void CloseEmulator(int exitCode)
{
_exit = true;
_exitCode = exitCode;
}
#endregion
#region Emulation Menu
@ -1174,6 +1213,24 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.OSD.AddMessage("Saved settings");
}
private void SaveConfigAsMenuItem_Click(object sender, EventArgs e)
{
var path = PathManager.DefaultIniPath;
var sfd = new SaveFileDialog
{
InitialDirectory = Path.GetDirectoryName(path),
FileName = Path.GetFileName(path),
Filter = "Config File (*.ini)|*.ini"
};
var result = sfd.ShowHawkDialog();
if (result == DialogResult.OK)
{
SaveConfig(sfd.FileName);
GlobalWin.OSD.AddMessage("Copied settings");
}
}
private void LoadConfigMenuItem_Click(object sender, EventArgs e)
{
Global.Config = ConfigService.Load<Config>(PathManager.DefaultIniPath);
@ -1181,6 +1238,25 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.OSD.AddMessage("Config file loaded");
}
private void LoadConfigFromMenuItem_Click(object sender, EventArgs e)
{
var path = PathManager.DefaultIniPath;
var ofd = new OpenFileDialog
{
InitialDirectory = Path.GetDirectoryName(path),
FileName = Path.GetFileName(path),
Filter = "Config File (*.ini)|*.ini"
};
var result = ofd.ShowHawkDialog();
if (result == DialogResult.OK)
{
Global.Config = ConfigService.Load<Config>(ofd.FileName);
Global.Config.ResolveDefaults();
GlobalWin.OSD.AddMessage("Config file loaded");
}
}
private void miUnthrottled_Click(object sender, EventArgs e)
{
_unthrottled ^= true;
@ -1246,82 +1322,45 @@ namespace BizHawk.Client.EmuHawk
batchRunnerToolStripMenuItem.Visible = VersionInfo.DeveloperBuild;
AutoHawkMenuItem.Enabled = GlobalWin.Tools.IsAvailable<AutoHawk>();
AutoHawkMenuItem.Visible = VersionInfo.DeveloperBuild;
BasicBotMenuItem.Enabled = GlobalWin.Tools.IsAvailable<BasicBot>();
gameSharkConverterToolStripMenuItem.Enabled = GlobalWin.Tools.IsAvailable<GameShark>();
ExperimentalToolsSubMenu.Visible = VersionInfo.DeveloperBuild;
}
private void ExternalToolToolStripMenuItem_DropDownOpening(object sender, EventArgs e)
{
externalToolToolStripMenuItem.DropDownItems.Clear();
string path = Path.Combine(Global.Config.PathEntries["Global", "External Tools"].Path);
if (Directory.Exists(path))
foreach(ToolStripMenuItem item in ExternalToolManager.ToolStripMenu)
{
DirectoryInfo dInfo = new DirectoryInfo(path);
Type[] assemblyTypes;
Assembly externalToolFile;
foreach (FileInfo fi in dInfo.GetFiles("*.dll"))
if(item.Enabled)
{
try
item.Click += delegate
{
//externalToolFile = Assembly.ReflectionOnlyLoadFrom(fi.FullName);
externalToolFile = Assembly.LoadFrom(fi.FullName);
}
catch (BadImageFormatException)
{
ToolStripMenuItem item = new ToolStripMenuItem(fi.Name, Properties.Resources.ExclamationRed);
item.ToolTipText = "This is not an assembly";
item.ForeColor = Color.Gray;
externalToolToolStripMenuItem.DropDownItems.Add(item);
continue;
}
ToolStripMenuItem externalToolMenu = new ToolStripMenuItem(externalToolFile.GetName().Name);
/*
The reason of using this ugly try catch is due to the use of ReflectionOnlyLoadFrom methods
When the assembly is loaded this way, referenced assemblies are not loaded and so, as soon as a type
existing in another assembly, it raises the exception.
But the advantage of this is that memory footprint is reduced
EDIT: In fact, I have some trouble when loading Reflection only... moved to regular load
*/
try
{
assemblyTypes = externalToolFile.GetTypes().Where<Type>(t => t != null && t.FullName == "BizHawk.Client.EmuHawk.CustomMainForm").ToArray<Type>();
}
catch (ReflectionTypeLoadException ex)
{
assemblyTypes = ex.Types.Where<Type>(t => t != null && t.FullName.Contains("BizHawk.Client.EmuHawk.CustomMainForm")).ToArray<Type>();
}
if (assemblyTypes.Count() == 1)
{
externalToolMenu.Image = Properties.Resources.Debugger;
externalToolMenu.Tag = fi.FullName;
externalToolMenu.Click += delegate (object sender2, EventArgs e2)
{
GlobalWin.Tools.Load<IExternalToolForm>(fi.FullName);
};
}
else
{
externalToolMenu.Image = Properties.Resources.ExclamationRed;
externalToolMenu.ForeColor = Color.Gray;
}
externalToolToolStripMenuItem.DropDownItems.Add(externalToolMenu);
GlobalWin.Tools.Load<IExternalToolForm>((string)item.Tag);
};
}
else
{
item.Image = Properties.Resources.ExclamationRed;
}
externalToolToolStripMenuItem.DropDownItems.Add(item);
}
if (externalToolToolStripMenuItem.DropDownItems.Count == 0)
{
externalToolToolStripMenuItem.DropDownItems.Add("None");
}
}
private void ExperimentalToolsSubMenu_DropDownOpened(object sender, EventArgs e)
{
AutoHawkMenuItem.Enabled = GlobalWin.Tools.IsAvailable<AutoHawk>();
NewHexEditorMenuItem.Enabled = GlobalWin.Tools.IsAvailable<NewHexEditor>();
}
private void AutoHawkMenuItem_Click(object sender, EventArgs e)
{
GlobalWin.Tools.Load<AutoHawk>();
@ -1392,6 +1431,11 @@ namespace BizHawk.Client.EmuHawk
new BatchRun().ShowDialog();
}
private void NewHexEditorMenuItem_Click(object sender, EventArgs e)
{
GlobalWin.Tools.Load<NewHexEditor>();
}
#endregion
#region NES
@ -2301,6 +2345,7 @@ namespace BizHawk.Client.EmuHawk
ViewSubtitlesContextMenuItem.Visible =
ViewCommentsContextMenuItem.Visible =
SaveMovieContextMenuItem.Visible =
SaveMovieAsContextMenuItem.Visible =
Global.MovieSession.Movie.IsActive;
BackupMovieContextMenuItem.Visible = Global.MovieSession.Movie.IsActive;

View File

@ -343,10 +343,10 @@ namespace BizHawk.Client.EmuHawk
//TAStudio
case "Add Branch":
GlobalWin.Tools.TAStudio.BookMarkControl.AddBranchExternal();
GlobalWin.Tools.TAStudio.AddBranchExternal();
break;
case "Delete Branch":
GlobalWin.Tools.TAStudio.BookMarkControl.RemoveBranchExtrenal();
GlobalWin.Tools.TAStudio.RemoveBranchExtrenal();
break;
// SNES

View File

@ -405,7 +405,7 @@ namespace BizHawk.Client.EmuHawk
if (startFullscreen || Global.Config.StartFullscreen)
{
ToggleFullscreen();
_needsFullscreenOnLoad = true;
}
if (!Global.Game.IsNullInstance)
@ -462,11 +462,25 @@ namespace BizHawk.Client.EmuHawk
private bool _supressSyncSettingsWarning = false;
public void ProgramRunLoop()
public int ProgramRunLoop()
{
CheckMessages();
CheckMessages(); //can someone leave a note about why this is needed?
LogConsole.PositionConsole();
//needs to be done late, after the log console snaps on top
//fullscreen should snap on top even harder!
if (_needsFullscreenOnLoad)
{
_needsFullscreenOnLoad = false;
ToggleFullscreen();
}
//incantation required to get the program reliably on top of the console window
//we might want it in ToggleFullscreen later, but here, it needs to happen regardless
BringToFront();
Activate();
BringToFront();
for (;;)
{
Input.Instance.Update();
@ -531,6 +545,7 @@ namespace BizHawk.Client.EmuHawk
}
Shutdown();
return _exitCode;
}
/// <summary>
@ -1308,6 +1323,7 @@ namespace BizHawk.Client.EmuHawk
private bool _avwriterpad;
private bool _exit;
private int _exitCode;
private bool _exitRequestPending;
private bool _runloopFrameProgress;
private long _frameAdvanceTimestamp;
@ -1330,6 +1346,7 @@ namespace BizHawk.Client.EmuHawk
private bool _cursorHidden;
private bool _inFullscreen;
private Point _windowedLocation;
private bool _needsFullscreenOnLoad;
private int _autoDumpLength;
private readonly bool _autoCloseOnDump;
@ -1570,22 +1587,6 @@ namespace BizHawk.Client.EmuHawk
}
}
private void SelectSlot(int num)
{
if (Global.Emulator.HasSavestates())
{
if (GlobalWin.Tools.Has<TAStudio>())
{
GlobalWin.Tools.TAStudio.BookMarkControl.SelectBranchExternal(num);
return;
}
Global.Config.SaveSlot = num;
SaveSlotSelectedMessage();
UpdateStatusSlots();
}
}
private void RewireSound()
{
if (_dumpProxy != null)
@ -1888,75 +1889,6 @@ namespace BizHawk.Client.EmuHawk
return bb;
}
private void SaveStateAs()
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (GlobalWin.Tools.Has<TAStudio>())
{
return;
}
var path = PathManager.GetSaveStatePath(Global.Game);
var file = new FileInfo(path);
if (file.Directory != null && file.Directory.Exists == false)
{
file.Directory.Create();
}
var sfd = new SaveFileDialog
{
AddExtension = true,
DefaultExt = "State",
Filter = "Save States (*.State)|*.State|All Files|*.*",
InitialDirectory = path,
FileName = PathManager.SaveStatePrefix(Global.Game) + "." + "QuickSave0.State"
};
var result = sfd.ShowHawkDialog();
if (result == DialogResult.OK)
{
SaveState(sfd.FileName, sfd.FileName, false);
}
}
private void LoadStateAs()
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (GlobalWin.Tools.Has<TAStudio>())
{
return;
}
var ofd = new OpenFileDialog
{
InitialDirectory = PathManager.GetSaveStatePath(Global.Game),
Filter = "Save States (*.State)|*.State|All Files|*.*",
RestoreDirectory = true
};
var result = ofd.ShowHawkDialog();
if (result != DialogResult.OK)
{
return;
}
if (File.Exists(ofd.FileName) == false)
{
return;
}
LoadState(ofd.FileName, Path.GetFileName(ofd.FileName));
}
private void SaveSlotSelectedMessage()
{
int slot = Global.Config.SaveSlot;
@ -2168,7 +2100,7 @@ namespace BizHawk.Client.EmuHawk
}
}
private void SaveConfig()
private void SaveConfig(string path = "")
{
if (Global.Config.SaveWindowPosition)
{
@ -2193,63 +2125,10 @@ namespace BizHawk.Client.EmuHawk
LogConsole.SaveConfigSettings();
}
ConfigService.Save(PathManager.DefaultIniPath, Global.Config);
}
if (string.IsNullOrEmpty(path))
path = PathManager.DefaultIniPath;
private void PreviousSlot()
{
if (Global.Emulator.HasSavestates())
{
if (GlobalWin.Tools.Has<TAStudio>())
{
GlobalWin.Tools.TAStudio.BookMarkControl.SelectBranchExternal(false);
return;
}
if (Global.Config.SaveSlot == 0)
{
Global.Config.SaveSlot = 9; // Wrap to end of slot list
}
else if (Global.Config.SaveSlot > 9)
{
Global.Config.SaveSlot = 9; // Meh, just in case
}
else
{
Global.Config.SaveSlot--;
}
SaveSlotSelectedMessage();
UpdateStatusSlots();
}
}
private void NextSlot()
{
if (Global.Emulator.HasSavestates())
{
if (GlobalWin.Tools.Has<TAStudio>())
{
GlobalWin.Tools.TAStudio.BookMarkControl.SelectBranchExternal(true);
return;
}
if (Global.Config.SaveSlot >= 9)
{
Global.Config.SaveSlot = 0; // Wrap to beginning of slot list
}
else if (Global.Config.SaveSlot < 0)
{
Global.Config.SaveSlot = 0; // Meh, just in case
}
else
{
Global.Config.SaveSlot++;
}
SaveSlotSelectedMessage();
UpdateStatusSlots();
}
ConfigService.Save(path, Global.Config);
}
private static void ToggleFPS()
@ -2708,112 +2587,6 @@ namespace BizHawk.Client.EmuHawk
});
}
private int SlotToInt(string slot)
{
return int.Parse(slot.Substring(slot.Length - 1, 1));
}
public void LoadState(string path, string userFriendlyStateName, bool fromLua = false, bool supressOSD = false) // Move to client.common
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (GlobalWin.Tools.Has<TAStudio>())
{
GlobalWin.Tools.TAStudio.BookMarkControl.LoadBranchExternal();
return;
}
// If from lua, disable counting rerecords
bool wasCountingRerecords = Global.MovieSession.Movie.IsCountingRerecords;
if (fromLua)
Global.MovieSession.Movie.IsCountingRerecords = false;
GlobalWin.DisplayManager.NeedsToPaint = true;
if (SavestateManager.LoadStateFile(path, userFriendlyStateName))
{
SetMainformMovieInfo();
GlobalWin.OSD.ClearGUIText();
GlobalWin.Tools.UpdateToolsBefore(fromLua);
UpdateToolsAfter(fromLua);
UpdateToolsLoadstate();
Global.AutoFireController.ClearStarts();
if (!supressOSD)
{
GlobalWin.OSD.AddMessage("Loaded state: " + userFriendlyStateName);
}
if (GlobalWin.Tools.Has<LuaConsole>())
{
GlobalWin.Tools.LuaConsole.LuaImp.CallLoadStateEvent(userFriendlyStateName);
}
}
else
{
GlobalWin.OSD.AddMessage("Loadstate error!");
}
Global.MovieSession.Movie.IsCountingRerecords = wasCountingRerecords;
}
public void LoadQuickSave(string quickSlotName, bool fromLua = false, bool supressOSD = false)
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (GlobalWin.Tools.Has<TAStudio>())
{
GlobalWin.Tools.TAStudio.BookMarkControl.LoadBranchExternal(SlotToInt(quickSlotName));
return;
}
var path = PathManager.SaveStatePrefix(Global.Game) + "." + quickSlotName + ".State";
if (File.Exists(path) == false)
{
GlobalWin.OSD.AddMessage("Unable to load " + quickSlotName + ".State");
return;
}
LoadState(path, quickSlotName, fromLua, supressOSD);
}
public void SaveState(string path, string userFriendlyStateName, bool fromLua)
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (GlobalWin.Tools.Has<TAStudio>())
{
GlobalWin.Tools.TAStudio.BookMarkControl.UpdateBranchExternal();
return;
}
try
{
SavestateManager.SaveStateFile(path, userFriendlyStateName);
GlobalWin.OSD.AddMessage("Saved state: " + userFriendlyStateName);
}
catch (IOException)
{
GlobalWin.OSD.AddMessage("Unable to save state " + path);
}
if (!fromLua)
{
UpdateStatusSlots();
}
}
// Alt key hacks
protected override void WndProc(ref Message m)
{
@ -3075,6 +2848,10 @@ namespace BizHawk.Client.EmuHawk
{
PauseEmulator();
PauseOnFrame = null;
if (GlobalWin.Tools.IsLoaded<TAStudio>())
{
GlobalWin.Tools.TAStudio.StopSeeking();
}
}
}
@ -3128,10 +2905,12 @@ namespace BizHawk.Client.EmuHawk
// select IVideoWriter to use
IVideoWriter aw = null;
if (unattended)
if (string.IsNullOrEmpty(videowritername) && !string.IsNullOrEmpty(Global.Config.VideoWriter))
videowritername = Global.Config.VideoWriter;
if (unattended && !string.IsNullOrEmpty(videowritername))
{
aw = VideoWriterInventory.GetVideoWriter(videowritername);
}
else
{
@ -3149,6 +2928,8 @@ namespace BizHawk.Client.EmuHawk
try
{
bool usingAvi = aw is AviWriter; //SO GROSS!
if (_dumpaudiosync)
{
aw = new VideoStretcher(aw);
@ -3172,12 +2953,17 @@ namespace BizHawk.Client.EmuHawk
// select codec token
// do this before save dialog because ffmpeg won't know what extension it wants until it's been configured
if (unattended)
if (unattended && !string.IsNullOrEmpty(filename))
{
aw.SetDefaultVideoCodecToken();
}
else
{
//THIS IS REALLY SLOPPY!
//PLEASE REDO ME TO NOT CARE WHICH AVWRITER IS USED!
if(usingAvi && !string.IsNullOrEmpty(Global.Config.AVICodecToken))
aw.SetDefaultVideoCodecToken();
var token = aw.AcquireVideoCodecToken(this);
if (token == null)
{
@ -3190,7 +2976,7 @@ namespace BizHawk.Client.EmuHawk
}
// select file to save to
if (unattended)
if (unattended && !string.IsNullOrEmpty(filename))
{
aw.OpenFile(filename);
}
@ -3725,50 +3511,6 @@ namespace BizHawk.Client.EmuHawk
}
}
// TODO: should backup logic be stuffed in into Client.Common.SaveStateManager?
public void SaveQuickSave(string quickSlotName)
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (GlobalWin.Tools.Has<TAStudio>())
{
GlobalWin.Tools.TAStudio.BookMarkControl.UpdateBranchExternal(SlotToInt(quickSlotName));
return;
}
var path = PathManager.SaveStatePrefix(Global.Game) + "." + quickSlotName + ".State";
var file = new FileInfo(path);
if (file.Directory != null && file.Directory.Exists == false)
{
file.Directory.Create();
}
// Make backup first
if (Global.Config.BackupSavestates && file.Exists)
{
var backup = path + ".bak";
var backupFile = new FileInfo(backup);
if (backupFile.Exists)
{
backupFile.Delete();
}
File.Move(path, backup);
}
SaveState(path, quickSlotName, false);
if (GlobalWin.Tools.Has<LuaConsole>())
{
GlobalWin.Tools.LuaConsole.LuaImp.CallSaveStateEvent(quickSlotName);
}
}
private static void CommitCoreSettingsToConfig()
{
// save settings object
@ -3894,11 +3636,315 @@ namespace BizHawk.Client.EmuHawk
// TODO: move me
public IControlMainform master { get; private set; }
public void RelinquishControl(IControlMainform master)
{
this.master = master;
}
private bool IsSlave
{
get { return master != null; }
}
public void TakeBackControl()
{
master = null;
}
private int SlotToInt(string slot)
{
return int.Parse(slot.Substring(slot.Length - 1, 1));
}
public void LoadState(string path, string userFriendlyStateName, bool fromLua = false, bool supressOSD = false) // Move to client.common
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (IsSlave && master.WantsToControlSavestates)
{
master.LoadState();
return;
}
// If from lua, disable counting rerecords
bool wasCountingRerecords = Global.MovieSession.Movie.IsCountingRerecords;
if (fromLua)
Global.MovieSession.Movie.IsCountingRerecords = false;
GlobalWin.DisplayManager.NeedsToPaint = true;
if (SavestateManager.LoadStateFile(path, userFriendlyStateName))
{
SetMainformMovieInfo();
GlobalWin.OSD.ClearGUIText();
GlobalWin.Tools.UpdateToolsBefore(fromLua);
UpdateToolsAfter(fromLua);
UpdateToolsLoadstate();
Global.AutoFireController.ClearStarts();
if (!supressOSD)
{
GlobalWin.OSD.AddMessage("Loaded state: " + userFriendlyStateName);
}
if (GlobalWin.Tools.Has<LuaConsole>())
{
GlobalWin.Tools.LuaConsole.LuaImp.CallLoadStateEvent(userFriendlyStateName);
}
}
else
{
GlobalWin.OSD.AddMessage("Loadstate error!");
}
Global.MovieSession.Movie.IsCountingRerecords = wasCountingRerecords;
}
public void LoadQuickSave(string quickSlotName, bool fromLua = false, bool supressOSD = false)
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (IsSlave && master.WantsToControlSavestates)
{
master.LoadQuickSave(SlotToInt(quickSlotName));
return;
}
var path = PathManager.SaveStatePrefix(Global.Game) + "." + quickSlotName + ".State";
if (File.Exists(path) == false)
{
GlobalWin.OSD.AddMessage("Unable to load " + quickSlotName + ".State");
return;
}
LoadState(path, quickSlotName, fromLua, supressOSD);
}
public void SaveState(string path, string userFriendlyStateName, bool fromLua)
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (IsSlave && master.WantsToControlSavestates)
{
master.SaveState();
return;
}
try
{
SavestateManager.SaveStateFile(path, userFriendlyStateName);
GlobalWin.OSD.AddMessage("Saved state: " + userFriendlyStateName);
}
catch (IOException)
{
GlobalWin.OSD.AddMessage("Unable to save state " + path);
}
if (!fromLua)
{
UpdateStatusSlots();
}
}
// TODO: should backup logic be stuffed in into Client.Common.SaveStateManager?
public void SaveQuickSave(string quickSlotName)
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (IsSlave && master.WantsToControlSavestates)
{
master.SaveQuickSave(SlotToInt(quickSlotName));
return;
}
var path = PathManager.SaveStatePrefix(Global.Game) + "." + quickSlotName + ".State";
var file = new FileInfo(path);
if (file.Directory != null && file.Directory.Exists == false)
{
file.Directory.Create();
}
// Make backup first
if (Global.Config.BackupSavestates && file.Exists)
{
var backup = path + ".bak";
var backupFile = new FileInfo(backup);
if (backupFile.Exists)
{
backupFile.Delete();
}
File.Move(path, backup);
}
SaveState(path, quickSlotName, false);
if (GlobalWin.Tools.Has<LuaConsole>())
{
GlobalWin.Tools.LuaConsole.LuaImp.CallSaveStateEvent(quickSlotName);
}
}
private void SaveStateAs()
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (IsSlave && master.WantsToControlSavestates)
{
master.SaveStateAs();
return;
}
var path = PathManager.GetSaveStatePath(Global.Game);
var file = new FileInfo(path);
if (file.Directory != null && file.Directory.Exists == false)
{
file.Directory.Create();
}
var sfd = new SaveFileDialog
{
AddExtension = true,
DefaultExt = "State",
Filter = "Save States (*.State)|*.State|All Files|*.*",
InitialDirectory = path,
FileName = PathManager.SaveStatePrefix(Global.Game) + "." + "QuickSave0.State"
};
var result = sfd.ShowHawkDialog();
if (result == DialogResult.OK)
{
SaveState(sfd.FileName, sfd.FileName, false);
}
}
private void LoadStateAs()
{
if (!Global.Emulator.HasSavestates())
{
return;
}
if (IsSlave && master.WantsToControlSavestates)
{
master.LoadStateAs();
return;
}
var ofd = new OpenFileDialog
{
InitialDirectory = PathManager.GetSaveStatePath(Global.Game),
Filter = "Save States (*.State)|*.State|All Files|*.*",
RestoreDirectory = true
};
var result = ofd.ShowHawkDialog();
if (result != DialogResult.OK)
{
return;
}
if (File.Exists(ofd.FileName) == false)
{
return;
}
LoadState(ofd.FileName, Path.GetFileName(ofd.FileName));
}
private void SelectSlot(int slot)
{
if (Global.Emulator.HasSavestates())
{
if (IsSlave && master.WantsToControlSavestates)
{
master.SelectSlot(slot);
return;
}
Global.Config.SaveSlot = slot;
SaveSlotSelectedMessage();
UpdateStatusSlots();
}
}
private void PreviousSlot()
{
if (Global.Emulator.HasSavestates())
{
if (IsSlave && master.WantsToControlSavestates)
{
master.PreviousSlot();
return;
}
if (Global.Config.SaveSlot == 0)
{
Global.Config.SaveSlot = 9; // Wrap to end of slot list
}
else if (Global.Config.SaveSlot > 9)
{
Global.Config.SaveSlot = 9; // Meh, just in case
}
else
{
Global.Config.SaveSlot--;
}
SaveSlotSelectedMessage();
UpdateStatusSlots();
}
}
private void NextSlot()
{
if (Global.Emulator.HasSavestates())
{
if (IsSlave && master.WantsToControlSavestates)
{
master.NextSlot();
return;
}
if (Global.Config.SaveSlot >= 9)
{
Global.Config.SaveSlot = 0; // Wrap to beginning of slot list
}
else if (Global.Config.SaveSlot < 0)
{
Global.Config.SaveSlot = 0; // Meh, just in case
}
else
{
Global.Config.SaveSlot++;
}
SaveSlotSelectedMessage();
UpdateStatusSlots();
}
}
private void ToggleReadOnly()
{
if (IsSlave && master.WantsToControlReadOnly)
@ -3933,16 +3979,6 @@ namespace BizHawk.Client.EmuHawk
}
}
private bool IsSlave
{
get { return master != null; }
}
public void TakeBackControl()
{
master = null;
}
private void GBAcoresettingsToolStripMenuItem1_Click(object sender, EventArgs e)
{
GenericCoreConfig.DoDialog(this, "Gameboy Advance Settings");
@ -3967,7 +4003,7 @@ namespace BizHawk.Client.EmuHawk
{
if (Global.ClientControls["Rewind"] || PressRewind)
{
runFrame = false; // TODO: the master should be deciding this!
runFrame = true; // TODO: the master should be deciding this!
return master.Rewind();
}
}
@ -4061,6 +4097,5 @@ namespace BizHawk.Client.EmuHawk
quickNESToolStripMenuItem.Checked = Global.Config.NES_InQuickNES == true;
nesHawkToolStripMenuItem.Checked = Global.Config.NES_InQuickNES == false;
}
}
}

View File

@ -123,453 +123,463 @@
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="DisplayConfigMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
vAAADrwBlbxySQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTFH80I3AAABpElEQVQ4T52T
QUsCURSF33+SDAUxRAyEwQiEksiFUJEMhGEDOcQgRi2UGJBgCkFIZDDbGEGWEsTMItBNrdu3ad3y1Hmk
VNosvHC4l3u+A2/ezIi/5fP58D1OlJf3qzRNmwCn7TzrZ8AzfGk3kM1mkcvlUCgUUCqVUKlUUK1WwSDF
mTt6ZMgyw6zIZDIYDAYziVmRTqfhui5WDhoI7VxAMa6xdvKIDWsgxZk7emTIRiIR2ZkVqVQKvV4Pc1vn
+OI9RYas4ziyMyuSySQ6nQ7mt2s4unuH6XxMFT0yZHkCdmZFIpFAs9lEUK1Drb9g82wIrfWK4s2bFGfu
6JEh2+12ZWdWxONxWJYln3HddBDVWlNFjwxZnoCdWRGNRlEul7Gw20Tm9Amr5YepokeGbLvdlp1ZEQ6H
YRgGInl7fPP/iQzZkZgVwWAQ+XweS3s1LO5fyVe2fHiL5PG9FGfu6JEhOxKzwu/3Q1VV6LoO0zRh2zb6
/f74Y+HMHT0yZEdiVhQNXQ6BQAChUEheUCwWkxekKIoUZ+7okSHLDLPyf3geuphFQgjxCdiQMGrYYwVf
AAAAAElFTkSuQmCC
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAAOuAAA
DrgBakH1WwAAAa9JREFUOE+dk0FrGlEUhd9/kloUxCBiQRBLQUglxIXQlspAMdiBKmEIlmahhAEJmBII
NMiQ2I0hEBOlUMZFwWzadffZdN3lab8HE1pjXEQ43Os539HxzWjMwisWi2nRi96vyv7ruK5750OWefd9
kfX/LawsnwbHqtVqqtfrajabarfb6na76vV6oojY8chgYOnQNdVqVfP5/EGiayqVimazmda3j5V680kF
70wbe1/1oj+3Yscjg4HNZDJ20jXlclmTyUSPXn3UX36lYGDDMLSTrimVShqNRnr8+lAfLn/JD38vFRkM
LFfApGuKxaIGg4GSzpGcox96eXAt9+Snds5vrNjxyGBgx+OxnXRNPp9Xv9+3v3HTD5V1T5aKDAaWK2DS
NdlsVp1OR2tbA1X3v+l558tSkcHADodDO+madDotz/OUaQS3Jx/dgcUJAxuJrkkmk2o0Gnr69lBP3n22
t+zZ+wuVdq+s2PHIYGAj0TXxeFyO46jVasn3fQVBoOl0evtgseORwcBGomt2vJZYEomEUqmUPaBcLmcP
qFAoWLHjkcHA0qFr/zjfr2d6iOj+AdiQMGoJxWWRAAAAAElFTkSuQmCC
</value>
</data>
<data name="FirmwaresMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAQ
SgAAEEoBNcinnwAAAHBJREFUOE/NkOEKACEIg330e/NOA2PqTqL+XPBpbcMokUfGFUy0xTrFitogNHgG
qUJDzs58ERpydua1/OwJiv967hQr4QkfaHJSPDzYICR4OwOOsOK3+c2Oh/I5QMUEDijD1gbMEiKZpaF5
BBW3kfECg6SiSi9TP3UAAAAASUVORK5CYII=
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAAQRgAA
EEYB7r8o6AAAAHVJREFUOE/NkuEKwCAIhN2b781bGsZlarH9aIEEcX2eVxfdVOjTYoCpUhef2d3qWnMR
AoTEkV9OMwEMdQTwsxGc9PU19l7BS5qhNVyuOXS4wFlgoXgL4FoMHHUtfqTIgZ6HGaw6I2CCDXMmGagu
BaycvB4hAz9wYIvatCqJLwAAAABJRU5ErkJggg==
</value>
</data>
<data name="gameSharkConverterToolStripMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAASUVORK5CYII=
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
</value>
</data>
<data name="N64PluginSettingsMenuItem.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<metadata name="MainStatusBar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
@ -580,24 +590,25 @@
</metadata>
<data name="toolStripMenuItem8.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO
vAAADrwBlbxySQAAABp0RVh0U29mdHdhcmUAUGFpbnQuTkVUIHYzLjUuMTFH80I3AAABpElEQVQ4T52T
QUsCURSF33+SDAUxRAyEwQiEksiFUJEMhGEDOcQgRi2UGJBgCkFIZDDbGEGWEsTMItBNrdu3ad3y1Hmk
VNosvHC4l3u+A2/ezIi/5fP58D1OlJf3qzRNmwCn7TzrZ8AzfGk3kM1mkcvlUCgUUCqVUKlUUK1WwSDF
mTt6ZMgyw6zIZDIYDAYziVmRTqfhui5WDhoI7VxAMa6xdvKIDWsgxZk7emTIRiIR2ZkVqVQKvV4Pc1vn
+OI9RYas4ziyMyuSySQ6nQ7mt2s4unuH6XxMFT0yZHkCdmZFIpFAs9lEUK1Drb9g82wIrfWK4s2bFGfu
6JEh2+12ZWdWxONxWJYln3HddBDVWlNFjwxZnoCdWRGNRlEul7Gw20Tm9Amr5YepokeGbLvdlp1ZEQ6H
YRgGInl7fPP/iQzZkZgVwWAQ+XweS3s1LO5fyVe2fHiL5PG9FGfu6JEhOxKzwu/3Q1VV6LoO0zRh2zb6
/f74Y+HMHT0yZEdiVhQNXQ6BQAChUEheUCwWkxekKIoUZ+7okSHLDLPyf3geuphFQgjxCdiQMGrYYwVf
AAAAAElFTkSuQmCC
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAAOuAAA
DrgBakH1WwAAAa9JREFUOE+dk0FrGlEUhd9/kloUxCBiQRBLQUglxIXQlspAMdiBKmEIlmahhAEJmBII
NMiQ2I0hEBOlUMZFwWzadffZdN3lab8HE1pjXEQ43Os539HxzWjMwisWi2nRi96vyv7ruK5750OWefd9
kfX/LawsnwbHqtVqqtfrajabarfb6na76vV6oojY8chgYOnQNdVqVfP5/EGiayqVimazmda3j5V680kF
70wbe1/1oj+3Yscjg4HNZDJ20jXlclmTyUSPXn3UX36lYGDDMLSTrimVShqNRnr8+lAfLn/JD38vFRkM
LFfApGuKxaIGg4GSzpGcox96eXAt9+Snds5vrNjxyGBgx+OxnXRNPp9Xv9+3v3HTD5V1T5aKDAaWK2DS
NdlsVp1OR2tbA1X3v+l558tSkcHADodDO+madDotz/OUaQS3Jx/dgcUJAxuJrkkmk2o0Gnr69lBP3n22
t+zZ+wuVdq+s2PHIYGAj0TXxeFyO46jVasn3fQVBoOl0evtgseORwcBGomt2vJZYEomEUqmUPaBcLmcP
qFAoWLHjkcHA0qFr/zjfr2d6iOj+AdiQMGoJxWWRAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolStripMenuItem11.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAQ
SgAAEEoBNcinnwAAAHBJREFUOE/NkOEKACEIg330e/NOA2PqTqL+XPBpbcMokUfGFUy0xTrFitogNHgG
qUJDzs58ERpydua1/OwJiv967hQr4QkfaHJSPDzYICR4OwOOsOK3+c2Oh/I5QMUEDijD1gbMEiKZpaF5
BBW3kfECg6SiSi9TP3UAAAAASUVORK5CYII=
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAAQRgAA
EEYB7r8o6AAAAHVJREFUOE/NkuEKwCAIhN2b781bGsZlarH9aIEEcX2eVxfdVOjTYoCpUhef2d3qWnMR
AoTEkV9OMwEMdQTwsxGc9PU19l7BS5qhNVyuOXS4wFlgoXgL4FoMHHUtfqTIgZ6HGaw6I2CCDXMmGagu
BaycvB4hAz9wYIvatCqJLwAAAABJRU5ErkJggg==
</value>
</data>
<metadata name="timerMouseIdle.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">

View File

@ -19,6 +19,37 @@ namespace BizHawk.Client.EmuHawk
{
//http://www.codeproject.com/Articles/310675/AppDomain-AssemblyResolve-Event-Tips
#if WINDOWS
//try loading libraries we know we'll need
//something in the winforms, etc. code below will cause .net to popup a missing msvcr100.dll in case that one's missing
//but oddly it lets us proceed and we'll then catch it here
var d3dx9 = Win32.LoadLibrary("d3dx9_43.dll");
var vc2015 = Win32.LoadLibrary("vcruntime140.dll");
var vc2010 = Win32.LoadLibrary("msvcr100.dll"); //TODO - check version?
var vc2010p = Win32.LoadLibrary("msvcp100.dll");
bool fail = false;
fail |= d3dx9 == IntPtr.Zero;
fail |= vc2015 == IntPtr.Zero;
fail |= vc2010 == IntPtr.Zero;
fail |= vc2010p == IntPtr.Zero;
if (fail)
{
var sw = new System.IO.StringWriter();
sw.WriteLine("[ OK ] .Net 4.0 (You couldn't even get here without it)");
sw.WriteLine("[{0}] Direct3d 9", d3dx9 == IntPtr.Zero ? "FAIL" : " OK ");
sw.WriteLine("[{0}] Visual C++ 2010 SP1 Runtime", (vc2010 == IntPtr.Zero || vc2010p == IntPtr.Zero) ? "FAIL" : " OK ");
sw.WriteLine("[{0}] Visual C++ 2015 Runtime", (vc2015 == IntPtr.Zero) ? "FAIL" : " OK ");
var str = sw.ToString();
var box = new BizHawk.Client.EmuHawk.CustomControls.PrereqsAlert();
box.textBox1.Text = str;
box.ShowDialog();
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
Win32.FreeLibrary(d3dx9);
Win32.FreeLibrary(vc2015);
Win32.FreeLibrary(vc2010);
Win32.FreeLibrary(vc2010p);
// this will look in subdirectory "dll" to load pinvoked stuff
string dllDir = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll");
SetDllDirectory(dllDir);
@ -30,18 +61,29 @@ namespace BizHawk.Client.EmuHawk
//in case assembly resolution fails, such as if we moved them into the dll subdiretory, this event handler can reroute to them
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
#endif
}
[STAThread]
static void Main(string[] args)
static int Main(string[] args)
{
SubMain(args);
return SubMain(args);
}
private static class Win32
{
[DllImport("kernel32.dll")]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32.dll")]
public static extern bool FreeLibrary(IntPtr hModule);
}
//NoInlining should keep this code from getting jammed into Main() which would create dependencies on types which havent been setup by the resolver yet... or something like that
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
static void SubMain(string[] args)
static int SubMain(string[] args)
{
// this check has to be done VERY early. i stepped through a debug build with wrong .dll versions purposely used,
// and there was a TypeLoadException before the first line of SubMain was reached (some static ColorType init?)
@ -55,7 +97,7 @@ namespace BizHawk.Client.EmuHawk
if (thisversion != utilversion || thisversion != emulversion)
{
MessageBox.Show("Conflicting revisions found! Don't mix .dll versions!");
return;
return -1;
}
}
@ -138,7 +180,7 @@ namespace BizHawk.Client.EmuHawk
mf.Show();
mf.Text = title;
mf.ProgramRunLoop();
GlobalWin.ExitCode = mf.ProgramRunLoop();
}
}
}
@ -169,13 +211,13 @@ namespace BizHawk.Client.EmuHawk
if (System.Diagnostics.Debugger.IsAttached)
{
mf.ProgramRunLoop();
GlobalWin.ExitCode = mf.ProgramRunLoop();
}
else
{
try
{
mf.ProgramRunLoop();
GlobalWin.ExitCode = mf.ProgramRunLoop();
}
catch (Exception e)
{
@ -227,6 +269,8 @@ namespace BizHawk.Client.EmuHawk
// GlobalWin.GL.Dispose();
//((IDisposable)GlobalWin.IGL_GL).Dispose();
//return 0 assuming things have gone well, non-zero values could be used as error codes or for scripting purposes
return GlobalWin.ExitCode;
} //SubMain
//declared here instead of a more usual place to avoid dependencies on the more usual place
@ -241,25 +285,6 @@ namespace BizHawk.Client.EmuHawk
DeleteFileW(path + ":Zone.Identifier");
}
//for debugging purposes, this is provided. when we're satisfied everyone understands whats going on, we'll get rid of this
[DllImportAttribute("kernel32.dll", EntryPoint = "CreateFileW")]
public static extern IntPtr CreateFileW([InAttribute()] [MarshalAsAttribute(UnmanagedType.LPWStr)] string lpFileName, int dwDesiredAccess, int dwShareMode, [InAttribute()] int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, [InAttribute()] int hTemplateFile);
static void ApplyMOTW(string path)
{
int generic_write = 0x40000000;
int file_share_write = 2;
int create_always = 2;
var adsHandle = CreateFileW(path + ":Zone.Identifier", generic_write, file_share_write, 0, create_always, 0, 0);
using (var sfh = new Microsoft.Win32.SafeHandles.SafeFileHandle(adsHandle, true))
{
var adsStream = new FileStream(sfh, FileAccess.Write);
StreamWriter sw = new StreamWriter(adsStream);
sw.Write("[ZoneTransfer]\r\nZoneId=3");
sw.Flush();
adsStream.Close();
}
}
static void WhackAllMOTW(string dllDir)
{
var todo = new Queue<DirectoryInfo>(new[] { new DirectoryInfo(dllDir) });
@ -319,7 +344,7 @@ namespace BizHawk.Client.EmuHawk
var title = MainForm.Text;
MainForm.Show();
MainForm.Text = title;
(MainForm as MainForm).ProgramRunLoop();
GlobalWin.ExitCode = (MainForm as MainForm).ProgramRunLoop();
}
}

View File

@ -58,7 +58,7 @@ namespace BizHawk.Client.EmuHawk
//notably, if we're frame-advancing, we should be paused.
if (signal_paused && !signal_continuousframeAdvancing)
{
Console.WriteLine("THE THING: {0} {1}", signal_paused ,signal_continuousframeAdvancing);
//Console.WriteLine("THE THING: {0} {1}", signal_paused ,signal_continuousframeAdvancing);
skipnextframe = false;
framesskipped = 0;
framestoskip = 0;

View File

@ -64,6 +64,8 @@
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.groupBox5 = new System.Windows.Forms.GroupBox();
this.cbLEC = new System.Windows.Forms.CheckBox();
this.cbGpuLag = new System.Windows.Forms.CheckBox();
this.groupBox6 = new System.Windows.Forms.GroupBox();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox3.SuspendLayout();
@ -73,6 +75,7 @@
((System.ComponentModel.ISupportInitialize)(this.NTSC_FirstLineNumeric)).BeginInit();
this.groupBox4.SuspendLayout();
this.groupBox5.SuspendLayout();
this.groupBox6.SuspendLayout();
this.SuspendLayout();
//
// btnCancel
@ -454,10 +457,10 @@
this.groupBox5.Controls.Add(this.cbLEC);
this.groupBox5.Location = new System.Drawing.Point(12, 306);
this.groupBox5.Name = "groupBox5";
this.groupBox5.Size = new System.Drawing.Size(299, 85);
this.groupBox5.Size = new System.Drawing.Size(238, 85);
this.groupBox5.TabIndex = 47;
this.groupBox5.TabStop = false;
this.groupBox5.Text = "Emulation";
this.groupBox5.Text = "Emulation Sync Settings";
//
// cbLEC
//
@ -469,6 +472,28 @@
this.cbLEC.Text = "Emulate Sector Error Correction\r\n(usually unneeded; breaks some patches)";
this.cbLEC.UseVisualStyleBackColor = true;
//
// cbGpuLag
//
this.cbGpuLag.AutoSize = true;
this.cbGpuLag.Location = new System.Drawing.Point(16, 19);
this.cbGpuLag.Name = "cbGpuLag";
this.cbGpuLag.Size = new System.Drawing.Size(181, 17);
this.cbGpuLag.TabIndex = 1;
this.cbGpuLag.Text = "Determine Lag from GPU Frames";
this.cbGpuLag.UseVisualStyleBackColor = true;
//
// groupBox6
//
this.groupBox6.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox6.Controls.Add(this.cbGpuLag);
this.groupBox6.Location = new System.Drawing.Point(264, 308);
this.groupBox6.Name = "groupBox6";
this.groupBox6.Size = new System.Drawing.Size(238, 85);
this.groupBox6.TabIndex = 48;
this.groupBox6.TabStop = false;
this.groupBox6.Text = "Emulation User Settings";
//
// PSXOptions
//
this.AcceptButton = this.btnOk;
@ -476,6 +501,7 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(713, 405);
this.Controls.Add(this.groupBox6);
this.Controls.Add(this.groupBox5);
this.Controls.Add(this.groupBox4);
this.Controls.Add(this.groupBox2);
@ -501,6 +527,8 @@
this.groupBox4.PerformLayout();
this.groupBox5.ResumeLayout(false);
this.groupBox5.PerformLayout();
this.groupBox6.ResumeLayout(false);
this.groupBox6.PerformLayout();
this.ResumeLayout(false);
}
@ -541,5 +569,7 @@
private System.Windows.Forms.RadioButton rbBob;
private System.Windows.Forms.GroupBox groupBox5;
private System.Windows.Forms.CheckBox cbLEC;
private System.Windows.Forms.CheckBox cbGpuLag;
private System.Windows.Forms.GroupBox groupBox6;
}
}

View File

@ -42,6 +42,7 @@ namespace BizHawk.Client.EmuHawk
rbClipToFramebuffer.Checked = _settings.HorizontalClipping == Octoshock.eHorizontalClipping.Framebuffer;
cbLEC.Checked = _syncSettings.EnableLEC;
cbGpuLag.Checked = _settings.GPULag;
rbWeave.Checked = _settings.DeinterlaceMode == Octoshock.eDeinterlaceMode.Weave;
rbBob.Checked = _settings.DeinterlaceMode == Octoshock.eDeinterlaceMode.Bob;
@ -98,6 +99,8 @@ namespace BizHawk.Client.EmuHawk
settings.ScanlineStart_PAL = (int)PAL_FirstLineNumeric.Value;
settings.ScanlineEnd_PAL = (int)PAL_LastLineNumeric.Value;
settings.GPULag = cbGpuLag.Checked;
syncSettings.EnableLEC = cbLEC.Checked;
}

View File

@ -41,7 +41,7 @@
// Ok
//
this.Ok.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.Ok.Location = new System.Drawing.Point(471, 411);
this.Ok.Location = new System.Drawing.Point(616, 505);
this.Ok.Name = "Ok";
this.Ok.Size = new System.Drawing.Size(75, 23);
this.Ok.TabIndex = 0;
@ -53,7 +53,7 @@
//
this.Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.Cancel.Location = new System.Drawing.Point(552, 411);
this.Cancel.Location = new System.Drawing.Point(697, 505);
this.Cancel.Name = "Cancel";
this.Cancel.Size = new System.Drawing.Size(75, 23);
this.Cancel.TabIndex = 1;
@ -70,13 +70,13 @@
this.PathTabControl.Multiline = true;
this.PathTabControl.Name = "PathTabControl";
this.PathTabControl.SelectedIndex = 0;
this.PathTabControl.Size = new System.Drawing.Size(615, 364);
this.PathTabControl.Size = new System.Drawing.Size(760, 458);
this.PathTabControl.TabIndex = 2;
//
// SaveBtn
//
this.SaveBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.SaveBtn.Location = new System.Drawing.Point(12, 411);
this.SaveBtn.Location = new System.Drawing.Point(12, 505);
this.SaveBtn.Name = "SaveBtn";
this.SaveBtn.Size = new System.Drawing.Size(75, 23);
this.SaveBtn.TabIndex = 3;
@ -88,7 +88,7 @@
//
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(527, 19);
this.label1.Location = new System.Drawing.Point(672, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(97, 13);
this.label1.TabIndex = 210;
@ -98,7 +98,7 @@
//
this.SpecialCommandsBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.SpecialCommandsBtn.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Help;
this.SpecialCommandsBtn.Location = new System.Drawing.Point(496, 14);
this.SpecialCommandsBtn.Location = new System.Drawing.Point(641, 14);
this.SpecialCommandsBtn.Name = "SpecialCommandsBtn";
this.SpecialCommandsBtn.Size = new System.Drawing.Size(26, 23);
this.SpecialCommandsBtn.TabIndex = 209;
@ -119,7 +119,7 @@
// DefaultsBtn
//
this.DefaultsBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.DefaultsBtn.Location = new System.Drawing.Point(93, 411);
this.DefaultsBtn.Location = new System.Drawing.Point(93, 505);
this.DefaultsBtn.Name = "DefaultsBtn";
this.DefaultsBtn.Size = new System.Drawing.Size(75, 23);
this.DefaultsBtn.TabIndex = 211;
@ -133,7 +133,7 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.Cancel;
this.ClientSize = new System.Drawing.Size(639, 446);
this.ClientSize = new System.Drawing.Size(784, 540);
this.Controls.Add(this.DefaultsBtn);
this.Controls.Add(this.label1);
this.Controls.Add(this.SpecialCommandsBtn);

View File

@ -32,20 +32,22 @@
this.btnCancel = new System.Windows.Forms.Button();
this.rbCompatibility = new System.Windows.Forms.RadioButton();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.label2 = new System.Windows.Forms.Label();
this.rbAccuracy = new System.Windows.Forms.RadioButton();
this.rbPerformance = new System.Windows.Forms.RadioButton();
this.cbRingbuf = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.cbDoubleSize = new System.Windows.Forms.CheckBox();
this.lblDoubleSize = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.cbForceDeterminism = new System.Windows.Forms.CheckBox();
this.label3 = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// btnOk
//
this.btnOk.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnOk.Location = new System.Drawing.Point(136, 277);
this.btnOk.Location = new System.Drawing.Point(136, 344);
this.btnOk.Name = "btnOk";
this.btnOk.Size = new System.Drawing.Size(75, 23);
this.btnOk.TabIndex = 0;
@ -57,7 +59,7 @@
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(217, 277);
this.btnCancel.Location = new System.Drawing.Point(217, 344);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 1;
@ -89,6 +91,14 @@
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Core Selection";
//
// label2
//
this.label2.Location = new System.Drawing.Point(72, 85);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(136, 21);
this.label2.TabIndex = 8;
this.label2.Text = "NOT SUPPORTED YET!";
//
// rbAccuracy
//
this.rbAccuracy.AutoSize = true;
@ -152,13 +162,25 @@
"orce the SNES output to stay double-size always. NOTE: The Accuracy core runs as" +
" if this is selected.\r\n";
//
// label2
// cbForceDeterminism
//
this.label2.Location = new System.Drawing.Point(72, 85);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(136, 21);
this.label2.TabIndex = 8;
this.label2.Text = "NOT SUPPORTED YET!";
this.cbForceDeterminism.AutoSize = true;
this.cbForceDeterminism.Location = new System.Drawing.Point(19, 271);
this.cbForceDeterminism.Name = "cbForceDeterminism";
this.cbForceDeterminism.Size = new System.Drawing.Size(113, 17);
this.cbForceDeterminism.TabIndex = 8;
this.cbForceDeterminism.Text = "Force Determinism";
this.cbForceDeterminism.UseVisualStyleBackColor = true;
this.cbForceDeterminism.CheckedChanged += new System.EventHandler(this.cbForceDeterminism_CheckedChanged);
//
// label3
//
this.label3.Location = new System.Drawing.Point(38, 295);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(251, 41);
this.label3.TabIndex = 9;
this.label3.Text = "Guarantee deterministic emulation by savestating every frame. Don\'t TAS without i" +
"t! Only ~75% of runs sync without it, but speed boost is ~30%.";
//
// SNESOptions
//
@ -166,7 +188,9 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnCancel;
this.ClientSize = new System.Drawing.Size(304, 312);
this.ClientSize = new System.Drawing.Size(304, 379);
this.Controls.Add(this.label3);
this.Controls.Add(this.cbForceDeterminism);
this.Controls.Add(this.lblDoubleSize);
this.Controls.Add(this.cbDoubleSize);
this.Controls.Add(this.label1);
@ -202,5 +226,7 @@
private System.Windows.Forms.Label lblDoubleSize;
private System.Windows.Forms.RadioButton rbAccuracy;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.CheckBox cbForceDeterminism;
private System.Windows.Forms.Label label3;
}
}

View File

@ -15,6 +15,35 @@ namespace BizHawk.Client.EmuHawk
bool SuppressDoubleSize;
bool UserDoubleSizeOption;
public static void DoSettingsDialog(IWin32Window owner)
{
var s = ((LibsnesCore)Global.Emulator).GetSettings();
var ss = ((LibsnesCore)Global.Emulator).GetSyncSettings();
var dlg = new SNESOptions
{
UseRingBuffer = s.UseRingBuffer,
AlwaysDoubleSize = s.AlwaysDoubleSize,
ForceDeterminism = s.ForceDeterminism,
Profile = ss.Profile
};
var result = dlg.ShowDialog(owner);
if (result == DialogResult.OK)
{
s.UseRingBuffer = dlg.UseRingBuffer;
s.AlwaysDoubleSize = dlg.AlwaysDoubleSize;
s.ForceDeterminism = dlg.ForceDeterminism;
ss.Profile = dlg.Profile;
GlobalWin.MainForm.PutCoreSettings(s);
GlobalWin.MainForm.PutCoreSyncSettings(ss);
}
}
private void SNESOptions_Load(object sender, EventArgs e)
{
rbAccuracy.Visible = VersionInfo.DeveloperBuild;
}
public string Profile
{
get
@ -45,6 +74,39 @@ namespace BizHawk.Client.EmuHawk
set { UserDoubleSizeOption = value; RefreshDoubleSizeOption(); }
}
public bool ForceDeterminism
{
get { return cbForceDeterminism.Checked; }
set { cbForceDeterminism.Checked = value; }
}
void RefreshDoubleSizeOption()
{
SuppressDoubleSize = true;
if (cbDoubleSize.Enabled)
cbDoubleSize.Checked = UserDoubleSizeOption;
else cbDoubleSize.Checked = true;
SuppressDoubleSize = false;
}
private void rbAccuracy_CheckedChanged(object sender, EventArgs e)
{
cbDoubleSize.Enabled = !rbAccuracy.Checked;
lblDoubleSize.ForeColor = cbDoubleSize.Enabled ? System.Drawing.SystemColors.ControlText : System.Drawing.SystemColors.GrayText;
RefreshDoubleSizeOption();
}
private void cbDoubleSize_CheckedChanged(object sender, EventArgs e)
{
if (SuppressDoubleSize) return;
UserDoubleSizeOption = cbDoubleSize.Checked;
}
private void cbForceDeterminism_CheckedChanged(object sender, EventArgs e)
{
}
private void btnOk_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
@ -57,54 +119,5 @@ namespace BizHawk.Client.EmuHawk
Close();
}
public static void DoSettingsDialog(IWin32Window owner)
{
var s = ((LibsnesCore)Global.Emulator).GetSettings();
var ss = ((LibsnesCore)Global.Emulator).GetSyncSettings();
var dlg = new SNESOptions
{
UseRingBuffer = s.UseRingBuffer,
AlwaysDoubleSize = s.AlwaysDoubleSize,
Profile = ss.Profile
};
var result = dlg.ShowDialog(owner);
if (result == DialogResult.OK)
{
s.UseRingBuffer = dlg.UseRingBuffer;
s.AlwaysDoubleSize = dlg.AlwaysDoubleSize;
ss.Profile = dlg.Profile;
GlobalWin.MainForm.PutCoreSettings(s);
GlobalWin.MainForm.PutCoreSyncSettings(ss);
}
}
private void rbAccuracy_CheckedChanged(object sender, EventArgs e)
{
cbDoubleSize.Enabled = !rbAccuracy.Checked;
lblDoubleSize.ForeColor = cbDoubleSize.Enabled ? System.Drawing.SystemColors.ControlText : System.Drawing.SystemColors.GrayText;
RefreshDoubleSizeOption();
}
void RefreshDoubleSizeOption()
{
SuppressDoubleSize = true;
if (cbDoubleSize.Enabled)
cbDoubleSize.Checked = UserDoubleSizeOption;
else cbDoubleSize.Checked = true;
SuppressDoubleSize = false;
}
private void cbDoubleSize_CheckedChanged(object sender, EventArgs e)
{
if (SuppressDoubleSize) return;
UserDoubleSizeOption = cbDoubleSize.Checked;
}
private void SNESOptions_Load(object sender, EventArgs e)
{
rbAccuracy.Visible = VersionInfo.DeveloperBuild;
}
}
}

View File

@ -150,10 +150,32 @@ namespace BizHawk.Client.EmuHawk
}
private void BrowseBtn_Click(object sender, EventArgs e)
{
{
string movieFolderPath = PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null);
// Create movie folder if it doesn't already exist
try
{
if (!Directory.Exists(movieFolderPath))
{
Directory.CreateDirectory(movieFolderPath);
}
}
catch (Exception movieDirException)
{
if (movieDirException is IOException ||
movieDirException is UnauthorizedAccessException ||
movieDirException is PathTooLongException
)
{
//TO DO : Pass error to user?
}
else throw;
}
var sfd = new SaveFileDialog
{
InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries.MoviesPathFragment, null),
InitialDirectory = movieFolderPath,
DefaultExt = "." + Global.MovieSession.Movie.PreferredExtension,
FileName = RecordBox.Text,
OverwritePrompt = false,

File diff suppressed because it is too large Load Diff

View File

@ -44,6 +44,7 @@ namespace BizHawk.Client.EmuHawk
private bool _oldCountingSetting = false;
private BotAttempt _currentBotAttempt = null;
private BotAttempt _bestBotAttempt = null;
private BotAttempt _comparisonBotAttempt = null;
private bool _replayMode = false;
private int _startFrame = 0;
private string _lastRom = string.Empty;
@ -93,7 +94,9 @@ namespace BizHawk.Client.EmuHawk
InitializeComponent();
Text = DialogTitle;
Settings = new BasicBotSettings();
}
_comparisonBotAttempt = new BotAttempt();
}
private void BasicBot_Load(object sender, EventArgs e)
{
@ -288,12 +291,12 @@ namespace BizHawk.Client.EmuHawk
{
get
{
return (byte)mainOperator.SelectedIndex;
return (byte)MainOperator.SelectedIndex;
}
set
{
if (value < 5) mainOperator.SelectedIndex = value;
else mainOperator.SelectedIndex = 0;
if (value < 5) MainOperator.SelectedIndex = value;
else MainOperator.SelectedIndex = 0;
}
}
@ -444,12 +447,21 @@ namespace BizHawk.Client.EmuHawk
TieBreaker2Address = 0;
TieBreaker3Address = 0;
StartFromSlotBox.SelectedIndex = 0;
mainOperator.SelectedIndex = 0;
MainOperator.SelectedIndex = 0;
Tiebreak1Operator.SelectedIndex = 0;
Tiebreak2Operator.SelectedIndex = 0;
Tiebreak3Operator.SelectedIndex = 0;
MainBestRadio.Checked = true;
MainValueNumeric.Value = 0;
TieBreak1Numeric.Value = 0;
TieBreak2Numeric.Value = 0;
TieBreak3Numeric.Value = 0;
TieBreak1BestRadio.Checked = true;
TieBreak2BestRadio.Checked = true;
TieBreak3BestRadio.Checked = true;
UpdateBestAttempt();
UpdateComparisonBotAttempt();
}
private void OpenMenuItem_Click(object sender, EventArgs e)
@ -561,7 +573,10 @@ namespace BizHawk.Client.EmuHawk
private void ClearBestButton_Click(object sender, EventArgs e)
{
_bestBotAttempt = null;
Attempts = 0;
Frames = 0;
UpdateBestAttempt();
UpdateComparisonBotAttempt();
}
private void PlayBestButton_Click(object sender, EventArgs e)
@ -615,17 +630,33 @@ namespace BizHawk.Client.EmuHawk
private class BotData
{
public BotData()
{
MainCompareToBest = true;
TieBreaker1CompareToBest = true;
TieBreaker2CompareToBest = true;
TieBreaker3CompareToBest = true;
}
public BotAttempt Best { get; set; }
public Dictionary<string, double> ControlProbabilities { get; set; }
public int Maximize { get; set; }
public int TieBreaker1 { get; set; }
public int TieBreaker2 { get; set; }
public int TieBreaker3 { get; set; }
public byte ComparisonTypeMain { get; set; }
public byte ComparisonTypeTie1 { get; set; }
public byte ComparisonTypeTie2 { get; set; }
public byte ComparisonTypeTie3 { get; set; }
public int FrameLength { get; set; }
public byte ComparisonTypeMain { get; set; }
public byte ComparisonTypeTie1 { get; set; }
public byte ComparisonTypeTie2 { get; set; }
public byte ComparisonTypeTie3 { get; set; }
public bool MainCompareToBest { get; set; }
public bool TieBreaker1CompareToBest { get; set; }
public bool TieBreaker2CompareToBest { get; set; }
public bool TieBreaker3CompareToBest { get; set; }
public int MainCompareToValue { get; set; }
public int TieBreaker1CompareToValue { get; set; }
public int TieBreaker2CompareToValue { get; set; }
public int TieBreaker3CompareToValue { get; set; }
public int FrameLength { get; set; }
public string FromSlot { get; set; }
public long Attempts { get; set; }
public long Frames { get; set; }
@ -661,7 +692,6 @@ namespace BizHawk.Client.EmuHawk
_bestBotAttempt = botData.Best;
var probabilityControls = ControlProbabilityPanel.Controls
.OfType<BotControlsRow>()
.ToList();
@ -682,14 +712,42 @@ namespace BizHawk.Client.EmuHawk
Tie1ComparisonType = botData.ComparisonTypeTie1;
Tie2ComparisonType = botData.ComparisonTypeTie2;
Tie3ComparisonType = botData.ComparisonTypeTie3;
}
MainBestRadio.Checked = botData.MainCompareToBest;
TieBreak1BestRadio.Checked = botData.TieBreaker1CompareToBest;
TieBreak2BestRadio.Checked = botData.TieBreaker2CompareToBest;
TieBreak3BestRadio.Checked = botData.TieBreaker3CompareToBest;
MainValueRadio.Checked = !botData.MainCompareToBest;
TieBreak1ValueRadio.Checked = !botData.TieBreaker1CompareToBest;
TieBreak2ValueRadio.Checked = !botData.TieBreaker2CompareToBest;
TieBreak3ValueRadio.Checked = !botData.TieBreaker3CompareToBest;
MainValueNumeric.Value = botData.MainCompareToValue;
TieBreak1Numeric.Value = botData.TieBreaker1CompareToValue;
TieBreak2Numeric.Value = botData.TieBreaker2CompareToValue;
TieBreak3Numeric.Value = botData.TieBreaker3CompareToValue;
}
catch
{
MainComparisonType = 0;
Tie1ComparisonType = 0;
Tie2ComparisonType = 0;
Tie3ComparisonType = 0;
}
MainBestRadio.Checked = true;
TieBreak1BestRadio.Checked = true;
TieBreak2BestRadio.Checked = true;
TieBreak3BestRadio.Checked = true;
MainBestRadio.Checked = false;
TieBreak1BestRadio.Checked = false;
TieBreak2BestRadio.Checked = false;
TieBreak3BestRadio.Checked = false;
MainValueNumeric.Value = 0;
TieBreak1Numeric.Value = 0;
TieBreak2Numeric.Value = 0;
TieBreak3Numeric.Value = 0;
}
FrameLength = botData.FrameLength;
FromSlot = botData.FromSlot;
Attempts = botData.Attempts;
@ -703,6 +761,7 @@ namespace BizHawk.Client.EmuHawk
_dataSize = botData.DataSize > 0 ? botData.DataSize : 1;
UpdateBestAttempt();
UpdateComparisonBotAttempt();
if (_bestBotAttempt != null)
{
@ -716,20 +775,28 @@ namespace BizHawk.Client.EmuHawk
return true;
}
private void SaveBotFile(string path)
{
var data = new BotData
{
Best = _bestBotAttempt,
ControlProbabilities = ControlProbabilities,
Maximize = MaximizeAddress,
TieBreaker1 = TieBreaker1Address,
TieBreaker2 = TieBreaker2Address,
TieBreaker3 = TieBreaker3Address,
ComparisonTypeMain = MainComparisonType,
ComparisonTypeTie1 = Tie1ComparisonType,
ComparisonTypeTie2 = Tie2ComparisonType,
ComparisonTypeTie3 = Tie3ComparisonType,
private void SaveBotFile(string path)
{
var data = new BotData
{
Best = _bestBotAttempt,
ControlProbabilities = ControlProbabilities,
Maximize = MaximizeAddress,
TieBreaker1 = TieBreaker1Address,
TieBreaker2 = TieBreaker2Address,
TieBreaker3 = TieBreaker3Address,
ComparisonTypeMain = MainComparisonType,
ComparisonTypeTie1 = Tie1ComparisonType,
ComparisonTypeTie2 = Tie2ComparisonType,
ComparisonTypeTie3 = Tie3ComparisonType,
MainCompareToBest = MainBestRadio.Checked,
TieBreaker1CompareToBest = TieBreak1BestRadio.Checked,
TieBreaker2CompareToBest = TieBreak2BestRadio.Checked,
TieBreaker3CompareToBest = TieBreak3BestRadio.Checked,
MainCompareToValue = (int)MainValueNumeric.Value,
TieBreaker1CompareToValue = (int)TieBreak1Numeric.Value,
TieBreaker2CompareToValue = (int)TieBreak2Numeric.Value,
TieBreaker3CompareToValue = (int)TieBreak3Numeric.Value,
FromSlot = FromSlot,
FrameLength = FrameLength,
Attempts = Attempts,
@ -857,7 +924,7 @@ namespace BizHawk.Client.EmuHawk
_currentBotAttempt.TieBreak3 = TieBreaker3Value;
PlayBestButton.Enabled = true;
if (_bestBotAttempt == null || IsBetter(_bestBotAttempt, _currentBotAttempt))
if (IsBetter(_comparisonBotAttempt, _currentBotAttempt))
{
_bestBotAttempt = _currentBotAttempt;
UpdateBestAttempt();
@ -880,25 +947,25 @@ namespace BizHawk.Client.EmuHawk
MessageLabel.Text = "Replay stopped";
}
private bool IsBetter(BotAttempt best, BotAttempt current)
private bool IsBetter(BotAttempt comparison, BotAttempt current)
{
if (!TestValue(MainComparisonType, current.Maximize, best.Maximize))
if (!TestValue(MainComparisonType, current.Maximize, comparison.Maximize))
{
return false;
}
else if (current.Maximize == best.Maximize)
else if (current.Maximize == comparison.Maximize)
{
if (!TestValue(Tie1ComparisonType, current.TieBreak1, best.TieBreak1))
if (!TestValue(Tie1ComparisonType, current.TieBreak1, comparison.TieBreak1))
{
return false;
}
else if (current.TieBreak1 == best.TieBreak1)
else if (current.TieBreak1 == comparison.TieBreak1)
{
if (!TestValue(Tie2ComparisonType, current.TieBreak2, best.TieBreak2))
if (!TestValue(Tie2ComparisonType, current.TieBreak2, comparison.TieBreak2))
{
return false;
}
else if (current.TieBreak2 == best.TieBreak2)
else if (current.TieBreak2 == comparison.TieBreak2)
{
if (!TestValue(Tie3ComparisonType, current.TieBreak3, current.TieBreak3))
{
@ -933,8 +1000,6 @@ namespace BizHawk.Client.EmuHawk
{
if (_bestBotAttempt != null)
{
ClearBestButton.Enabled = true;
BestAttemptNumberLabel.Text = _bestBotAttempt.Attempt.ToString();
BestMaximizeBox.Text = _bestBotAttempt.Maximize.ToString();
@ -1101,5 +1166,161 @@ namespace BizHawk.Client.EmuHawk
&& !string.IsNullOrWhiteSpace(MaximizeAddressBox.Text)
&& ControlProbabilities.Any(kvp => kvp.Value > 0);
}
/// <summary>
/// Updates comparison bot attempt with current best bot attempt values for values where the "best" radio button is selected
/// </summary>
private void UpdateComparisonBotAttempt()
{
if(_bestBotAttempt == null)
{
if (MainBestRadio.Checked)
{
_comparisonBotAttempt.Maximize = 0;
}
if (TieBreak1BestRadio.Checked)
{
_comparisonBotAttempt.TieBreak1 = 0;
}
if (TieBreak2BestRadio.Checked)
{
_comparisonBotAttempt.TieBreak2= 0;
}
if (TieBreak3BestRadio.Checked)
{
_comparisonBotAttempt.TieBreak3 = 0;
}
}
else
{
if (MainBestRadio.Checked && _bestBotAttempt.Maximize != _comparisonBotAttempt.Maximize)
{
_comparisonBotAttempt.Maximize = _bestBotAttempt.Maximize;
}
if (TieBreak1BestRadio.Checked && _bestBotAttempt.TieBreak1 != _comparisonBotAttempt.TieBreak1)
{
_comparisonBotAttempt.TieBreak1 = _bestBotAttempt.TieBreak1;
}
if (TieBreak2BestRadio.Checked && _bestBotAttempt.TieBreak2 != _comparisonBotAttempt.TieBreak2)
{
_comparisonBotAttempt.TieBreak2 = _bestBotAttempt.TieBreak2;
}
if (TieBreak3BestRadio.Checked && _bestBotAttempt.TieBreak3 != _comparisonBotAttempt.TieBreak3)
{
_comparisonBotAttempt.TieBreak3 = _bestBotAttempt.TieBreak3;
}
}
}
private void MainBestRadio_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
this.MainValueNumeric.Enabled = false;
_comparisonBotAttempt.Maximize = _bestBotAttempt == null ? 0 : _bestBotAttempt.Maximize;
}
}
private void Tiebreak1BestRadio_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
this.TieBreak1Numeric.Enabled = false;
_comparisonBotAttempt.TieBreak1 = _bestBotAttempt == null ? 0 : _bestBotAttempt.TieBreak1;
}
}
private void Tiebreak2BestRadio_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
this.TieBreak2Numeric.Enabled = false;
_comparisonBotAttempt.TieBreak2 = _bestBotAttempt == null ? 0 : _bestBotAttempt.TieBreak2;
}
}
private void Tiebreak3BestRadio_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
this.TieBreak3Numeric.Enabled = false;
_comparisonBotAttempt.TieBreak3 = _bestBotAttempt == null ? 0 : _bestBotAttempt.TieBreak3;
}
}
private void MainValueRadio_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
this.MainValueNumeric.Enabled = true;
_comparisonBotAttempt.Maximize = (int)this.MainValueNumeric.Value;
}
}
private void TieBreak1ValueRadio_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
this.TieBreak1Numeric.Enabled = true;
_comparisonBotAttempt.TieBreak1 = (int)this.TieBreak1Numeric.Value;
}
}
private void TieBreak2ValueRadio_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
this.TieBreak2Numeric.Enabled = true;
_comparisonBotAttempt.TieBreak2 = (int)this.TieBreak2Numeric.Value;
}
}
private void TieBreak3ValueRadio_CheckedChanged(object sender, EventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
if (radioButton.Checked)
{
this.TieBreak3Numeric.Enabled = true;
_comparisonBotAttempt.TieBreak3 = (int)this.TieBreak3Numeric.Value;
}
}
private void MainValueNumeric_ValueChanged(object sender, EventArgs e)
{
NumericUpDown numericUpDown = (NumericUpDown)sender;
this._comparisonBotAttempt.Maximize = (int)numericUpDown.Value;
}
private void TieBreak1Numeric_ValueChanged(object sender, EventArgs e)
{
NumericUpDown numericUpDown = (NumericUpDown)sender;
this._comparisonBotAttempt.TieBreak1 = (int)numericUpDown.Value;
}
private void TieBreak2Numeric_ValueChanged(object sender, EventArgs e)
{
NumericUpDown numericUpDown = (NumericUpDown)sender;
this._comparisonBotAttempt.TieBreak2 = (int)numericUpDown.Value;
}
private void TieBreak3Numeric_ValueChanged(object sender, EventArgs e)
{
NumericUpDown numericUpDown = (NumericUpDown)sender;
this._comparisonBotAttempt.TieBreak3 = (int)numericUpDown.Value;
}
}
}

View File

@ -65,7 +65,7 @@
this.ProbabilitySlider.Location = new System.Drawing.Point(147, -2);
this.ProbabilitySlider.Maximum = 100;
this.ProbabilitySlider.Name = "ProbabilitySlider";
this.ProbabilitySlider.Size = new System.Drawing.Size(111, 45);
this.ProbabilitySlider.Size = new System.Drawing.Size(203, 45);
this.ProbabilitySlider.TabIndex = 2;
this.ProbabilitySlider.TickFrequency = 25;
this.ProbabilitySlider.ValueChanged += new System.EventHandler(this.ProbabilitySlider_ValueChanged);
@ -78,7 +78,7 @@
this.Controls.Add(this.ProbabilityUpDown);
this.Controls.Add(this.ButtonNameLabel);
this.Name = "BotControlsRow";
this.Size = new System.Drawing.Size(258, 29);
this.Size = new System.Drawing.Size(350, 29);
this.Load += new System.EventHandler(this.BotControlsRow_Load);
((System.ComponentModel.ISupportInitialize)(this.ProbabilityUpDown)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.ProbabilitySlider)).EndInit();

View File

@ -7,10 +7,6 @@ using System.Linq;
using System.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions;
using BizHawk.Emulation.Cores.Nintendo.SNES;
using BizHawk.Emulation.Cores.Sega.Genesis;
using BizHawk.Client.Common;
using BizHawk.Client.EmuHawk.ToolExtensions;
using BizHawk.Client.EmuHawk.WinFormExtensions;
@ -172,7 +168,7 @@ namespace BizHawk.Client.EmuHawk
{
GameGenieToolbarSeparator.Visible =
LoadGameGenieToolbarItem.Visible =
GlobalWin.Tools.GameGenieAvailable;
GlobalWin.Tools.IsAvailable<GameShark>();
}
private void AddCheat()
@ -443,7 +439,7 @@ namespace BizHawk.Client.EmuHawk
GameGenieSeparator.Visible =
OpenGameGenieEncoderDecoderMenuItem.Visible =
GlobalWin.Tools.GameGenieAvailable;
GlobalWin.Tools.IsAvailable<GameShark>();
}
private void RemoveCheatMenuItem_Click(object sender, EventArgs e)

View File

@ -7,6 +7,18 @@ namespace BizHawk.Client.EmuHawk
{
public partial class GenericDebugger : IControlMainform
{
public bool WantsToControlSavestates { get { return false; } }
public void SaveState() { }
public void LoadState() { }
public void SaveStateAs() { }
public void LoadStateAs() { }
public void SaveQuickSave(int slot) { }
public void LoadQuickSave(int slot) { }
public void SelectSlot(int slot) { }
public void PreviousSlot() { }
public void NextSlot() { }
public bool WantsToControlReadOnly { get { return false; } }
public void ToggleReadOnly() { }

View File

@ -5,11 +5,11 @@ using System.Text.RegularExpressions;
using System.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions;
using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
[ToolAttributes(false, null)]
public partial class GBGameGenie : Form, IToolFormAutoConfig
{
// TODO: fix the use of Global.Game.System and Emulator.SystemId

View File

@ -42,12 +42,12 @@
//
this.mnuGameShark.Location = new System.Drawing.Point(0, 0);
this.mnuGameShark.Name = "mnuGameShark";
this.mnuGameShark.Size = new System.Drawing.Size(284, 24);
this.mnuGameShark.Size = new System.Drawing.Size(281, 24);
this.mnuGameShark.TabIndex = 0;
//
// btnClear
//
this.btnClear.Location = new System.Drawing.Point(141, 132);
this.btnClear.Location = new System.Drawing.Point(156, 90);
this.btnClear.Name = "btnClear";
this.btnClear.Size = new System.Drawing.Size(75, 23);
this.btnClear.TabIndex = 4;
@ -58,7 +58,7 @@
// lblCheat
//
this.lblCheat.AutoSize = true;
this.lblCheat.Location = new System.Drawing.Point(147, 91);
this.lblCheat.Location = new System.Drawing.Point(162, 49);
this.lblCheat.Name = "lblCheat";
this.lblCheat.Size = new System.Drawing.Size(63, 13);
this.lblCheat.TabIndex = 11;
@ -66,14 +66,14 @@
//
// txtCheat
//
this.txtCheat.Location = new System.Drawing.Point(128, 106);
this.txtCheat.Location = new System.Drawing.Point(143, 64);
this.txtCheat.Name = "txtCheat";
this.txtCheat.Size = new System.Drawing.Size(100, 20);
this.txtCheat.TabIndex = 2;
//
// btnGo
//
this.btnGo.Location = new System.Drawing.Point(35, 131);
this.btnGo.Location = new System.Drawing.Point(50, 89);
this.btnGo.Name = "btnGo";
this.btnGo.Size = new System.Drawing.Size(75, 24);
this.btnGo.TabIndex = 3;
@ -84,7 +84,7 @@
// lblDescription
//
this.lblDescription.AutoSize = true;
this.lblDescription.Location = new System.Drawing.Point(42, 90);
this.lblDescription.Location = new System.Drawing.Point(57, 48);
this.lblDescription.Name = "lblDescription";
this.lblDescription.Size = new System.Drawing.Size(60, 13);
this.lblDescription.TabIndex = 17;
@ -92,7 +92,7 @@
//
// txtDescription
//
this.txtDescription.Location = new System.Drawing.Point(22, 106);
this.txtDescription.Location = new System.Drawing.Point(37, 64);
this.txtDescription.Name = "txtDescription";
this.txtDescription.Size = new System.Drawing.Size(100, 20);
this.txtDescription.TabIndex = 1;
@ -101,7 +101,7 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.ClientSize = new System.Drawing.Size(281, 144);
this.Controls.Add(this.txtDescription);
this.Controls.Add(this.lblDescription);
this.Controls.Add(this.btnClear);
@ -113,6 +113,7 @@
this.MainMenuStrip = this.mnuGameShark;
this.MaximizeBox = false;
this.Name = "GameShark";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "GameShark Converter";
this.Load += new System.EventHandler(this.GameShark_Load);
this.ResumeLayout(false);

File diff suppressed because it is too large Load Diff

View File

@ -12,6 +12,7 @@ using BizHawk.Emulation.Cores.Consoles.Sega.gpgx;
namespace BizHawk.Client.EmuHawk
{
[ToolAttributes(false, null)]
public partial class GenGameGenie : Form, IToolFormAutoConfig
{
#pragma warning disable 675

View File

@ -87,8 +87,8 @@
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.viewN64MatrixToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.MemoryViewerBox = new System.Windows.Forms.GroupBox();
this.AddressLabel = new System.Windows.Forms.Label();
this.HexScrollBar = new System.Windows.Forms.VScrollBar();
this.AddressLabel = new System.Windows.Forms.Label();
this.AddressesLabel = new System.Windows.Forms.Label();
this.Header = new System.Windows.Forms.Label();
this.HexMenuStrip.SuspendLayout();
@ -133,7 +133,7 @@
this.SaveMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.SaveAs;
this.SaveMenuItem.Name = "SaveMenuItem";
this.SaveMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
this.SaveMenuItem.Size = new System.Drawing.Size(225, 22);
this.SaveMenuItem.Size = new System.Drawing.Size(236, 22);
this.SaveMenuItem.Text = "Save";
this.SaveMenuItem.Click += new System.EventHandler(this.SaveMenuItem_Click);
//
@ -142,33 +142,33 @@
this.SaveAsBinaryMenuItem.Name = "SaveAsBinaryMenuItem";
this.SaveAsBinaryMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.S)));
this.SaveAsBinaryMenuItem.Size = new System.Drawing.Size(225, 22);
this.SaveAsBinaryMenuItem.Size = new System.Drawing.Size(236, 22);
this.SaveAsBinaryMenuItem.Text = "Save as binary...";
this.SaveAsBinaryMenuItem.Click += new System.EventHandler(this.SaveAsBinaryMenuItem_Click);
//
// SaveAsTextMenuItem
//
this.SaveAsTextMenuItem.Name = "SaveAsTextMenuItem";
this.SaveAsTextMenuItem.Size = new System.Drawing.Size(225, 22);
this.SaveAsTextMenuItem.Size = new System.Drawing.Size(236, 22);
this.SaveAsTextMenuItem.Text = "Save as text...";
this.SaveAsTextMenuItem.Click += new System.EventHandler(this.SaveAsTextMenuItem_Click);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(222, 6);
this.toolStripSeparator4.Size = new System.Drawing.Size(233, 6);
//
// LoadTableFileMenuItem
//
this.LoadTableFileMenuItem.Name = "LoadTableFileMenuItem";
this.LoadTableFileMenuItem.Size = new System.Drawing.Size(225, 22);
this.LoadTableFileMenuItem.Size = new System.Drawing.Size(236, 22);
this.LoadTableFileMenuItem.Text = "&Load .tbl file";
this.LoadTableFileMenuItem.Click += new System.EventHandler(this.LoadTableFileMenuItem_Click);
//
// CloseTableFileMenuItem
//
this.CloseTableFileMenuItem.Name = "CloseTableFileMenuItem";
this.CloseTableFileMenuItem.Size = new System.Drawing.Size(225, 22);
this.CloseTableFileMenuItem.Size = new System.Drawing.Size(236, 22);
this.CloseTableFileMenuItem.Text = "Close .tbl file";
this.CloseTableFileMenuItem.Click += new System.EventHandler(this.CloseTableFileMenuItem_Click);
//
@ -177,26 +177,26 @@
this.RecentTablesSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.noneToolStripMenuItem});
this.RecentTablesSubMenu.Name = "RecentTablesSubMenu";
this.RecentTablesSubMenu.Size = new System.Drawing.Size(225, 22);
this.RecentTablesSubMenu.Size = new System.Drawing.Size(236, 22);
this.RecentTablesSubMenu.Text = "Recent";
this.RecentTablesSubMenu.DropDownOpened += new System.EventHandler(this.RecentTablesSubMenu_DropDownOpened);
//
// noneToolStripMenuItem
//
this.noneToolStripMenuItem.Name = "noneToolStripMenuItem";
this.noneToolStripMenuItem.Size = new System.Drawing.Size(99, 22);
this.noneToolStripMenuItem.Size = new System.Drawing.Size(110, 22);
this.noneToolStripMenuItem.Text = "None";
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(222, 6);
this.toolStripSeparator1.Size = new System.Drawing.Size(233, 6);
//
// ExitMenuItem
//
this.ExitMenuItem.Name = "ExitMenuItem";
this.ExitMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4)));
this.ExitMenuItem.Size = new System.Drawing.Size(225, 22);
this.ExitMenuItem.Size = new System.Drawing.Size(236, 22);
this.ExitMenuItem.Text = "E&xit";
this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click);
//
@ -220,7 +220,7 @@
this.CopyMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Duplicate;
this.CopyMenuItem.Name = "CopyMenuItem";
this.CopyMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
this.CopyMenuItem.Size = new System.Drawing.Size(144, 22);
this.CopyMenuItem.Size = new System.Drawing.Size(155, 22);
this.CopyMenuItem.Text = "&Copy";
this.CopyMenuItem.Click += new System.EventHandler(this.CopyMenuItem_Click);
//
@ -228,7 +228,7 @@
//
this.ExportMenuItem.Name = "ExportMenuItem";
this.ExportMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.E)));
this.ExportMenuItem.Size = new System.Drawing.Size(144, 22);
this.ExportMenuItem.Size = new System.Drawing.Size(155, 22);
this.ExportMenuItem.Text = "&Export";
this.ExportMenuItem.Click += new System.EventHandler(this.ExportMenuItem_Click);
//
@ -237,20 +237,20 @@
this.PasteMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Paste;
this.PasteMenuItem.Name = "PasteMenuItem";
this.PasteMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V)));
this.PasteMenuItem.Size = new System.Drawing.Size(144, 22);
this.PasteMenuItem.Size = new System.Drawing.Size(155, 22);
this.PasteMenuItem.Text = "&Paste";
this.PasteMenuItem.Click += new System.EventHandler(this.PasteMenuItem_Click);
//
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
this.toolStripSeparator6.Size = new System.Drawing.Size(141, 6);
this.toolStripSeparator6.Size = new System.Drawing.Size(152, 6);
//
// FindMenuItem
//
this.FindMenuItem.Name = "FindMenuItem";
this.FindMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F)));
this.FindMenuItem.Size = new System.Drawing.Size(144, 22);
this.FindMenuItem.Size = new System.Drawing.Size(155, 22);
this.FindMenuItem.Text = "&Find...";
this.FindMenuItem.Click += new System.EventHandler(this.FindMenuItem_Click);
//
@ -258,7 +258,7 @@
//
this.FindNextMenuItem.Name = "FindNextMenuItem";
this.FindNextMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F3;
this.FindNextMenuItem.Size = new System.Drawing.Size(144, 22);
this.FindNextMenuItem.Size = new System.Drawing.Size(155, 22);
this.FindNextMenuItem.Text = "Find Next";
this.FindNextMenuItem.Click += new System.EventHandler(this.FindNextMenuItem_Click);
//
@ -266,7 +266,7 @@
//
this.FindPrevMenuItem.Name = "FindPrevMenuItem";
this.FindPrevMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F2;
this.FindPrevMenuItem.Size = new System.Drawing.Size(144, 22);
this.FindPrevMenuItem.Size = new System.Drawing.Size(155, 22);
this.FindPrevMenuItem.Text = "Find Prev";
this.FindPrevMenuItem.Click += new System.EventHandler(this.FindPrevMenuItem_Click);
//
@ -292,7 +292,7 @@
this.MemoryDomainsMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripSeparator3});
this.MemoryDomainsMenuItem.Name = "MemoryDomainsMenuItem";
this.MemoryDomainsMenuItem.Size = new System.Drawing.Size(206, 22);
this.MemoryDomainsMenuItem.Size = new System.Drawing.Size(217, 22);
this.MemoryDomainsMenuItem.Text = "&Memory Domains";
this.MemoryDomainsMenuItem.DropDownOpened += new System.EventHandler(this.MemoryDomainsMenuItem_DropDownOpened);
//
@ -308,47 +308,47 @@
this.DataSizeWordMenuItem,
this.DataSizeDWordMenuItem});
this.DataSizeSubMenu.Name = "DataSizeSubMenu";
this.DataSizeSubMenu.Size = new System.Drawing.Size(206, 22);
this.DataSizeSubMenu.Size = new System.Drawing.Size(217, 22);
this.DataSizeSubMenu.Text = "Data Size";
//
// DataSizeByteMenuItem
//
this.DataSizeByteMenuItem.Name = "DataSizeByteMenuItem";
this.DataSizeByteMenuItem.Size = new System.Drawing.Size(105, 22);
this.DataSizeByteMenuItem.Size = new System.Drawing.Size(116, 22);
this.DataSizeByteMenuItem.Text = "1 Byte";
this.DataSizeByteMenuItem.Click += new System.EventHandler(this.DataSizeByteMenuItem_Click);
//
// DataSizeWordMenuItem
//
this.DataSizeWordMenuItem.Name = "DataSizeWordMenuItem";
this.DataSizeWordMenuItem.Size = new System.Drawing.Size(105, 22);
this.DataSizeWordMenuItem.Size = new System.Drawing.Size(116, 22);
this.DataSizeWordMenuItem.Text = "2 Byte";
this.DataSizeWordMenuItem.Click += new System.EventHandler(this.DataSizeWordMenuItem_Click);
//
// DataSizeDWordMenuItem
//
this.DataSizeDWordMenuItem.Name = "DataSizeDWordMenuItem";
this.DataSizeDWordMenuItem.Size = new System.Drawing.Size(105, 22);
this.DataSizeDWordMenuItem.Size = new System.Drawing.Size(116, 22);
this.DataSizeDWordMenuItem.Text = "4 Byte";
this.DataSizeDWordMenuItem.Click += new System.EventHandler(this.DataSizeDWordMenuItem_Click);
//
// BigEndianMenuItem
//
this.BigEndianMenuItem.Name = "BigEndianMenuItem";
this.BigEndianMenuItem.Size = new System.Drawing.Size(206, 22);
this.BigEndianMenuItem.Size = new System.Drawing.Size(217, 22);
this.BigEndianMenuItem.Text = "Big Endian";
this.BigEndianMenuItem.Click += new System.EventHandler(this.BigEndianMenuItem_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(203, 6);
this.toolStripSeparator2.Size = new System.Drawing.Size(214, 6);
//
// GoToAddressMenuItem
//
this.GoToAddressMenuItem.Name = "GoToAddressMenuItem";
this.GoToAddressMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.G)));
this.GoToAddressMenuItem.Size = new System.Drawing.Size(206, 22);
this.GoToAddressMenuItem.Size = new System.Drawing.Size(217, 22);
this.GoToAddressMenuItem.Text = "&Go to Address...";
this.GoToAddressMenuItem.Click += new System.EventHandler(this.GoToAddressMenuItem_Click);
//
@ -357,7 +357,7 @@
this.AddToRamWatchMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.FindHS;
this.AddToRamWatchMenuItem.Name = "AddToRamWatchMenuItem";
this.AddToRamWatchMenuItem.ShortcutKeyDisplayString = "Ctrl+W";
this.AddToRamWatchMenuItem.Size = new System.Drawing.Size(206, 22);
this.AddToRamWatchMenuItem.Size = new System.Drawing.Size(217, 22);
this.AddToRamWatchMenuItem.Text = "Add to Ram Watch";
this.AddToRamWatchMenuItem.Click += new System.EventHandler(this.AddToRamWatchMenuItem_Click);
//
@ -366,7 +366,7 @@
this.FreezeAddressMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Freeze;
this.FreezeAddressMenuItem.Name = "FreezeAddressMenuItem";
this.FreezeAddressMenuItem.ShortcutKeyDisplayString = "Space";
this.FreezeAddressMenuItem.Size = new System.Drawing.Size(206, 22);
this.FreezeAddressMenuItem.Size = new System.Drawing.Size(217, 22);
this.FreezeAddressMenuItem.Text = "&Freeze Address";
this.FreezeAddressMenuItem.Click += new System.EventHandler(this.FreezeAddressMenuItem_Click);
//
@ -375,7 +375,7 @@
this.UnfreezeAllMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Unfreeze;
this.UnfreezeAllMenuItem.Name = "UnfreezeAllMenuItem";
this.UnfreezeAllMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Shift | System.Windows.Forms.Keys.Delete)));
this.UnfreezeAllMenuItem.Size = new System.Drawing.Size(206, 22);
this.UnfreezeAllMenuItem.Size = new System.Drawing.Size(217, 22);
this.UnfreezeAllMenuItem.Text = "Unfreeze All";
this.UnfreezeAllMenuItem.Click += new System.EventHandler(this.UnfreezeAllMenuItem_Click);
//
@ -384,7 +384,7 @@
this.PokeAddressMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.poke;
this.PokeAddressMenuItem.Name = "PokeAddressMenuItem";
this.PokeAddressMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.P)));
this.PokeAddressMenuItem.Size = new System.Drawing.Size(206, 22);
this.PokeAddressMenuItem.Size = new System.Drawing.Size(217, 22);
this.PokeAddressMenuItem.Text = "&Poke Address";
this.PokeAddressMenuItem.Click += new System.EventHandler(this.PokeAddressMenuItem_Click);
//
@ -403,25 +403,25 @@
this.toolStripSeparator8,
this.ResetColorsToDefaultMenuItem});
this.CustomColorsSubMenu.Name = "CustomColorsSubMenu";
this.CustomColorsSubMenu.Size = new System.Drawing.Size(143, 22);
this.CustomColorsSubMenu.Size = new System.Drawing.Size(154, 22);
this.CustomColorsSubMenu.Text = "Custom Colors";
//
// SetColorsMenuItem
//
this.SetColorsMenuItem.Name = "SetColorsMenuItem";
this.SetColorsMenuItem.Size = new System.Drawing.Size(153, 22);
this.SetColorsMenuItem.Size = new System.Drawing.Size(164, 22);
this.SetColorsMenuItem.Text = "Set Colors";
this.SetColorsMenuItem.Click += new System.EventHandler(this.SetColorsMenuItem_Click);
//
// toolStripSeparator8
//
this.toolStripSeparator8.Name = "toolStripSeparator8";
this.toolStripSeparator8.Size = new System.Drawing.Size(150, 6);
this.toolStripSeparator8.Size = new System.Drawing.Size(161, 6);
//
// ResetColorsToDefaultMenuItem
//
this.ResetColorsToDefaultMenuItem.Name = "ResetColorsToDefaultMenuItem";
this.ResetColorsToDefaultMenuItem.Size = new System.Drawing.Size(153, 22);
this.ResetColorsToDefaultMenuItem.Size = new System.Drawing.Size(164, 22);
this.ResetColorsToDefaultMenuItem.Text = "Reset to Default";
this.ResetColorsToDefaultMenuItem.Click += new System.EventHandler(this.ResetColorsToDefaultMenuItem_Click);
//
@ -570,19 +570,31 @@
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.MemoryViewerBox.ContextMenuStrip = this.ViewerContextMenuStrip;
this.MemoryViewerBox.Controls.Add(this.AddressLabel);
this.MemoryViewerBox.Controls.Add(this.HexScrollBar);
this.MemoryViewerBox.Controls.Add(this.AddressLabel);
this.MemoryViewerBox.Controls.Add(this.AddressesLabel);
this.MemoryViewerBox.Controls.Add(this.Header);
this.MemoryViewerBox.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.MemoryViewerBox.Location = new System.Drawing.Point(12, 27);
this.MemoryViewerBox.MaximumSize = new System.Drawing.Size(600, 1024);
this.MemoryViewerBox.MinimumSize = new System.Drawing.Size(260, 180);
this.MemoryViewerBox.Name = "MemoryViewerBox";
this.MemoryViewerBox.Size = new System.Drawing.Size(558, 262);
this.MemoryViewerBox.Size = new System.Drawing.Size(560, 262);
this.MemoryViewerBox.TabIndex = 2;
this.MemoryViewerBox.TabStop = false;
this.MemoryViewerBox.Paint += new System.Windows.Forms.PaintEventHandler(this.MemoryViewerBox_Paint);
//
// HexScrollBar
//
this.HexScrollBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Right)));
this.HexScrollBar.LargeChange = 16;
this.HexScrollBar.Location = new System.Drawing.Point(544, 16);
this.HexScrollBar.Name = "HexScrollBar";
this.HexScrollBar.Size = new System.Drawing.Size(16, 246);
this.HexScrollBar.TabIndex = 1;
this.HexScrollBar.ValueChanged += new System.EventHandler(this.HexScrollBar_ValueChanged);
//
// AddressLabel
//
this.AddressLabel.AutoSize = true;
@ -593,22 +605,11 @@
this.AddressLabel.TabIndex = 2;
this.AddressLabel.Text = " ";
//
// HexScrollBar
//
this.HexScrollBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Right)));
this.HexScrollBar.LargeChange = 16;
this.HexScrollBar.Location = new System.Drawing.Point(539, 8);
this.HexScrollBar.Name = "HexScrollBar";
this.HexScrollBar.Size = new System.Drawing.Size(16, 251);
this.HexScrollBar.TabIndex = 1;
this.HexScrollBar.ValueChanged += new System.EventHandler(this.HexScrollBar_ValueChanged);
//
// AddressesLabel
//
this.AddressesLabel.AutoSize = true;
this.AddressesLabel.ContextMenuStrip = this.ViewerContextMenuStrip;
this.AddressesLabel.Location = new System.Drawing.Point(65, 30);
this.AddressesLabel.Location = new System.Drawing.Point(79, 30);
this.AddressesLabel.Name = "AddressesLabel";
this.AddressesLabel.Size = new System.Drawing.Size(31, 13);
this.AddressesLabel.TabIndex = 0;

View File

@ -480,7 +480,7 @@ namespace BizHawk.Client.EmuHawk
addrStr.Append(" ");
}
addrStr.AppendLine(_addr.ToHexString(_numDigits));
addrStr.AppendLine(_addr.ToHexString(_numDigits) + " |");
}
return addrStr.ToString();
@ -516,7 +516,7 @@ namespace BizHawk.Client.EmuHawk
}
}
rowStr.Append(" | ");
rowStr.Append("| ");
for (var k = 0; k < 16; k++)
{
if (_addr + k < _domain.Size)
@ -669,13 +669,15 @@ namespace BizHawk.Client.EmuHawk
private void UpdateFormText()
{
Text = "Hex Editor";
if (_addressHighlighted >= 0)
{
Text = "Hex Editor - Editing Address 0x" + string.Format(_numDigitsStr, _addressHighlighted);
}
else
{
Text = "Hex Editor";
Text += " - Editing Address 0x" + string.Format(_numDigitsStr, _addressHighlighted);
if (_secondaryHighlightedAddresses.Any())
{
Text += string.Format(" (Selected 0x{0:X})", _secondaryHighlightedAddresses.Count() +
(_secondaryHighlightedAddresses.Contains(_addressHighlighted) ? 0 : 1));
}
}
}
@ -690,13 +692,13 @@ namespace BizHawk.Client.EmuHawk
switch (DataSize)
{
case 1:
Header.Text = " 0 1 2 3 4 5 6 7 8 9 A B C D E F";
Header.Text = " 0 1 2 3 4 5 6 7 8 9 A B C D E F";
break;
case 2:
Header.Text = " 0 2 4 6 8 A C E";
Header.Text = " 0 2 4 6 8 A C E";
break;
case 4:
Header.Text = " 0 4 8 C";
Header.Text = " 0 4 8 C";
break;
}
@ -940,10 +942,11 @@ namespace BizHawk.Client.EmuHawk
var column = x / (fontWidth * colWidth);
var start = GetTextOffset() - 50;
var innerOffset = AddressesLabel.Location.X - AddressLabel.Location.X + AddressesLabel.Margin.Left;
var start = GetTextOffset() - innerOffset;
if (x > start)
{
column = (x - start) / (fontWidth / DataSize);
column = (x - start) / (fontWidth * DataSize);
}
if (i >= 0 && i <= _maxRow && column >= 0 && column < (16 / DataSize))
@ -977,6 +980,17 @@ namespace BizHawk.Client.EmuHawk
_secondaryHighlightedAddresses.Add(x);
}
}
if (!IsVisible(_addressOver))
{
var value = (_addressOver / 16) + 1 - ((_addressOver / 16) < HexScrollBar.Value ? 1 : _rowsVisible);
if (value < 0)
{
value = 0;
}
HexScrollBar.Value = (int)value; // This will fail on a sufficiently large domain
}
}
}
@ -1009,7 +1023,7 @@ namespace BizHawk.Client.EmuHawk
{
int start = (16 / DataSize) * fontWidth * (DataSize * 2 + 1);
start += AddressesLabel.Location.X + fontWidth / 2;
start += fontWidth * 4;
start += fontWidth * 2;
return start;
}
@ -1043,7 +1057,7 @@ namespace BizHawk.Client.EmuHawk
private void AddToSecondaryHighlights(long address)
{
if (address >= 0 && address < _domain.Size)
if (address >= 0 && address < _domain.Size && !_secondaryHighlightedAddresses.Contains(address))
{
_secondaryHighlightedAddresses.Add(address);
}
@ -2166,8 +2180,8 @@ namespace BizHawk.Client.EmuHawk
}
else
{
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(0x77FFD4D4)), rect);
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(0x77FFD4D4)), textrect);
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(0x44, Global.Config.HexHighlightColor)), rect);
e.Graphics.FillRectangle(new SolidBrush(Color.FromArgb(0x44, Global.Config.HexHighlightColor)), textrect);
}
}
}
@ -2190,6 +2204,7 @@ namespace BizHawk.Client.EmuHawk
if (_mouseIsDown)
{
DoShiftClick();
UpdateFormText();
MemoryViewerBox.Refresh();
}
}

View File

@ -0,0 +1,102 @@
namespace BizHawk.Client.EmuHawk
{
partial class NewHexEditor
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.HexMenu = new System.Windows.Forms.MenuStrip();
this.FileSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.ExitMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.HexViewControl = new BizHawk.Client.EmuHawk.HexView();
this.HexMenu.SuspendLayout();
this.SuspendLayout();
//
// HexMenu
//
this.HexMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.FileSubMenu});
this.HexMenu.Location = new System.Drawing.Point(0, 0);
this.HexMenu.Name = "HexMenu";
this.HexMenu.Size = new System.Drawing.Size(448, 24);
this.HexMenu.TabIndex = 0;
this.HexMenu.Text = "menuStrip1";
//
// FileSubMenu
//
this.FileSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.ExitMenuItem});
this.FileSubMenu.Name = "FileSubMenu";
this.FileSubMenu.Size = new System.Drawing.Size(37, 20);
this.FileSubMenu.Text = "&File";
this.FileSubMenu.DropDownOpened += new System.EventHandler(this.FileSubMenu_DropDownOpened);
//
// ExitMenuItem
//
this.ExitMenuItem.Name = "ExitMenuItem";
this.ExitMenuItem.ShortcutKeyDisplayString = "Alt+F4";
this.ExitMenuItem.Size = new System.Drawing.Size(134, 22);
this.ExitMenuItem.Text = "E&xit";
this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click);
//
// HexViewControl
//
this.HexViewControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.HexViewControl.ArrayLength = 0;
this.HexViewControl.Location = new System.Drawing.Point(12, 27);
this.HexViewControl.Name = "HexViewControl";
this.HexViewControl.Size = new System.Drawing.Size(424, 231);
this.HexViewControl.TabIndex = 1;
this.HexViewControl.Text = "hexView1";
//
// NewHexEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(448, 270);
this.Controls.Add(this.HexViewControl);
this.Controls.Add(this.HexMenu);
this.MainMenuStrip = this.HexMenu;
this.Name = "NewHexEditor";
this.Text = "NewHexEditor";
this.Load += new System.EventHandler(this.NewHexEditor_Load);
this.HexMenu.ResumeLayout(false);
this.HexMenu.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.MenuStrip HexMenu;
private System.Windows.Forms.ToolStripMenuItem FileSubMenu;
private System.Windows.Forms.ToolStripMenuItem ExitMenuItem;
private HexView HexViewControl;
}
}

View File

@ -0,0 +1,103 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
{
public partial class NewHexEditor : Form, IToolFormAutoConfig
{
#region Initialize and Dependencies
[RequiredService]
private IMemoryDomains MemoryDomains { get; set; }
[RequiredService]
private IEmulator Emulator { get; set; }
public NewHexEditor()
{
InitializeComponent();
Closing += (o, e) => SaveConfigSettings();
HexViewControl.QueryIndexValue += HexView_QueryIndexValue;
HexViewControl.QueryIndexForeColor += HexView_QueryIndexForeColor;
HexViewControl.QueryIndexBgColor += HexView_QueryIndexForeColor;
}
private void NewHexEditor_Load(object sender, EventArgs e)
{
HexViewControl.ArrayLength = MemoryDomains.MainMemory.Size;
}
private void SaveConfigSettings()
{
}
#endregion
#region IToolForm implementation
public void UpdateValues()
{
// TODO
}
public void FastUpdate()
{
// TODO
}
public void Restart()
{
// TODO
}
public bool AskSaveChanges()
{
return true; // TODO
}
public bool UpdateBefore { get { return false; } }
#endregion
#region HexView Callbacks
private void HexView_QueryIndexValue(int index, out long value)
{
value = MemoryDomains.MainMemory.PeekByte(index);
}
private void HexView_QueryIndexBgColor(int index, ref Color color)
{
color = Color.White;
}
private void HexView_QueryIndexForeColor(int index, ref Color color)
{
color = Color.Black;
}
#endregion
#region Menu Items
private void FileSubMenu_DropDownOpened(object sender, EventArgs e)
{
}
private void ExitMenuItem_Click(object sender, EventArgs e)
{
Close();
}
#endregion
}
}

View File

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="HexMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -45,6 +45,15 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.MainForm.CloseEmulator();
}
[LuaMethodAttributes(
"exitCode",
"Closes the emulator and returns the provided code"
)]
public void CloseEmulatorWithCode(int exitCode)
{
GlobalWin.MainForm.CloseEmulator(exitCode);
}
[LuaMethodAttributes(
"borderheight",
"Gets the current height in pixels of the letter/pillarbox area (top side only) around the emu display surface, excluding the gameExtraPadding you've set. This function (the whole lot of them) should be renamed or refactored since the padding areas have got more complex."
@ -303,7 +312,10 @@ namespace BizHawk.Client.EmuHawk
)]
public static void RebootCore()
{
//pretty hacky.. we dont want a lua script to be able to restart itself by rebooting the core
((LuaConsole)GlobalWin.Tools.Get<LuaConsole>()).IsRebootingCore = true;
GlobalWin.MainForm.RebootCore();
((LuaConsole)GlobalWin.Tools.Get<LuaConsole>()).IsRebootingCore = false;
}
[LuaMethodAttributes(

View File

@ -482,6 +482,10 @@ namespace BizHawk.Client.EmuHawk
{
if (form.Handle == ptr)
{
if (form.GetType().GetProperty(property).PropertyType.IsEnum)
{
value = Enum.Parse(form.GetType().GetProperty(property).PropertyType, value.ToString(), true);
}
form
.GetType()
.GetProperty(property)
@ -493,6 +497,10 @@ namespace BizHawk.Client.EmuHawk
{
if (control.Handle == ptr)
{
if (control.GetType().GetProperty(property).PropertyType.IsEnum)
{
value = Enum.Parse(control.GetType().GetProperty(property).PropertyType, value.ToString(), true);
}
control
.GetType()
.GetProperty(property)
@ -557,7 +565,7 @@ namespace BizHawk.Client.EmuHawk
[LuaMethodAttributes(
"textbox",
"Creates a textbox control on the given form. The caption property will be the initial value of the textbox (default is empty). Width and Height are option, if not specified they will be a default size of 100, 20. Type is an optional property to restrict the textbox input. The available options are HEX, SIGNED, and UNSIGNED. Passing it null or any other value will set it to no restriction. x, and y are the optional location parameters for the position of the textbox within the given form. The function returns the handle of the created textbox. If true, the multiline will enable the standard winform multi-line property. If true, the fixedWidth options will create a fixed width font"
"Creates a textbox control on the given form. The caption property will be the initial value of the textbox (default is empty). Width and Height are option, if not specified they will be a default size of 100, 20. Type is an optional property to restrict the textbox input. The available options are HEX, SIGNED, and UNSIGNED. Passing it null or any other value will set it to no restriction. x, and y are the optional location parameters for the position of the textbox within the given form. The function returns the handle of the created textbox. If true, the multiline will enable the standard winform multi-line property. If true, the fixedWidth options will create a fixed width font. Scrollbars is an optional property to specify which scrollbars to display. The available options are Vertical, Horizontal, Both, and None. Scrollbars are only shown on a multiline textbox"
)]
public int Textbox(
int formHandle,
@ -568,7 +576,8 @@ namespace BizHawk.Client.EmuHawk
int? x = null,
int? y = null,
bool multiline = false,
bool fixedWidth = false)
bool fixedWidth = false,
string scrollbars = null)
{
var form = GetForm(formHandle);
if (form == null)
@ -583,6 +592,26 @@ namespace BizHawk.Client.EmuHawk
}
textbox.Multiline = multiline;
if (scrollbars != null)
{
switch (scrollbars.ToUpper())
{
case "VERTICAL":
textbox.ScrollBars = ScrollBars.Vertical;
break;
case "HORIZONTAL":
textbox.ScrollBars = ScrollBars.Horizontal;
textbox.WordWrap = false;
break;
case "BOTH":
textbox.ScrollBars = ScrollBars.Both;
textbox.WordWrap = false;
break;
case "NONE":
textbox.ScrollBars = ScrollBars.None;
break;
}
}
SetText(textbox, caption);
if (x.HasValue && y.HasValue)

View File

@ -164,7 +164,7 @@ namespace BizHawk.Client.EmuHawk
[LuaMethodAttributes(
"defaultForeground",
"Sets the default foreground color to use when using drawing methods, white by default"
"Sets the default foreground color to use in drawing methods, white by default"
)]
public void SetDefaultForegroundColor(Color color)
{
@ -173,13 +173,22 @@ namespace BizHawk.Client.EmuHawk
[LuaMethodAttributes(
"defaultBackground",
"Sets the default background color to use when using drawing methods, transparent by default"
"Sets the default background color to use in drawing methods, transparent by default"
)]
public void SetDefaultBackgroundColor(Color color)
{
DefaultBackground = color;
}
[LuaMethodAttributes(
"defaultTextBackground",
"Sets the default backgroiund color to use in text drawing methods, half-transparent black by default"
)]
public void SetDefaultTextBackground(Color color)
{
DefaultTextBackground = color;
}
[LuaMethodAttributes(
"drawBezier",
"Draws a Bezier curve using the table of coordinates provided in the given color"

View File

@ -144,7 +144,8 @@ namespace BizHawk.Client.EmuHawk
public Lua SpawnCoroutine(string file)
{
var lua = _lua.NewThread();
var main = lua.LoadString(File.ReadAllText(file), "main");
var content = File.ReadAllText(file);
var main = lua.LoadString(content, "main");
lua.Push(main); // push main function on to stack for subsequent resuming
return lua;
}

View File

@ -27,6 +27,8 @@ namespace BizHawk.Client.EmuHawk
private List<string> _consoleCommandHistory = new List<string>();
private int _consoleCommandHistoryIndex = -1;
public bool IsRebootingCore;
public LuaConsole()
{
_sortReverse = false;

View File

@ -107,6 +107,7 @@
//
// RemoveButton
//
this.RemoveButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.RemoveButton.Enabled = false;
this.RemoveButton.Location = new System.Drawing.Point(93, 284);
this.RemoveButton.Name = "RemoveButton";
@ -140,6 +141,7 @@
//
// RemoveAllBtn
//
this.RemoveAllBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.RemoveAllBtn.Enabled = false;
this.RemoveAllBtn.Location = new System.Drawing.Point(174, 284);
this.RemoveAllBtn.Name = "RemoveAllBtn";
@ -161,7 +163,7 @@
this.Controls.Add(this.FunctionView);
this.Controls.Add(this.OK);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MinimumSize = new System.Drawing.Size(200, 50);
this.MinimumSize = new System.Drawing.Size(360, 150);
this.Name = "LuaRegisteredFunctionsList";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Active Registered Functions";

View File

@ -64,6 +64,10 @@ namespace BizHawk.Client.EmuHawk
break;
}
}
else if (e.KeyData == (Keys.Control | Keys.A))
{
base.SelectAll();
}
else
{
base.OnKeyDown(e);

View File

@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
@ -15,6 +10,7 @@ using BizHawk.Client.EmuHawk.ToolExtensions;
namespace BizHawk.Client.EmuHawk
{
[ToolAttributes(false, null)]
public partial class MacroInputTool : Form, IToolFormAutoConfig
{
[RequiredService]

View File

@ -4,11 +4,11 @@ using System.Globalization;
using System.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions;
using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
[ToolAttributes(false, null)]
public partial class NESGameGenie : Form, IToolFormAutoConfig
{
[RequiredService]

View File

@ -164,19 +164,19 @@
this.toolStripSeparator2,
this.ExitMenuItem});
this.FileSubMenu.Name = "FileSubMenu";
this.FileSubMenu.Size = new System.Drawing.Size(35, 20);
this.FileSubMenu.Size = new System.Drawing.Size(37, 20);
this.FileSubMenu.Text = "&File";
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(129, 6);
this.toolStripSeparator2.Size = new System.Drawing.Size(131, 6);
//
// ExitMenuItem
//
this.ExitMenuItem.Name = "ExitMenuItem";
this.ExitMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4)));
this.ExitMenuItem.Size = new System.Drawing.Size(132, 22);
this.ExitMenuItem.Size = new System.Drawing.Size(134, 22);
this.ExitMenuItem.Text = "E&xit";
this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click);
//
@ -189,9 +189,12 @@
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.menuStrip1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "NESMusicRipper";
this.Text = "NESMusicRipper";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Music Ripper";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.NESMusicRipper_FormClosed);
this.Load += new System.EventHandler(this.NESMusicRipper_Load);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);

View File

@ -515,5 +515,9 @@ namespace BizHawk.Client.EmuHawk
apu.DebugCallback = null;
}
private void NESMusicRipper_Load(object sender, EventArgs e)
{
}
}
}

View File

@ -125,4 +125,299 @@ Make sure the template has 5 tracks. There should be pulse waveforms in instrume
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAYAMBwAAAEAIAAIFgAAZgAAADAcAAABAAgASAoAAG4WAAAgIAAAAQAgAKgQAAC2IAAAICAAAAEA
CACoCAAAXjEAABAQAAABACAAaAQAAAY6AAAQEAAAAQAIAGgFAABuPgAAKAAAADAAAAA4AAAAAQAgAAAA
AAAAKgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADU1NQYpKSkY5aUlIGWlJKBl5WVfpSS
koGUlJSBlpaWepaWlnqWlpZ6lZWVfpWVlX6VlZV+lZWVfpWVlX6XlZV+mZeVfpmXlX6XlZV+l5WVfpaU
lIGWlJSBl5WVfpWXlX6Vl5V+lZeVfpWXlX6Xl5V+l5eVfpeXlX6Xl5V+l5WVfpeVlX6WlJSBl5WVfpeV
lX6XlZV+l5WVfpeVlX6VlZV+l5WVfpeVlX6Vk5GFlJKSgaSkpGPY2NgUAAAAALe3t0QsLCz/CAQD/w4L
B/8WEQ7/Ew4L/xQQD/8NCwr/DwoJ/xALCv8RDAv/Eg0M/xINDP8SDQz/FA8O/xUQD/8QDAv/EQ0M/xMP
Dv8TDw7/FBAP/xUREP8WEhH/FxMS/xMREP8TERD/EhAP/xIQD/8RDw7/EA4N/xAODf8PDQz/FBAP/xMP
Dv8SDg3/Eg4N/xIODf8SDg3/EQ0M/xAMC/8MCgn/Ew8O/xEMCf8UDwz/DwwI/wsHBv8tLS3/s7O3Ry0s
Lv8bGRn/bWhl/4aAe/+Gfnf/eXNu/4B5dv+FgH3/h357/4qBfv+NhIH/j4aD/5GIhf+Tiof/lo2K/5iP
jP+blpP/nJeU/5+al/+hnJn/o56b/6ahnv+oo6D/qqWi/6qlov+ppKH/p6Kf/6Wgnf+inZr/oJuY/5+a
l/+emZb/mJOQ/5eSj/+VkI3/k46L/5GMif+Qi4j/jomG/4yHhP+KhYL/hX57/395dP+Lg3z/jIaB/3Nu
a/8dGxv/KSgq/wQCAv9OSUj/qaOe/6Wck/+onZX/rKOa/6igmf+moJv/rKSd/66mn/+yqqP/tKyl/7au
p/+4sKn/u7Os/762r/++tbL/wLe0/8O6t//Gvbr/yL+8/8vCv//OxcL/0MfE/9HKx//Qycb/zcbD/8rD
wP/HwL3/xL26/8K7uP/Burf/w7u0/8G5sv++tq//u7Os/7iwqf+1rab/s6uk/7Gpov+uqKP/sami/7Ws
o/+uo5v/qaCX/62nov9STUz/BwUF/wQAAP9VUE3/tq6n/8e9s//GurD/x72z/8rBuP/Jwbr/ycG6/8zE
vf/Oxr//z8fA/8/HwP/QyMH/08vE/9XNxv/Yz8v/2tHN/9zTz//e1dH/4djU/+Pa1v/l3Nj/597a/+rh
3f/p4Nz/597a/+Tb1//h2NT/39bS/93U0P/c08//1c3G/9TMxf/QyMH/zcW+/8rCu//Hv7j/xLy1/8K6
s/+8tK3/v7at/7uxp/+3q6H/t62j/6ujnP9STUr/BQAB/wAAAP9tbW3/7u7u/+Li4v/c3Nz/19fX/9fX
1//Z2dn/2tra/9zc3P/U1NT/1tbW/9zc3P/d29v/1NLS/9rY2P/d29v/3NjX/+Xg3f/m4Nv/6ePe/+nj
3v/n4N3/5+Dd/+bk2v/k4dz/4d3j/+Tc5v/i2+D/49nf/93Y2f/Y3c7/3NnU/97Z0P/i2+L/1tfT/9LV
0//Y0dj/3NrQ/9fUz//i4bv/0c7d/8vO1v/d1db/4tvS/+Hp2P9dYmX/BwUA/wAAAP9+fn7/6enp/2ho
aP8mJib/JiYm/ysrK/8pKSn/JiYm/yoqKv8pKSn/MjAw/yYkJP8sKir/NTMz/zEvL/8wLi7/VVFQ/4aB
fv95c27/fXdy/3lzbv9ya2j/e3Rx/3dvaP91cmr/dHJq/3FvZf99d2z/X1ZT/z01PP9BPUP/RT5L/0FE
Nf8+Qjz/OjhM/0FFP/9QVkX/QjtI/0tMSv9PQE7/TEZl/0tPUP9VT0j/hHt3/+bo6P92dYX/BAIA/wMD
A/9ycnL/3Nzc/zk5Of8AAAD/BAQE/wAAAP8BAQH/AgAA/wQCAv8CAAD/AwEB/wQCAv8CAAD/BAIC/wMB
Af8DAQH/Ih4d/0pFQv9IQj3/TEZB/09JRP9KQ0D/SEE+/0s/Pf9DOjf/RkE4/0Q+Mf9JQTT/OTAm/xkS
D/8fGiP/HxUi/xgfCv8iISv/LRpN/yUbLP8kIhr/IB0f/ygmJv8qHzn/JSM3/x4iHP8sJiH/XFRU/+Ti
6P95dYj/BAAA/wMFBf9zdXX/4+Xl/zAyMv8AAAD/AQMD/wACAv8GCAj/W1lY/2xqaf9pZ2b/NzU0/wcF
BP8FAwL/DQsK/wcIBv8RDw//GhgX/yckIP8tKST/JiAb/yslIP80LSr/KiUi/zIpJv8yKSz/Ni4v/zQp
K/8tHyP/KyUY/zw+Kv+TlpT/q6aj/52hov+jpqr/in2N/11PUf+ioYz/rK+m/6Sjp/+mrLH/dn53/yos
Jv80KjD/YVxb/+Pi3v9vbXP/BwUE/wIDAf9tbmz/4+Ti/zk6OP8AAQD/AAEA/wMEAv8eHx3/cGxr/0E9
PP9TT07/XVta/wgGBf8GBAP/CQcG/wsMCv8GBgb/YV9e/8bDv//KxsH/w724/7q0r/+5tLH/w767/7q0
r/+1rrH/rKin/6+oq/++sr7/cG5k/1RaT//NzOb/mYzg/4F75v+mquX/vbjH/4iCff/S0+j/kYrl/4N9
3P+zt+f/pKyr/zUyLf8tIir/XVpW/+bj3v9wb2v/CQsF/xMUEv9pamj/2NnX/zk6OP8AAQD/AwQC/wME
Av8nKCb/RkFA/xINDP8gHBv/VFBP/wQCAf8VExL/BwgG/wgJB/8LCwv/fnx7/+Xi3v+Cfnn/Z2Ne/2ll
YP+KhYL/zsnG/3l2bv9dWlb/YGJP/4aFd//Ty9L/fn15/0ZIU/+GecX/Hhi9/wANof8kJrr/gYek/3aC
bP9gX7v/DhKt/wkRsv8/L73/hoak/z85NP8zLi3/YF1Z/+Td4P9wa2r/Cw4F/wkHBv9pZ2b/4d/e/zo4
N/8NCwr/UU9O/1BOTf9oZmX/TUhH/yIdHP8qJST/cm5t/15cW/9aWFf/MTIw/wwNC/8KCgr/eXd2/+jl
4f+sqKP/pKCb/6Sgm/+wq6j/2NPQ/6ymof+WkJH/nZ6K/7Ctnv/Qxc//fnx0/0tNVf9hUaX/BADM/wAE
xv8QCs3/bGic/3Bxb/9GO7//BAjL/wAAx/8lEr//dHOV/zkyKf8yLSr/YWJZ/+Xb4f9nYWL/CgwM/xkV
FP9jX17/3dnY/0I+Pf8YFBP/YFxb/zMvLv87Nzb/MCsq/xwXFv8lIB//My8u/y8tLP9APj3/U1RS/wkK
CP8NDQ3/QUJA/39+ev+Kh4L/hIB7/4J+ef+GgX7/gHt4/4R4eP+LfYj/f3Zy/4V5ef+EcYT/U1BB/09X
Rv+bksr/JyTe/w4H+P88RMf/npWq/4N3bf+JiMz/GRLl/xEW4/9XVtz/iZGY/0M6MP80LTD/YGRZ/+Xf
2v9lXV3/ExEd/xYWFv9aWFj/2dXU/0E/Pv8SExH/UFFN/ysoJP8wJyT/LSQg/y8mIv8rJSD/LCYh/ykk
If84MzD/UUxJ/xYTD/8bGBD/IyIU/zMzJ/8oKyn/Jyo4/ycoPP8uLzn/NzU0/y40L/81Ozr/MDQ1/zU1
Nf8+Ozf/Mi0q/0E8Pf9vbXP/Y12A/1tYbv9xb3X/YWJZ/0tMQ/93dnj/ZGBz/11Xdv93dXT/XFhX/zw3
NP82Lyz/aWJf/+Db2P9aWFf/FhcV/x4eHv9cV1j/1dHQ/0NBQP8dHhz/VVZS/zs4NP8+NTL/Rz84/0Q7
N/86NC//QTs2/zk0Mf9ST0v/YF1Z/y8rKv8zLyr/QzlF/1xJdP9VPIb/UDeN/0w5fv9USmj/XllW/1E8
ev9QOYP/SDF7/006a/9USlb/Pzwu/yopH/8wLzP/My81/yolJ/82Lyz/Ny4q/ygfG/87MDL/MSkw/zEp
NP80MjH/NjIx/zUwLf86MzD/aGFe/9nU0f9XVVT/Hh8d/x4fHf9RTUz/0c3M/1ZSUf85Ojj/X2Be/1lW
Uv9lXlv/TkY//0Q8Nf9GQDv/aWNe/1RPTP9YVFP/SUdG/zAuLf87ODT/RkI9/1lVUP9VUFL/Uk5a/05K
Vv9STFH/V05K/09EVP9QRlf/SkJT/01FT/9UTEz/R0E8/zQxLf8uLi7/MjYq/zAxJ/8wLSn/OTI1/zct
M/8yKy7/NzIz/zQyMf8tKyr/NjIx/zo1Mv8/ODX/bWZj/9jT0P9RT07/HR4c/ygpJ/9LR0b/z8rJ/15a
Wf85Ojj/Ozw6/zw6Of9PSkn/ZFxV/01FPv9HQTz/XVhV/z47N/87OTj/NTU1/z4+Pv8xKjf/OzQ3/01H
QP9JRDv/SkZB/0dAQ/9KPUX/SzpD/0c/OP9GQjf/Q0I0/0M/NP9COTX/OjIz/zMuL/8wMS//Li8z/zUy
O/80LTr/NCo7/zkvQP8xKjf/OjU+/zEvNf86ODf/Ozc2/zgzMP86MzD/bWZj/9nU0f9OTEv/ICEf/ygp
J/9DPz7/zcjH/2NeXf9DQUD/Ozw6/0JAP/9QTEv/WVNO/1JMR/9WUk3/WVZS/z87Ov87OTj/MzMz/zU1
Nf85OjH/S0k//2hhWP9oXlf/Zl1Z/2FZUv9kW1H/aV5Q/2RZUf9cUlL/WU5W/15TVv9YUUj/SkQ5/zg0
M/8uKzT/GBSR/x0bk/8hHpL/FxOE/yAdiv8eG4j/IR6L/xsbh/81MzL/OjY1/zs2M/88NTL/bWZj/9PO
y/9HRUT/KSoo/y8wLP9DQDz/zcXF/11YV/9APj3/QUJA/0NEQv9EQD//U05L/0xHRP9OS0f/TElF/0A+
Pf89Ozr/Ojs5/zs8Ov81NDb/RT9A/2BUUv9eUkz/XlVM/1tSSf9aT0v/Xk9N/1xVQv9VTj3/U01A/1hS
R/9XTkX/SD87/zkzNP8zMjb/MCxP/ywqR/8yM0f/Ky04/zI1Pf8wMzv/LjA7/zMzQ/87OTj/Pzs6/0A7
OP9AOTb/cGlm/8/Kx/9APj3/LS4s/zM0MP8/PDj/zcbD/2JaWv9CQD//R0hG/0RERP9CQED/R0VE/0A+
Pf89Ozr/Q0FA/0E/Pv88Ozf/PDs3/z8+Ov88QDX/RkI9/1tNTv9ZSkj/W09J/1lQRv9WTkH/VEs+/1VD
UP9RR0f/TUo8/05HPv9MPkL/QDI9/zkzNP86PjL/PTY5/zgyM/89ODX/Ozcy/z06Mv89NzL/PTcy/0A5
Nv89Ozr/Ozc2/zo1Mv8+NzT/cmto/87Jxv89Ozr/MzQy/zY3M/85NjL/zMXC/2piYv9HQ0L/QUJA/zs7
O/9EQkL/Ojo6/0RERP89PT3/QD49/zs5OP9APzv/QD87/z06Nf84ODj/S0ZF/2peWv9rX1X/amJR/2Ve
T/9iW1L/ZFhY/2BXTv9hWVL/XFZR/1pUTf9dVEv/UEhB/z86N/86ODj/PDov/z89M/8/Ojf/QDo7/z84
O/9COjv/Rj4+/0A5Nv8+PDv/QDw7/0I9Ov9GPzz/dm9s/8rFwv84NjX/Njc1/zs6Nv80MS3/ysPA/7qv
q/+Xi4X/loyF/5mSif+TjoX/mJCJ/5iQif+YkIn/mJCJ/5iQif+YkIn/mJCJ/5iQif+Zj4j/oJaP/6ie
l/+roZr/qqCZ/6iel/+nnZb/qJ6X/6ael/+mnpf/pp6X/6Sclf+impP/npaP/5uTjP+ZkYr/nZWO/52V
jv+dlY7/nZWO/52Vjv+dlY7/nZWO/52Vjv+cl47/oJmQ/6CWj/+glI7/uq+r/8nCv/82My//Ozo2/0ZH
Rf8lISD/wLu4/+Pa1//h1tL/5dzY/9rUzf/e29P/39fQ/9/X0P/f19D/39fQ/9/X0P/f19D/39fQ/9/X
0P/c1M3/39fQ/+La0//i2tP/4NjR/9/X0P/g2NH/4trT/97Wz//f19D/4NjR/+HZ0v/h2dL/4NjR/9/X
0P/f19D/39fQ/9/X0P/f19D/39fQ/9/X0P/f19D/39fQ/9/X0P/Y1c3/39nS/+Tb1//d0s7/6N/c/8G8
uf8hHRz/TU5M/4SEhP8RDw7/ZmJh/6mhof+mn5z/pp+c/6qmof+in5r/p6Kf/6ein/+nop//p6Kf/6ei
n/+nop//p6Kf/6ein/+nop//p6Kf/6ahnv+loJ3/pJ+c/6Oem/+loJ3/pqGe/6Wgnf+loJ3/pqGe/6ah
nv+moZ7/p6Kf/6ahnv+moZ7/p6Kf/6ein/+nop//p6Kf/6ein/+nop//p6Kf/6ein/+mo57/pqKd/6eg
nf+qo6D/o5ub/2RgX/8VExL/f39//9ra2gdcXFzXCQcH/wkEBf8ZFRT/DQkI/xAODf8PDQz/EAwL/xAM
C/8QDAv/EAwL/xAMC/8QDAv/EAwL/xAMC/8SDg3/Eg4N/xENDP8RDQz/Eg4N/xIODf8RDQz/EAwL/xIO
Df8SDg3/Eg4N/xENDP8RDQz/EAwL/xAMC/8QDAv/EQ0M/xENDP8RDQz/EQ0M/xENDP8RDQz/EQ0M/xEN
DP8NCwr/EQ8O/wsHBv8XExL/DQgJ/wwKCv9cXFzX////AwAAAAAAAAAAtbW1SZyZmXScmZl0kpCQhJmZ
mXSYmJV3mJWVd5iVlXeYlZV3mJWVd5iVlXeYlZV3mJWVd5iVlXeXlZV7l5WVe5eVlXuYlZV3mpiYd5qY
mHeYlZV3l5WVe5eVlXuXlZV7l5WVe5eVlXuXlZV7l5WVe5iVlXeYlZV3mJWVd5iVlXeYlZV3mJWVd5iV
lXeYlZV3mJWVd5iVlXeXl5V7mZmZdJCOjoiYlZV3n5ycbba2tkYAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//
/////wAA5P/5/9/nAACAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAgAAAAAABAAD7/////98AAP///////wAAKAAAADAAAAA4AAAAAQAIAAAA
AACACgAAAAAAAAAAAAAAAAAAAAAAAAMCAf8JBgX/BwgG/woLBv8GCAj/DAsK/xENDP8VEg7/FBMR/xkV
FP8aGBP/ExEd/x0dHP8hHRz/KB8b/x4iHP8lIhv/Hxci/ykdJ/8qHzn/JiQj/yslIv8nKCb/Kikl/yIh
K/8tIir/Kysq/zAnJP8yKSb/Mi0s/y4yLf8xMif/OTAm/zMyLf85Myz/PTwt/yUjN/8uLTP/Jyk6/ywu
OP8yKzP/NCs6/y4wO/80MzL/OjQz/zw5Nf8yMzv/PDU7/zU7Ov87Ojn/Qjo0/0AyPf9BPTv/ST88/zxA
Nf8+Qjz/Q0I1/0lBNP9EQTz/SkQ8/0xJPf9UTD3/LRpN/ywqR/85L0D/MCxP/zIzRf86OEz/QzxC/0s8
Q/9DPEn/TTpr/0o1fP9RPHr/REJB/0pGQv9HSEb/TUlF/05CTv9NS0r/UUdH/1NMQv9STUv/W01L/09X
Rv9RU0P/WVJF/1NQTf9bU0v/VFpP/0tIU/9SRFP/U0tT/1tOU/9STlr/VVNR/1tUUv9cWFb/XFdY/1xa
Wv9gV07/ZV5P/2BUUv9iWlL/aV5U/2JcW/9qXlr/X2Be/2BiT/9qYlH/YmJb/2hhXP9MRmX/VEpo/1tY
bv9cSXT/XVd2/11iZf9mYWH/amVj/21oZf9ra2r/cGxl/3Jtav93c2z/a2hz/3Fvdf90dHP/fHZy/3Z+
d/9+enT/d3Z4/359e/+Dd23/g3t4/3aCbP+GgXz/FxOE/xsbh/8eG4j/GBSR/x0bk/8gHYr/IR6S/wAN
of8OEq3/CRGy/x4Yvf8lEr//JCa6/z8vvf9ROYf/Rju//2NdgP93dYb/bGic/3Rzlf9hUaX/YF+7/wID
yf8QCs3/JyTe/xUU5P8OB/j/PETH/1dW3P+IeYj/hnnF/4N93P+Be+b/hISE/4uFgv+OiYb/lIuF/5KM
iv+Yj4r/lpGO/5qSi/+dnor/iZGY/5WUlP+Ylpb/l5iW/52Zlv+bmZn/oJWO/6SclP+onZb/o52a/6Kh
jP+poJf/pqGe/6uim/+wrZ7/g4ak/56Vqv+doaL/paSm/6qkof+sqaT/o6aq/6Ssq/+vqKv/tKuj/7Cr
qP+6r6v/u7Os/6assf+1rrH/tbS1/7u0sf+7tLv/wLe0/8O6s//DvLn/yL+8/8bBvv/Kwrz/4uG7/4mI
zP+bksr/vbjH/5WL4v+mquX/s7fn/8zFwf/Oycb/z8rJ/9DHxP/SysT/0MXP/9LNy//Yz8v/19TP/9vT
zf/Y3c7/y87W/9LM1//U1NT/3dbQ/9zZ0//Y0dj/29ra/+HW0v/h2dP/5Nza/+jf3P/m4tz/zczm/9LT
6P/j2+L/3uDg/+bm5v//////AAAA/wAAAP/9/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39
/f39/f39/f39/f39/f397sW0tbW1tLW1t7S0tLS4tbW1tbW0tLS0tLa0tri4trW0tLW0tLW1tLS1sLDH
7v3TGgEDBwYHAwYGBgYGBgYGBgYGBgcICAkICAYIBgUGBggHBwUHBwYFBQcGBgYBGtEaDHiIiHyCiIiI
iKytra+xtbW8vLzAwMbGxsa8vLy3tbGwsLCsrqyrq4aGiKt7DBkATb+6u8C+v8DHy8vLzc7O0tTV19fZ
5OTl5eHh2dbW1tXVzs7Oy8vLx8vLwb7HUgEAV87X1dXZ2NjZ4uXi5eXo6urv7/T19fb29/X18/Pv7+fl
5eHZ1tbVzs7Oy8vAVwAAfvz78vLu8vLy7u7y8u7x8vD19vf19vb39fz69frw6/Dr+u7u7+vu2u3s8PT3
dQEAhPx5FBYaFhQaGSsVGiseJVeqfICAe3x8fHt6fGUvREY4N0NKVEZPTnBaWIb8mgAAfvIxAAAAAAAA
AAAAAAAAAA1LO0tRO0s7Mjk5OSAHEQ0KGD4SEAwUEyQQEGD8mgAAgfweAAAAAmN5eSsAAAUCBgwQFw4Q
IRAcHSgdEhAjtsfExaZgvcrFz4EXKGn3fgAAefwwAAAAD3s0UmMFAAUFAmPY4tjS0tjS0MbL3XhZ+N6p
392I+d6o4MkhGWH8eQMIee4xAAAAGUoGDVwACAQFBYT8gm5uq+J8Y2yI54Rap5OQlcKHnpGSmMIyHWf6
ewUFefUvBV9Xd0sNFXxjYCEFBIT3x7+/zOrGsbLB5oJanZ+foJt+mJ+flJwgHW71dwUJbvI3CGMoMR0J
EB0dSl8DBjqIrIaEiISGpoaGpj1U3KGjpMOF26KipbMyKG71aQsIYe9ECFQXGxUbFRwQIVcHBxAfFycm
KiweLiUrNB06fZlyfm5NgHR0f2MsIHfyYwgRY+5KDF8tLDk0IjIsV2EaHURzl5eXcWBJl0hHWyMVKCsX
IR0OLCgoKyshLGrvXwwPT+NXLXZgaVEyOm9XYE8lLTphXF5aW1NbWlpaUjUhHiEdHSwsKCsrGiEsMnfu
Xw8WTuNjMDExT2c7O2ExMSs3JSw7O01LRUU1OTgyMiwdJSUuKSlAJy8oLS8iLHjvTxEXOuN2SjA6UldS
V2ExMSsrLU1qaGdmZW1lYF1mVjsrJYyNjYmOi46KKy0sLHjnShoeOuRgN0pMN1JNUk00MTAxK0RmZGRT
U1NWPT1XVjUsK0E/QiUuLilCLzI0MnrhSh4rMeFpOkxKSk0xMTo3LS06NjpTU1NWUT1bUDw9RTMsLS0s
MiwsMiwyNC8sLHvjMSsrLeF3RToxOjFMMTQtOjotLUtqaGxtZWlYZ2FYWFE0LS0jNC80NDQyMTQ0NXvh
KystIdnNr62wra+vsa+vra+tr7q+wMC7u7rAvru6urGxsbm1srqxurm1srm5uc3hLDFMDdP18/Xq8O/z
7/T09PT06ur09PTw9PTq7/Pw9PTv7+rq6urq6urr6vD16vbWDVSqCHbGvMDGv8W/v7+/v7+/xsa/v7y8
v7+/v8XAv7+/v8bGxsbGxsbGv8a8xrx2CITyYwMBCQEGBQYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYG
BgYGBgYGBQUFCAUFY/v9/dG4uLS2t7W1tbW1tbW1tbW1tbi4tbW1tbS0tbW1tbW1tbW1tbW1triuuLjR
/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f3///////8AAOT/
+f/f5wAAgAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAIAAAAAAAQAA+//////fAAD///////8AACgAAAAgAAAAQAAAAAEAIAAAAAAAACAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzMzAWoqKhBlpSUaZeUlGeUlJRplJSUZZeXl2OWlpZmlpaWZpaW
lmaWlpZmmJaWZpiWlmaYlpZmlpSUaZeUlGeWlpZmlpaWZpaWlmaWmJZmlpiWZpaWlmaXlJRnl5SUZ5iW
lmaYlpZmlpaWZpaWlmaYlZNolZKSaqenp0C/v78Ea2tuUSIhH8gpJCLYKyck1yomJdgnIiLWJyMi1Sgk
I9YpJSTXKicl1yonJdcpJSTXKicl1ysoJ9csKSjYLikp1yopKNcpKCfXKSgn1ygnJdcoJyTXKicn1yon
JdcpJSXXKSUl1yklJNcnIyPXKSUk1yklI9cpJSLYJCIiyGxsbFI4ODjCOTUz/1JNSP9OSET/UEtJ/1JL
Sf9VTUv/V1BO/1lSUP9cVVP/XldV/15aWP9iXVv/ZF9d/2ZiYP9pZGL/Z2Rh/2ZiYP9kYF7/YV1b/2Bc
Wv9eWlj/XFhW/1pWVP9ZVFL/V1NR/1VQTv9TTUv/UEtG/1VQS/89OTf/ODY4wyAeH/9xbGn/k4yF/5CI
gf+Ri4b/lo6J/5qSjf+elpH/oZmU/6WcmP+poJz/q6Sh/6+opf+yq6j/trCt/7qzsP+6tLH/uLKv/7Su
q/+wqqf/rqil/6uloP+oop3/pZ6a/6Gblv+emJP/m5WQ/5iRjf+Xj4j/mZGK/3Zxbv8gHh//FxMT/5WP
i/+wpp3/s6mg/7Kqo/+0rKX/uLCp/7y0rf++tq//wbmy/8W9t//Hvrv/y8K//8/Gwv/Tysb/1s3K/9jQ
zf/Vzsr/0cnG/83Fwv/Kwr//yMC6/8a+t//BubL/vLSt/7iwqf+1raf/tKyl/7Wrov+upJv/lY+K/xkV
Ff8YFRT/pqCb/8vDuv/Kwbn/zMW+/8zFv//PyML/0MnD/9HLxf/TzMb/1s/K/9rSzv/e1dH/4dnV/+Tb
1//m3dr/6OHc/+be2//j2tj/4NfU/9zU0P/X0Mr/1c3H/8/Jw//LxL//yMG7/8W+tv/CurT/vrWu/760
q/+cmJH/GRQU/xsbG//Nzc3/19fX/83Nzf/MzMz/zs7O/87Ozv/Ly8v/0NDQ/8zKyv/Qzs7/08/O/9/Z
1v/h29b/4dvW/+DZ1v/e3NP/2tfZ/9zV3P/a0db/0c/M/9HQyf/V0Mr/z87N/8rLy//Rzsn/0M7C/8zJ
zf/Hx83/2tLM/8DHvP8cHBn/Hx8f/87Ozv9gYGD/MTEx/zU1Nf8xMTH/NDQ0/zo4OP8yMDD/PDo6/zs5
Of9UUVD/iIOA/4J8d/9+eHP/f3h1/312b/97eHH/endu/25lYf9HQUf/TUdR/0pMQP9ERFD/TVFJ/05L
T/9UUVL/VU1m/1VXVv9+dnH/ycvO/yAeIP8eHh7/w8PD/zMzM/8JCQn/CAgI/wgHB/8KCQn/CwkJ/woI
CP8MCgr/CwkJ/yMgH/9UTkv/VE5J/1VPSv9RSkf/UUdD/05IQf9OSDv/RDwy/yEaG/8lHSn/ISYZ/y0h
Rf8qJSz/JyQl/y8rMP8tKD7/KSsm/1dPTv/Jx8//IR0h/x4gIP/Fxsb/Jicn/wECAv8BAgL/MC8u/0pI
SP8vLSz/BQMC/wgGBf8HBwX/GBYV/zIuKv8yLSj/NzEs/zUvLP85Ly3/OjIx/zguK/8wKB//QEA1/3t2
eP91eXb/cGV7/1dNTv9+f3b/fXyB/2Vpbf8pKCT/U01N/8fFx/8hHiD/HR8e/8bHxv8nKSj/AAEA/wYH
Bv9RUE7/VlJR/1BOTf8HBQT/CQcG/wkKCP80MjH/gX56/4B6df98dnH/f3p3/312dP95cnP/enB0/11W
UP9kZ1//pZ7E/5OSyP+moLX/h4B//6Six/+Ylsf/l56j/zAsKv9TTU3/x8XC/yEhH/8hIiD/wcLA/yor
Kv8AAQD/CgsJ/05LSv8wLCv/UU5N/wcFBP8JCAb/CQoI/1RSUv/JxsH/npmU/5qUkP++ubb/mZSQ/4uJ
gv+noaD/ioaD/2Vncv91bNL/UVTK/5WVvv+IiY3/aWjO/1pZzP+Rk7P/NjEu/1JOTP/Hw8H/IyQe/yYm
JP++vrz/LCwq/xUVFP8jIyH/REFA/xoVFP9OSkn/IiAf/xkZGP8JCgj/YF5d/9DMyP9/e3b/gn15/8K9
uv+Cfnj/cnJj/6Kflv+Tj43/VFJt/y8nwP8HDrH/Y2Wp/21ygP8eILf/EhK5/25ppv86NC//VFJN/8a/
wv8jJB//IiAf/8K/vv8wLi3/QkA//09NTP9NSUj/Ih0c/1ZSUf9VU1L/Pj89/wsLCv9VVFP/yMXB/5+b
lv+gnJf/v7q3/6CZlv+Wk4f/rqeh/4iEgP9TUmj/IhzG/wgIzv9eWan/a2eD/xoZzP8NCsr/ZWKh/zgx
Kv9VVU3/xbzA/yIhI/8rJyb/vrq5/zczMv9NSUj/NDAv/zItLP8fGhj/Lyop/zIwL/9OTUz/CgsJ/zIz
Mf98e3b/f3x4/315dv98d3X/gHV3/3xzc/9/cnf/XFVP/2BjZf9GQdP/HRrk/4N/rP+BeIH/ODLY/yYp
2v96gKT/PjYw/1VWTv/Evrr/JyQs/ycmJv+5trX/NTMy/0FCPv8sKCT/LiUh/y0kIP8rJiH/LSgl/0pG
Q/8WEw7/IiAV/zU1LP8tLzj/Li8//zk4Of81OTb/Njk6/zw6Of83Mi//TUpM/2Negv9cWXf/Z2Zl/1hY
U/9lYnr/X1p8/2RhYv86NTH/W1VS/766t/8nJyX/LCsr/7ezsv84Nzb/RUZD/zg0MP9AODL/PTUx/zs1
MP87NzP/WVVR/ysnJP85Mjb/UkFp/0k1ev9HOW3/VE5T/0o6bv9FM2//Sjxc/0E8Nf8xMCv/OzhC/zYx
Nf8/ODT/NCwp/z01Pf87ND//PTo5/zcxLv9cVVL/ubWy/ysrKf8rKyn/sq6t/0hFRP9QUU//UU1K/09H
Qf9DOzb/VU9K/05JRv9RT03/MS8t/0E8O/9YT13/Ukdo/05GX/9XT1D/T0Fh/0s+YP9ORFX/SEI9/zAu
Kv8xMi3/Ly0n/zYvL/8yKSz/NS4x/zIuMP80MC//OTQx/19YVf+2srD/Kiop/y4tLP+vqqn/Uk9O/0ZH
Rf9MSUf/WVJM/0hAOv9bVVH/R0RB/0A+Pv83NTb/PTc4/1FMRv9NSUr/SkRL/09CR/9KQUT/R0JC/0hB
P/9COjj/Mi8u/y8xLv8yMDL/NS02/zYtOP82MTf/MjAy/zc0M/85NDH/YFlW/7ayr/8qKyn/Ly8t/6yn
pv9XVFL/Ozw6/0JAP/9bVE//TkhC/1dTT/89Ojj/NTU1/zg3OP8+Ojj/WFFJ/1ZPSv9TSkn/V0lJ/1JK
Qv9NR0L/TkZB/0M8N/8zMDD/JyVR/yonYf8oIVz/LCZe/y0pXv8rKk//OTY1/zk0Mf9gWVb/s6+s/y0t
LP8wMC3/qqWk/1lVVP8+Pjz/RENB/1RPS/9QS0f/VFFN/z47Ov82NjX/Nzc1/0RCPP9lXFX/Y1pU/19W
T/9kWE//X1ZM/1dOTv9bUk7/TEU8/zYyM/8jH2r/IiB7/x8db/8lJHH/JCNx/ycnYv86NjX/PDc0/2Fa
V/+uqqf/MDEv/zQ0MP+qo6L/VlFR/0FBQP9DQ0H/TUlH/0pFQ/9KR0T/Pz08/zo7OP86Ojj/QT09/15S
T/9dU0v/WlBI/1tOSf9ZUEP/Ukw//1VORf9KQD3/NzM0/zIvRf8vLUP/LzA6/zM1Ov8xMTn/NjU+/z06
Of8/OTb/ZF1a/6qmpP8yMjD/NjYy/6mjoP9aU1P/RUVE/0NCQv9FQ0L/Pz08/0E/Pv8/PTz/PDs3/z4+
OP9DQTv/W01N/1tOSf9ZUEX/VUxA/1RFTf9OSj//TkU//0Q2Pv85NTP/PDg2/zk0M/87NzP/PTky/z03
Mv8/OTf/Ozg3/zs2M/9lXlv/qaWi/zU1NP82NjL/p6Ge/2BZWf9CQkD/PT09/z08PP9CQUH/Pz09/zw6
OP8/Pjr/Ozk1/0ZCQf9pXVf/aWBR/2NcT/9iV1X/X1ZO/1xVUP9ZU0v/UklD/z05N/87OTH/Pjsz/z85
Of8/ODr/RDw8/z85N/8/Ozr/Qj06/2liX/+loZ//NjY0/zg3M/+ln5v/opeU/4Z9eP+GgXn/hX95/4eB
e/+HgHr/hn95/4eAev+Gf3n/jYR//52Si/+elIv/m5GJ/5qQiv+YkIn/mJCJ/5WOh/+QiIH/iYF7/4mD
e/+LhH3/i4N+/4uDfv+MhH7/i4R9/42Hf/+OhX7/pZuX/6Sem/85NzT/PDs5/5yXlP/TycX/y8G9/8XA
uP/Iwbr/yMC5/8jAuf/IwLn/yMC5/8jAuf/Kwbr/0MfA/8/Gv//Nxb7/z8a//8zEvf/Nxb7/zcW+/8vD
vP/Jwbr/ysK7/8rCu//Kwrv/ysK7/8rCu//Jwrr/ycS8/83Dvv/Vy8j/nJeU/z8+PP9VVFP/cGxq/8G5
t//BubX/vrmz/765tP+/ubT/v7m0/7+5tP+/ubT/v7i0/7+4tP/AubX/vriz/723sv+/ubT/vrey/7+4
tP+/ubT/v7m0/764s/+/ubT/v7m0/7+5tP+/ubT/v7m0/765s/++ubP/wbm1/8C4tv9wbGr/VVVU/2Zm
Zqk4NjX7ZF1d/2ReXP9lYl//ZGBd/2RgXv9kYF7/ZGBe/2RgXv9lYF7/ZWFf/2RgXf9kX13/Y19d/2Rf
Xf9kYF7/ZWBe/2RgXv9kYF7/ZF9d/2VgXv9lYF7/ZWBe/2VgXv9lYF7/ZGBe/2RhXv9kXlz/Y11c/zk2
NvtkYmKoaWlpKSkmJrolICDUKCMj1yYlJNQnIyLVJyMi1ScjItUnIyLVJyMi1ScjI9UpJiTWKCUj1Sgl
JdUoJSXVJyMj1SkmJNYoJiTWKCQj1igkI9YnIyLVJyMj1SclI9UnJSPVJyUj1SclI9UnIyPVJiYl1CYj
ItgmISPSKikpuWJiYicAAAAAs7OzLJ2aml6Tk5NomJiYX5iVlWGYlZVhmJWVYZiVlWGYlZVhlpaWYpiW
lmSXlZVjmJWVYZiVlWGXlZVjmJaWZJaTk2SWk5NkmJaWZJiVlWGYlZVhmJWVYZiVlWGYlZVhmJWVYZaW
lmKXl5dgkY6Oa5yamlu3t7crAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////+AAAABAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAB//////////8oAAAAIAAAAEAAAAABAAgAAAAAAAAI
AAAAAAAAAAAAAAAAAAAAAAAAAQIC/wgGBf8HCQj/DAwL/xEPD/8UExP/HRoW/x0bGv8hHR3/JSAf/yQj
I/8rJiP/LCkm/ysrKv80LCb/Mi0s/zIwLv88NC//Liww/zMuM/80LDn/LzEx/zExMP81MjH/NjQy/zMx
Nf82MjT/NjU1/zgyMf84NDL/PTYx/zk2Nf89NzT/Nzg2/zw4Nf81MDn/OTc4/zo7OP89OTj/PTw6/z05
Pf8+Pj3/QDc0/0I7Nv9BPDv/SDw//0NBPf9KQz3/KCdP/y0rTv8yL0b/My5J/zIyQP85NUf/PTlA/yok
Xf8rKVv/JyNg/yonYf8lI2n/JSNz/0E8Rf9APk7/QD5Q/0g9Vv9MP13/RDZm/0U6ZP9JPWL/Rjdt/0VD
Q/9KRUP/TEhF/0ZETP9KRUr/SklI/01KSf9LTEn/TkxK/05KTP9OTE3/UUpE/1lPRv9QREj/U01K/1hL
Sf9WUEz/W1FL/05DVf9PSVL/Vk5S/1ZMXP9UUlH/WVRT/1xZVP9XV1j/W1VY/1paWv9dWlj/XVhd/11d
XP9iVk7/YVpU/2FaWP9gXVv/ZF1a/2JdXP9mX1z/aF5Z/2VhXv9rYVv/cGZa/09GYP9QQmD/UUZo/1lX
Yv9OS3//XFl0/2FeY/9jXW7/YGBg/2diYP9jYmT/ZGRk/2llY/9taGb/aWxn/2Fhaf9ybGn/dnBv/3ly
bv97em3/bGN3/21ufP90b3L/eG9y/29ydf9xcXH/dnNz/3d1c/92dHT/enJy/3x3cv98cnT/eHZ2/3l4
c/95eHf/fHh1/3d2f/95eHj/fHx9/4V+ef+FgHr/iYJ9/xIXuf8cGr3/KSq8/1JPgf9ZVYL/YF2f/21q
jP9ucYv/eXOD/2xtlv9yb57/XVqq/2Zhov9gYan/DQ7O/xUSy/8vKMb/JCLL/ykny/8wMMf/OTLA/0A9
xf9KRcP/VVfJ/11by/9sa8z/d2/P/4B/gP+LhoL/kouE/5OMif+XkY3/mZGM/4qLlv+PlZ3/k5GR/5WR
kP+WlZX/mZOR/5mVkf+dlZH/mJaW/5yXlv+XmJb/mJiX/56Zlf+ZmJj/nZqa/56cnP+glpP/opqW/6Oe
m/+moZ3/qaKd/7Cmnv+HiKz/npmv/42Nuf+loaD/q6Wj/66ppv+op6j/rayr/7Oqo/+yrKr/tbGu/7qz
rf+1rrD/srGx/7Wysf+2tLL/tbK1/7W1tf+6tLD/vLi1/7m3vv+8vLz/wbev/8K6tP/Fvrn/yL+4/8bA
tv/DwLz/ycG8/5OTxP+gnMD/w8HA/8zEwf/OyMT/zcbJ/83JyP/RysX/1c3K/9bQyv/Z0s7/0dDS/93U
0v/h2dX/49vZ/wAAAP8AAAD/AAAA//nYv7+/xca/v7/DxsbDw8G/xcXFxcbDw8bDv8O/wNj5tZKSkpCQ
kpWSkpCVlZOVlpWVlZWVlZWSlZKSlZOSlZZfDRgRHRAQGB0dHxwiHyIkIB8fGx0fHxgYGxAQHRAPXxsi
UUhIVlZXXV1mYmpqfHx7fGttaF5eXl1XXVZRViIbCXy3t7e3ubrCzM3V1dna3Nza2tXVz8/MzMK6ubq3
gAoHttbQ2drc3Ofk6Ort8vX3+Pf08e3t6Ojc3NnZ2c+2CQrO7e3x7fLy8vb3+Pr7/Pz8/Pz6+Pj19e3s
7Onj58EICubs3t7e4t7i3+Pm8vL19fX08fHm5OTl4uTc4+Lp4AoN5ohGS0lGT0dOTHm2tpiZmJiXgmBi
XnNoZHl3erblDQ3iKQMEBAcFAwQEClZSVlRRUVErCxQQNRQeKDUQZ+UNDd4WAAANLA0BAQIGIiIrKysq
KhEuhoWEXZKifw9d4g0N3hUAAkhcSwMCAhuTjoGTjYqHXn7v7tK27+68HV3hDQ3YFQADRhFIAwIDXOTH
udvAmdS2hbSx07uzstEfXeMNDdgYBg0uCEYMBwNk7Ji247aDzrh1rpqnoZybpite3Q0N2B8bRy8JR00n
A1bbwcHawLfPtnWqqKWgq6mfIl7aDQ/YJy4fEAkREUYFGJGLi5OPhodmf7CspKKvraMrXtoNEtQpJxAO
CwwQRgYLRj8/SklKSidQnp1/Yp6ddiJm2BAW1C4uIh4RIiJWDBpBRUNZREJAKx09KCsqPT0sHWnUFRDN
UE1WSCtRSFQYLFtycVpxRFgvEBYNEw8TExcdZ9QQFsldRkhXL1ZIKSMsSE9KU0dHLywQFRMUFCQaGxxr
zhUXxF4pRlZIViwhISZXV1RSUUhIKxMwOjc6ODEfHmvNFhDBaClGVk5WJyQhLmZlZWVlUlcvHzk8Ozs7
OCIfa8kYIcBgLkZIR0YuIicvV2VXUlJRUi0fMjM0NDQ0JitswhgYwWdGRkYuRiknIi5VZVJSUlFRLR0i
JSIiJCsmIHzDGyG6fUxIS1BIR0hHVW9vbm5sZmZXSC8vSEhRSEhRgMEhIr7LmZmYmJiYmJe2urq6urq6
t7eZmZmZmZmZmbbLviInuPHo5Ojo6Ojo6Ojt7ert6urp6ejo6Ojo6OTp6vG4J1B93ePc3Nzj49zc3OPj
4+Pj49zj4+Pj4+Pj3Nzj3H1QZCZrbXltfHlufHl8bW1tbW1rfGtteXl5eXl5eW1rJmR4GxcdGB0XFxcX
HB8fHR0dHx8dHxccHR0dHRcYFxcbZHiMlYySkJWVlZWVkJCSkpCQkJCQlZWVlZWVlZKMlZV44t7Jv8jG
w8PDw8PDw8jIw8O/v8PDw8PDw8PDxr3K3uL//////////4AAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAH//////////ygAAAAQAAAAIAAAAAEAIAAAAAAAAAgAAAAA
AAAAAAAAAAAAAAAAAADGxsYJlJSUMJSUlDCVlZUukpKSL5eXki+Xl5IvlJSUMJeXki+Xl5cvl5eXL5SU
lDCXl5cvkpKSL5OTkzLf398IKSkp/yQeG/8cGRj/IBsZ/yIcG/8hHRz/JCAf/ygkIv8lIyL/IyAf/yAe
Hf8iHh3/IR0c/xsZGP8iHRr/Kyoq/0dDQv+jmZH/oZyX/62lnv+zq6T/ubGu/8G4tf/JwL3/y8TB/8K7
uP+8tbL/uLGq/7Coov+po57/qZ+X/0tGRf9kYmH/08/L/9PQzf/Rzsz/2NPR/9vW1f/j29f/5t7b/+Xg
3P/h2dv/2dnO/9vT1f/Rysz/09C1/87Fwv9YWlr/eXl5/xcXF/8aGhr/GhkZ/xwaGv8fHR3/ZmBb/2Nc
Wf9iXVb/aWJX/zQvN/8zNTX/P0I0/0EzRv9FPzn/d3WG/3J0c/8AAAD/CQoK/2ZkY/8FAwL/Dw0N/0A8
N/9EPTr/Qjk8/z8xNv+anJ7/o6ax/6inl/+nrbf/Mykv/29tcv9pamj/AAEA/yUmJP8mIiH/ExEQ/woK
Cv+Lh4L/j4qH/2hkYf/Qx8//joPJ/zQ2v/9ubcD/TUDC/zIsLP9wa2r/ZWJh/xMQD/9LSEf/JiEg/0lH
Rv8LCwv/lpOO/5WQjf+PhIv/oJCg/4V5vP8rLsn/b2vH/0Q80f8zLS3/ZV5e/1pXWP8WFxX/NSwp/zAq
Jf9BPTr/JCAZ/zgxS/88OUr/PzpV/0ZAQv9XVVv/WldZ/2BbXf9dW1r/NzAt/1hWVf9QTEv/OTo4/2Jb
WP9GQDv/VFBP/zk2NP9TTk//UUpP/05FU/9RSUn/Li4u/zAtK/8xKi//Liwr/z43NP9QTk3/REA//0FA
P/9PS0r/VE9K/zs5OP84ODH/ZFpT/2BXT/9ZUE7/VU5F/y4rM/8jH4f/IBx9/zUzMv87NDH/R0VE/0A9
Of9BPz7/QkA//0NBPv88Ozj/OTs1/1pNSf9XTkT/UklD/1BEQ/83OTP/ODY7/zg1Nf88Ojn/Pjc0/z48
O/83NDD/ZV5b/2FeW/9fXFn/YV1Y/1xYVv+Dd27/e3Nr/3pya/92bmb/XVlW/2JcV/9kXFr/YV5a/2de
Wv83NDL/Ih4d/9nPy//W08v/2NDJ/9jQyf/Vzcf/2tLM/9jRyv/X0Mn/2dLL/9fQyf/Y0Mn/2NDJ/9HO
x//WzMj/Hxsa/1FPT9wqJiX/IR8d/yIeHf8iHh3/JCAf/yMfHv8jHx7/JCAf/yMfHv8iHh3/Ix8e/yMf
Hv8gHhz/KSUj/1FRUdwAAAAAnJycLJiYmC2YmJgtmJiYLZWVlS6YmJgtmJiYLZWVlS6VlZUumJiYLZiY
mC2YmJgtlZWVLpiYmC0AAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA//8AACgAAAAQAAAAIAAAAAEACAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAA
AAAHBQX/EhMS/xMSEf8WFRT/GBcX/xgZF/8bGRn/ICEg/yUlJP8oJCD/KCYl/ysrK/8tLSz/NS4p/zEt
LP8wLi3/MTAu/zIrMv8zLzD/NS4z/zQxMf8yMTf/NzU0/zc2Nf86NTT/ODY2/zk2Nf86Njb/OTk3/zo4
N/8/Ojb/NTI6/zg1Of88ODn/Pjk4/zw6OP8+Ojn/Pzs6/z08Ov8/Pjr/Pzk//0A7N/9BOzr/Qz88/0Q+
PP9DQD//RUE//0ZCPP9IQj//LSpG/zIwRf89N0b/PzpN/z01Uv89N1T/JiJr/yklaP9DQUH/Q0JB/0ZB
QP9FQ0H/RkNB/0ZEQ/9GRUT/SUFD/0hDQv9NQ0D/SEVD/0lEQ/9LRUL/TEZD/09HQf9IRUT/SUVE/0pH
Rf9OSEL/SUhG/0pIR/9LSEb/TUlH/09JRv9OSkf/SUVN/0pJSP9NSEv/TEpJ/05KSP9PTEj/T0tO/1NL
Q/9SSUb/WU9G/1BMSv9TTUn/U05J/1ZNSP9cVUv/XFBM/15WT/9LQVL/UEdQ/1BMU/9SS1X/W1NS/1tV
Uf9aVlH/YVtV/2BdW/9kXlr/YF5c/2VgWv9jYl3/ZGFd/2VhXP9nYV3/ZmJf/2diXP9pYV//aGJe/2ll
Yv9oZmP/aWZl/2pnZP9qaGb/bGlo/2xqaP9ta2n/b2xs/3Rtav93b2j/cG5s/3Jvbv95cGz/fXZv/3Nu
cf9xcnD/cnNz/3Rycv91cnD/dXV1/3V0ev92dHr/gXhw/4V7cv+Fgnv/TUqf/1JOr/9fWqL/REO//1NW
u/9cWrr/Y2Sp/z48xf+FgYb/i4KB/5CIhv+Iipv/ioif/5WVlf+WlJT/l5WU/5aXlf+Xlpb/mpWS/5iW
lf+Zl5f/l5iW/5iYl/+dmpX/mZiY/5+bmf+imZH/o5uW/6WclP+noJr/pqGd/6ujnf+tpqD/rKij/66u
rv+xqaP/ta6o/7iwrP+0tLT/tra2/7u0sP+/t7T/wLq2/8O+t//Fvbj/xL+4/8W+uP/Gvrn/yb+8/8fA
uv/Iwbv/yMG+/8nAvf/LxMD/zsnA/9DMyP/Sz8v/087K/9PQzf/W0s//19LO/9rV0v/b1tH/49zY/+ff
2//i2tz/5uDd/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAA
AP8AAAD/s6Ceop6ipaCipqKipJ+fsxYeIiosO0NVTUg9Li0lJRlWq6ywtLa6wMS7ubWxrq1cecrJy8zO
0NHT0s/NyMfGb4sLBAYGCnZsamARFRczV4yIAQdNAANpaGhajZ2ZnB6JhwUOGAIMsq+QqpOVl5YsioMZ
OQ4/CKijm5qRmJKUL4Z/HA0NKwk1NDYoUlhUZUGCfVNdS0obZmRjQBASExRFfnlMUV4dI2JhX0cxNzgy
Rn16VT48JidhW1lCIB8XIVB7d4Bwc3Fyj46FgW50dXaEeGvBvL+/vcPCwMK/wMC+xW06RENERElERElJ
REREQ0E5t6SppaWkpaWkpKWlpaeguP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAA=
</value>
</data>
</root>

View File

@ -5,12 +5,12 @@ using System.Text.RegularExpressions;
using System.Windows.Forms;
using BizHawk.Emulation.Common;
using BizHawk.Emulation.Common.IEmulatorExtensions;
using BizHawk.Emulation.Cores.Nintendo.SNES;
using BizHawk.Client.Common;
namespace BizHawk.Client.EmuHawk
{
[ToolAttributes(false, null)]
public partial class SNESGameGenie : Form, IToolFormAutoConfig
{
[RequiredService]

View File

@ -187,6 +187,7 @@ namespace BizHawk.Client.EmuHawk
Markers.Add(new TasMovieMarker(markerFrame, ""));
UpdateValues();
}
Tastudio.RefreshDialog();
}
public void EditMarkerPopUp(TasMovieMarker marker)

View File

@ -82,6 +82,7 @@ namespace BizHawk.Client.EmuHawk
this.ConfigSubMenu = new System.Windows.Forms.ToolStripMenuItem();
this.SetMaxUndoLevelsMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SetBranchCellHoverIntervalMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SetSeekingCutoffIntervalMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator();
this.AutoadjustInputMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
@ -241,7 +242,7 @@ namespace BizHawk.Client.EmuHawk
//
this.NewTASMenuItem.Name = "NewTASMenuItem";
this.NewTASMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
this.NewTASMenuItem.Size = new System.Drawing.Size(190, 22);
this.NewTASMenuItem.Size = new System.Drawing.Size(201, 22);
this.NewTASMenuItem.Text = "&New";
this.NewTASMenuItem.Click += new System.EventHandler(this.NewTasMenuItem_Click);
//
@ -251,21 +252,21 @@ namespace BizHawk.Client.EmuHawk
this.NewFromNowMenuItem,
this.NewFromCurrentSaveRamMenuItem});
this.NewFromSubMenu.Name = "NewFromSubMenu";
this.NewFromSubMenu.Size = new System.Drawing.Size(190, 22);
this.NewFromSubMenu.Size = new System.Drawing.Size(201, 22);
this.NewFromSubMenu.Text = "New From";
this.NewFromSubMenu.DropDownOpened += new System.EventHandler(this.NewFromSubMenu_DropDownOpened);
//
// NewFromNowMenuItem
//
this.NewFromNowMenuItem.Name = "NewFromNowMenuItem";
this.NewFromNowMenuItem.Size = new System.Drawing.Size(159, 22);
this.NewFromNowMenuItem.Size = new System.Drawing.Size(170, 22);
this.NewFromNowMenuItem.Text = "&Now";
this.NewFromNowMenuItem.Click += new System.EventHandler(this.StartNewProjectFromNowMenuItem_Click);
//
// NewFromCurrentSaveRamMenuItem
//
this.NewFromCurrentSaveRamMenuItem.Name = "NewFromCurrentSaveRamMenuItem";
this.NewFromCurrentSaveRamMenuItem.Size = new System.Drawing.Size(159, 22);
this.NewFromCurrentSaveRamMenuItem.Size = new System.Drawing.Size(170, 22);
this.NewFromCurrentSaveRamMenuItem.Text = "&Current SaveRam";
this.NewFromCurrentSaveRamMenuItem.Click += new System.EventHandler(this.StartANewProjectFromSaveRamMenuItem_Click);
//
@ -273,7 +274,7 @@ namespace BizHawk.Client.EmuHawk
//
this.OpenTASMenuItem.Name = "OpenTASMenuItem";
this.OpenTASMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
this.OpenTASMenuItem.Size = new System.Drawing.Size(190, 22);
this.OpenTASMenuItem.Size = new System.Drawing.Size(201, 22);
this.OpenTASMenuItem.Text = "&Open";
this.OpenTASMenuItem.Click += new System.EventHandler(this.OpenTasMenuItem_Click);
//
@ -281,7 +282,7 @@ namespace BizHawk.Client.EmuHawk
//
this.SaveTASMenuItem.Name = "SaveTASMenuItem";
this.SaveTASMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
this.SaveTASMenuItem.Size = new System.Drawing.Size(190, 22);
this.SaveTASMenuItem.Size = new System.Drawing.Size(201, 22);
this.SaveTASMenuItem.Text = "&Save";
this.SaveTASMenuItem.Click += new System.EventHandler(this.SaveTasMenuItem_Click);
//
@ -290,7 +291,7 @@ namespace BizHawk.Client.EmuHawk
this.SaveAsTASMenuItem.Name = "SaveAsTASMenuItem";
this.SaveAsTASMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.S)));
this.SaveAsTASMenuItem.Size = new System.Drawing.Size(190, 22);
this.SaveAsTASMenuItem.Size = new System.Drawing.Size(201, 22);
this.SaveAsTASMenuItem.Text = "Save As";
this.SaveAsTASMenuItem.Click += new System.EventHandler(this.SaveAsTasMenuItem_Click);
//
@ -300,7 +301,7 @@ namespace BizHawk.Client.EmuHawk
this.toolStripSeparator3});
this.RecentSubMenu.Image = ((System.Drawing.Image)(resources.GetObject("RecentSubMenu.Image")));
this.RecentSubMenu.Name = "RecentSubMenu";
this.RecentSubMenu.Size = new System.Drawing.Size(190, 22);
this.RecentSubMenu.Size = new System.Drawing.Size(201, 22);
this.RecentSubMenu.Text = "Recent";
this.RecentSubMenu.DropDownOpened += new System.EventHandler(this.RecentSubMenu_DropDownOpened);
//
@ -312,19 +313,19 @@ namespace BizHawk.Client.EmuHawk
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(187, 6);
this.toolStripSeparator1.Size = new System.Drawing.Size(198, 6);
//
// saveSelectionToMacroToolStripMenuItem
//
this.saveSelectionToMacroToolStripMenuItem.Name = "saveSelectionToMacroToolStripMenuItem";
this.saveSelectionToMacroToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
this.saveSelectionToMacroToolStripMenuItem.Size = new System.Drawing.Size(201, 22);
this.saveSelectionToMacroToolStripMenuItem.Text = "Save Selection to Macro";
this.saveSelectionToMacroToolStripMenuItem.Click += new System.EventHandler(this.saveSelectionToMacroToolStripMenuItem_Click);
//
// placeMacroAtSelectionToolStripMenuItem
//
this.placeMacroAtSelectionToolStripMenuItem.Name = "placeMacroAtSelectionToolStripMenuItem";
this.placeMacroAtSelectionToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
this.placeMacroAtSelectionToolStripMenuItem.Size = new System.Drawing.Size(201, 22);
this.placeMacroAtSelectionToolStripMenuItem.Text = "Place Macro at Selection";
this.placeMacroAtSelectionToolStripMenuItem.Click += new System.EventHandler(this.placeMacroAtSelectionToolStripMenuItem_Click);
//
@ -334,7 +335,7 @@ namespace BizHawk.Client.EmuHawk
this.toolStripSeparator22});
this.recentMacrosToolStripMenuItem.Image = global::BizHawk.Client.EmuHawk.Properties.Resources.Recent;
this.recentMacrosToolStripMenuItem.Name = "recentMacrosToolStripMenuItem";
this.recentMacrosToolStripMenuItem.Size = new System.Drawing.Size(190, 22);
this.recentMacrosToolStripMenuItem.Size = new System.Drawing.Size(201, 22);
this.recentMacrosToolStripMenuItem.Text = "Recent Macros";
this.recentMacrosToolStripMenuItem.DropDownOpened += new System.EventHandler(this.recentMacrosToolStripMenuItem_DropDownOpened);
//
@ -346,25 +347,25 @@ namespace BizHawk.Client.EmuHawk
// toolStripSeparator20
//
this.toolStripSeparator20.Name = "toolStripSeparator20";
this.toolStripSeparator20.Size = new System.Drawing.Size(187, 6);
this.toolStripSeparator20.Size = new System.Drawing.Size(198, 6);
//
// ToBk2MenuItem
//
this.ToBk2MenuItem.Name = "ToBk2MenuItem";
this.ToBk2MenuItem.Size = new System.Drawing.Size(190, 22);
this.ToBk2MenuItem.Size = new System.Drawing.Size(201, 22);
this.ToBk2MenuItem.Text = "&Export to Bk2";
this.ToBk2MenuItem.Click += new System.EventHandler(this.ToBk2MenuItem_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(187, 6);
this.toolStripSeparator2.Size = new System.Drawing.Size(198, 6);
//
// ExitMenuItem
//
this.ExitMenuItem.Name = "ExitMenuItem";
this.ExitMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4)));
this.ExitMenuItem.Size = new System.Drawing.Size(190, 22);
this.ExitMenuItem.Size = new System.Drawing.Size(201, 22);
this.ExitMenuItem.Text = "E&xit";
this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click);
//
@ -406,7 +407,7 @@ namespace BizHawk.Client.EmuHawk
//
this.UndoMenuItem.Name = "UndoMenuItem";
this.UndoMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z)));
this.UndoMenuItem.Size = new System.Drawing.Size(280, 22);
this.UndoMenuItem.Size = new System.Drawing.Size(291, 22);
this.UndoMenuItem.Text = "&Undo";
this.UndoMenuItem.Click += new System.EventHandler(this.UndoMenuItem_Click);
//
@ -415,14 +416,14 @@ namespace BizHawk.Client.EmuHawk
this.RedoMenuItem.Enabled = false;
this.RedoMenuItem.Name = "RedoMenuItem";
this.RedoMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y)));
this.RedoMenuItem.Size = new System.Drawing.Size(280, 22);
this.RedoMenuItem.Size = new System.Drawing.Size(291, 22);
this.RedoMenuItem.Text = "&Redo";
this.RedoMenuItem.Click += new System.EventHandler(this.RedoMenuItem_Click);
//
// showUndoHistoryToolStripMenuItem
//
this.showUndoHistoryToolStripMenuItem.Name = "showUndoHistoryToolStripMenuItem";
this.showUndoHistoryToolStripMenuItem.Size = new System.Drawing.Size(280, 22);
this.showUndoHistoryToolStripMenuItem.Size = new System.Drawing.Size(291, 22);
this.showUndoHistoryToolStripMenuItem.Text = "Show Undo History";
this.showUndoHistoryToolStripMenuItem.Click += new System.EventHandler(this.showUndoHistoryToolStripMenuItem_Click);
//
@ -431,7 +432,7 @@ namespace BizHawk.Client.EmuHawk
this.SelectionUndoMenuItem.Enabled = false;
this.SelectionUndoMenuItem.Name = "SelectionUndoMenuItem";
this.SelectionUndoMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Q)));
this.SelectionUndoMenuItem.Size = new System.Drawing.Size(280, 22);
this.SelectionUndoMenuItem.Size = new System.Drawing.Size(291, 22);
this.SelectionUndoMenuItem.Text = "Selection Undo";
//
// SelectionRedoMenuItem
@ -439,18 +440,18 @@ namespace BizHawk.Client.EmuHawk
this.SelectionRedoMenuItem.Enabled = false;
this.SelectionRedoMenuItem.Name = "SelectionRedoMenuItem";
this.SelectionRedoMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.W)));
this.SelectionRedoMenuItem.Size = new System.Drawing.Size(280, 22);
this.SelectionRedoMenuItem.Size = new System.Drawing.Size(291, 22);
this.SelectionRedoMenuItem.Text = "Selection Redo";
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
this.toolStripSeparator5.Size = new System.Drawing.Size(277, 6);
this.toolStripSeparator5.Size = new System.Drawing.Size(288, 6);
//
// DeselectMenuItem
//
this.DeselectMenuItem.Name = "DeselectMenuItem";
this.DeselectMenuItem.Size = new System.Drawing.Size(280, 22);
this.DeselectMenuItem.Size = new System.Drawing.Size(291, 22);
this.DeselectMenuItem.Text = "Deselect";
this.DeselectMenuItem.Click += new System.EventHandler(this.DeselectMenuItem_Click);
//
@ -458,7 +459,7 @@ namespace BizHawk.Client.EmuHawk
//
this.SelectBetweenMarkersMenuItem.Name = "SelectBetweenMarkersMenuItem";
this.SelectBetweenMarkersMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
this.SelectBetweenMarkersMenuItem.Size = new System.Drawing.Size(280, 22);
this.SelectBetweenMarkersMenuItem.Size = new System.Drawing.Size(291, 22);
this.SelectBetweenMarkersMenuItem.Text = "Select between Markers";
this.SelectBetweenMarkersMenuItem.Click += new System.EventHandler(this.SelectBetweenMarkersMenuItem_Click);
//
@ -468,7 +469,7 @@ namespace BizHawk.Client.EmuHawk
this.SelectAllMenuItem.ShortcutKeyDisplayString = "";
this.SelectAllMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.A)));
this.SelectAllMenuItem.Size = new System.Drawing.Size(280, 22);
this.SelectAllMenuItem.Size = new System.Drawing.Size(291, 22);
this.SelectAllMenuItem.Text = "Select &All";
this.SelectAllMenuItem.Click += new System.EventHandler(this.SelectAllMenuItem_Click);
//
@ -476,20 +477,20 @@ namespace BizHawk.Client.EmuHawk
//
this.ReselectClipboardMenuItem.Name = "ReselectClipboardMenuItem";
this.ReselectClipboardMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.B)));
this.ReselectClipboardMenuItem.Size = new System.Drawing.Size(280, 22);
this.ReselectClipboardMenuItem.Size = new System.Drawing.Size(291, 22);
this.ReselectClipboardMenuItem.Text = "Reselect Clipboard";
this.ReselectClipboardMenuItem.Click += new System.EventHandler(this.ReselectClipboardMenuItem_Click);
//
// toolStripSeparator7
//
this.toolStripSeparator7.Name = "toolStripSeparator7";
this.toolStripSeparator7.Size = new System.Drawing.Size(277, 6);
this.toolStripSeparator7.Size = new System.Drawing.Size(288, 6);
//
// CopyMenuItem
//
this.CopyMenuItem.Name = "CopyMenuItem";
this.CopyMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
this.CopyMenuItem.Size = new System.Drawing.Size(280, 22);
this.CopyMenuItem.Size = new System.Drawing.Size(291, 22);
this.CopyMenuItem.Text = "Copy";
this.CopyMenuItem.Click += new System.EventHandler(this.CopyMenuItem_Click);
//
@ -497,7 +498,7 @@ namespace BizHawk.Client.EmuHawk
//
this.PasteMenuItem.Name = "PasteMenuItem";
this.PasteMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V)));
this.PasteMenuItem.Size = new System.Drawing.Size(280, 22);
this.PasteMenuItem.Size = new System.Drawing.Size(291, 22);
this.PasteMenuItem.Text = "&Paste";
this.PasteMenuItem.Click += new System.EventHandler(this.PasteMenuItem_Click);
//
@ -506,7 +507,7 @@ namespace BizHawk.Client.EmuHawk
this.PasteInsertMenuItem.Name = "PasteInsertMenuItem";
this.PasteInsertMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.V)));
this.PasteInsertMenuItem.Size = new System.Drawing.Size(280, 22);
this.PasteInsertMenuItem.Size = new System.Drawing.Size(291, 22);
this.PasteInsertMenuItem.Text = "&Paste Insert";
this.PasteInsertMenuItem.Click += new System.EventHandler(this.PasteInsertMenuItem_Click);
//
@ -514,21 +515,21 @@ namespace BizHawk.Client.EmuHawk
//
this.CutMenuItem.Name = "CutMenuItem";
this.CutMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X)));
this.CutMenuItem.Size = new System.Drawing.Size(280, 22);
this.CutMenuItem.Size = new System.Drawing.Size(291, 22);
this.CutMenuItem.Text = "&Cut";
this.CutMenuItem.Click += new System.EventHandler(this.CutMenuItem_Click);
//
// toolStripSeparator8
//
this.toolStripSeparator8.Name = "toolStripSeparator8";
this.toolStripSeparator8.Size = new System.Drawing.Size(277, 6);
this.toolStripSeparator8.Size = new System.Drawing.Size(288, 6);
//
// ClearMenuItem
//
this.ClearMenuItem.Name = "ClearMenuItem";
this.ClearMenuItem.ShortcutKeyDisplayString = "";
this.ClearMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Delete;
this.ClearMenuItem.Size = new System.Drawing.Size(280, 22);
this.ClearMenuItem.Size = new System.Drawing.Size(291, 22);
this.ClearMenuItem.Text = "Clear";
this.ClearMenuItem.Click += new System.EventHandler(this.ClearMenuItem_Click);
//
@ -536,7 +537,7 @@ namespace BizHawk.Client.EmuHawk
//
this.InsertFrameMenuItem.Name = "InsertFrameMenuItem";
this.InsertFrameMenuItem.ShortcutKeys = System.Windows.Forms.Keys.Insert;
this.InsertFrameMenuItem.Size = new System.Drawing.Size(280, 22);
this.InsertFrameMenuItem.Size = new System.Drawing.Size(291, 22);
this.InsertFrameMenuItem.Text = "&Insert";
this.InsertFrameMenuItem.Click += new System.EventHandler(this.InsertFrameMenuItem_Click);
//
@ -544,7 +545,7 @@ namespace BizHawk.Client.EmuHawk
//
this.DeleteFramesMenuItem.Name = "DeleteFramesMenuItem";
this.DeleteFramesMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Delete)));
this.DeleteFramesMenuItem.Size = new System.Drawing.Size(280, 22);
this.DeleteFramesMenuItem.Size = new System.Drawing.Size(291, 22);
this.DeleteFramesMenuItem.Text = "&Delete";
this.DeleteFramesMenuItem.Click += new System.EventHandler(this.DeleteFramesMenuItem_Click);
//
@ -552,7 +553,7 @@ namespace BizHawk.Client.EmuHawk
//
this.CloneMenuItem.Name = "CloneMenuItem";
this.CloneMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Insert)));
this.CloneMenuItem.Size = new System.Drawing.Size(280, 22);
this.CloneMenuItem.Size = new System.Drawing.Size(291, 22);
this.CloneMenuItem.Text = "&Clone";
this.CloneMenuItem.Click += new System.EventHandler(this.CloneMenuItem_Click);
//
@ -562,40 +563,40 @@ namespace BizHawk.Client.EmuHawk
this.InsertNumFramesMenuItem.ShortcutKeyDisplayString = "";
this.InsertNumFramesMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.Insert)));
this.InsertNumFramesMenuItem.Size = new System.Drawing.Size(280, 22);
this.InsertNumFramesMenuItem.Size = new System.Drawing.Size(291, 22);
this.InsertNumFramesMenuItem.Text = "Insert # of Frames";
this.InsertNumFramesMenuItem.Click += new System.EventHandler(this.InsertNumFramesMenuItem_Click);
//
// toolStripSeparator6
//
this.toolStripSeparator6.Name = "toolStripSeparator6";
this.toolStripSeparator6.Size = new System.Drawing.Size(277, 6);
this.toolStripSeparator6.Size = new System.Drawing.Size(288, 6);
//
// TruncateMenuItem
//
this.TruncateMenuItem.Name = "TruncateMenuItem";
this.TruncateMenuItem.Size = new System.Drawing.Size(280, 22);
this.TruncateMenuItem.Size = new System.Drawing.Size(291, 22);
this.TruncateMenuItem.Text = "&Truncate Movie";
this.TruncateMenuItem.Click += new System.EventHandler(this.TruncateMenuItem_Click);
//
// ClearGreenzoneMenuItem
//
this.ClearGreenzoneMenuItem.Name = "ClearGreenzoneMenuItem";
this.ClearGreenzoneMenuItem.Size = new System.Drawing.Size(280, 22);
this.ClearGreenzoneMenuItem.Size = new System.Drawing.Size(291, 22);
this.ClearGreenzoneMenuItem.Text = "&Clear Savestate History";
this.ClearGreenzoneMenuItem.Click += new System.EventHandler(this.ClearGreenzoneMenuItem_Click);
//
// GreenzoneICheckSeparator
//
this.GreenzoneICheckSeparator.Name = "GreenzoneICheckSeparator";
this.GreenzoneICheckSeparator.Size = new System.Drawing.Size(277, 6);
this.GreenzoneICheckSeparator.Size = new System.Drawing.Size(288, 6);
//
// StateHistoryIntegrityCheckMenuItem
//
this.StateHistoryIntegrityCheckMenuItem.Name = "StateHistoryIntegrityCheckMenuItem";
this.StateHistoryIntegrityCheckMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.I)));
this.StateHistoryIntegrityCheckMenuItem.Size = new System.Drawing.Size(280, 22);
this.StateHistoryIntegrityCheckMenuItem.Size = new System.Drawing.Size(291, 22);
this.StateHistoryIntegrityCheckMenuItem.Text = "State History Integrity Check";
this.StateHistoryIntegrityCheckMenuItem.Click += new System.EventHandler(this.StateHistoryIntegrityCheckMenuItem_Click);
//
@ -604,6 +605,7 @@ namespace BizHawk.Client.EmuHawk
this.ConfigSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.SetMaxUndoLevelsMenuItem,
this.SetBranchCellHoverIntervalMenuItem,
this.SetSeekingCutoffIntervalMenuItem,
this.toolStripSeparator9,
this.AutoadjustInputMenuItem,
this.toolStripSeparator11,
@ -629,38 +631,45 @@ namespace BizHawk.Client.EmuHawk
// SetMaxUndoLevelsMenuItem
//
this.SetMaxUndoLevelsMenuItem.Name = "SetMaxUndoLevelsMenuItem";
this.SetMaxUndoLevelsMenuItem.Size = new System.Drawing.Size(242, 22);
this.SetMaxUndoLevelsMenuItem.Size = new System.Drawing.Size(253, 22);
this.SetMaxUndoLevelsMenuItem.Text = "Set max Undo Levels";
this.SetMaxUndoLevelsMenuItem.Click += new System.EventHandler(this.SetMaxUndoLevelsMenuItem_Click);
//
// SetBranchCellHoverIntervalMenuItem
//
this.SetBranchCellHoverIntervalMenuItem.Name = "SetBranchCellHoverIntervalMenuItem";
this.SetBranchCellHoverIntervalMenuItem.Size = new System.Drawing.Size(242, 22);
this.SetBranchCellHoverIntervalMenuItem.Size = new System.Drawing.Size(253, 22);
this.SetBranchCellHoverIntervalMenuItem.Text = "Set Branch Cell Hover Interval";
this.SetBranchCellHoverIntervalMenuItem.Click += new System.EventHandler(this.SetBranchCellHoverIntervalMenuItem_Click);
//
// SetSeekingCutoffIntervalMenuItem
//
this.SetSeekingCutoffIntervalMenuItem.Name = "SetSeekingCutoffIntervalMenuItem";
this.SetSeekingCutoffIntervalMenuItem.Size = new System.Drawing.Size(253, 22);
this.SetSeekingCutoffIntervalMenuItem.Text = "Set Seeking Cutoff Interval";
this.SetSeekingCutoffIntervalMenuItem.Click += new System.EventHandler(this.SetSeekingCutoffIntervalMenuItem_Click);
//
// toolStripSeparator9
//
this.toolStripSeparator9.Name = "toolStripSeparator9";
this.toolStripSeparator9.Size = new System.Drawing.Size(239, 6);
this.toolStripSeparator9.Size = new System.Drawing.Size(250, 6);
//
// AutoadjustInputMenuItem
//
this.AutoadjustInputMenuItem.CheckOnClick = true;
this.AutoadjustInputMenuItem.Name = "AutoadjustInputMenuItem";
this.AutoadjustInputMenuItem.Size = new System.Drawing.Size(242, 22);
this.AutoadjustInputMenuItem.Size = new System.Drawing.Size(253, 22);
this.AutoadjustInputMenuItem.Text = "Auto-adjust Input according to Lag";
//
// toolStripSeparator11
//
this.toolStripSeparator11.Name = "toolStripSeparator11";
this.toolStripSeparator11.Size = new System.Drawing.Size(239, 6);
this.toolStripSeparator11.Size = new System.Drawing.Size(250, 6);
//
// DrawInputByDraggingMenuItem
//
this.DrawInputByDraggingMenuItem.Name = "DrawInputByDraggingMenuItem";
this.DrawInputByDraggingMenuItem.Size = new System.Drawing.Size(242, 22);
this.DrawInputByDraggingMenuItem.Size = new System.Drawing.Size(253, 22);
this.DrawInputByDraggingMenuItem.Text = "Draw Input by dragging";
this.DrawInputByDraggingMenuItem.Click += new System.EventHandler(this.DrawInputByDraggingMenuItem_Click);
//
@ -668,7 +677,7 @@ namespace BizHawk.Client.EmuHawk
//
this.applyPatternToPaintedInputToolStripMenuItem.CheckOnClick = true;
this.applyPatternToPaintedInputToolStripMenuItem.Name = "applyPatternToPaintedInputToolStripMenuItem";
this.applyPatternToPaintedInputToolStripMenuItem.Size = new System.Drawing.Size(242, 22);
this.applyPatternToPaintedInputToolStripMenuItem.Size = new System.Drawing.Size(253, 22);
this.applyPatternToPaintedInputToolStripMenuItem.Text = "Apply Pattern to painted input";
this.applyPatternToPaintedInputToolStripMenuItem.CheckedChanged += new System.EventHandler(this.applyPatternToPaintedInputToolStripMenuItem_CheckedChanged);
//
@ -679,20 +688,20 @@ namespace BizHawk.Client.EmuHawk
this.onlyOnAutoFireColumnsToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.onlyOnAutoFireColumnsToolStripMenuItem.Enabled = false;
this.onlyOnAutoFireColumnsToolStripMenuItem.Name = "onlyOnAutoFireColumnsToolStripMenuItem";
this.onlyOnAutoFireColumnsToolStripMenuItem.Size = new System.Drawing.Size(242, 22);
this.onlyOnAutoFireColumnsToolStripMenuItem.Size = new System.Drawing.Size(253, 22);
this.onlyOnAutoFireColumnsToolStripMenuItem.Text = "Only on Auto-Fire columns";
//
// UseInputKeysItem
//
this.UseInputKeysItem.Enabled = false;
this.UseInputKeysItem.Name = "UseInputKeysItem";
this.UseInputKeysItem.Size = new System.Drawing.Size(242, 22);
this.UseInputKeysItem.Size = new System.Drawing.Size(253, 22);
this.UseInputKeysItem.Text = "Use Input keys for Column Set";
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
this.toolStripSeparator4.Size = new System.Drawing.Size(239, 6);
this.toolStripSeparator4.Size = new System.Drawing.Size(250, 6);
//
// BindMarkersToInputMenuItem
//
@ -700,52 +709,52 @@ namespace BizHawk.Client.EmuHawk
this.BindMarkersToInputMenuItem.CheckOnClick = true;
this.BindMarkersToInputMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.BindMarkersToInputMenuItem.Name = "BindMarkersToInputMenuItem";
this.BindMarkersToInputMenuItem.Size = new System.Drawing.Size(242, 22);
this.BindMarkersToInputMenuItem.Size = new System.Drawing.Size(253, 22);
this.BindMarkersToInputMenuItem.Text = "Bind Markers to Input";
this.BindMarkersToInputMenuItem.Click += new System.EventHandler(this.BindMarkersToInputMenuItem_Click);
//
// EmptyNewMarkerNotesMenuItem
//
this.EmptyNewMarkerNotesMenuItem.Name = "EmptyNewMarkerNotesMenuItem";
this.EmptyNewMarkerNotesMenuItem.Size = new System.Drawing.Size(242, 22);
this.EmptyNewMarkerNotesMenuItem.Size = new System.Drawing.Size(253, 22);
this.EmptyNewMarkerNotesMenuItem.Text = "Empty new Marker Notes";
this.EmptyNewMarkerNotesMenuItem.Click += new System.EventHandler(this.EmptyNewMarkerNotesMenuItem_Click);
//
// toolStripSeparator13
//
this.toolStripSeparator13.Name = "toolStripSeparator13";
this.toolStripSeparator13.Size = new System.Drawing.Size(239, 6);
this.toolStripSeparator13.Size = new System.Drawing.Size(250, 6);
//
// BranchesRestoreEntireMovieMenuItem
//
this.BranchesRestoreEntireMovieMenuItem.Enabled = false;
this.BranchesRestoreEntireMovieMenuItem.Name = "BranchesRestoreEntireMovieMenuItem";
this.BranchesRestoreEntireMovieMenuItem.Size = new System.Drawing.Size(242, 22);
this.BranchesRestoreEntireMovieMenuItem.Size = new System.Drawing.Size(253, 22);
this.BranchesRestoreEntireMovieMenuItem.Text = "Branches restore entire Movie";
//
// OsdInBranchScreenshotsMenuItem
//
this.OsdInBranchScreenshotsMenuItem.Enabled = false;
this.OsdInBranchScreenshotsMenuItem.Name = "OsdInBranchScreenshotsMenuItem";
this.OsdInBranchScreenshotsMenuItem.Size = new System.Drawing.Size(242, 22);
this.OsdInBranchScreenshotsMenuItem.Size = new System.Drawing.Size(253, 22);
this.OsdInBranchScreenshotsMenuItem.Text = "OSD in Branch screenshots";
//
// toolStripSeparator14
//
this.toolStripSeparator14.Name = "toolStripSeparator14";
this.toolStripSeparator14.Size = new System.Drawing.Size(239, 6);
this.toolStripSeparator14.Size = new System.Drawing.Size(250, 6);
//
// AutopauseAtEndOfMovieMenuItem
//
this.AutopauseAtEndOfMovieMenuItem.Name = "AutopauseAtEndOfMovieMenuItem";
this.AutopauseAtEndOfMovieMenuItem.Size = new System.Drawing.Size(242, 22);
this.AutopauseAtEndOfMovieMenuItem.Size = new System.Drawing.Size(253, 22);
this.AutopauseAtEndOfMovieMenuItem.Text = "Autopause at end of Movie";
this.AutopauseAtEndOfMovieMenuItem.Click += new System.EventHandler(this.AutopauseAtEndMenuItem_Click);
//
// sepToolStripMenuItem
//
this.sepToolStripMenuItem.Name = "sepToolStripMenuItem";
this.sepToolStripMenuItem.Size = new System.Drawing.Size(239, 6);
this.sepToolStripMenuItem.Size = new System.Drawing.Size(250, 6);
//
// autoHoldFireToolStripMenuItem
//
@ -758,20 +767,20 @@ namespace BizHawk.Client.EmuHawk
this.setpToolStripMenuItem,
this.setCustomsToolStripMenuItem});
this.autoHoldFireToolStripMenuItem.Name = "autoHoldFireToolStripMenuItem";
this.autoHoldFireToolStripMenuItem.Size = new System.Drawing.Size(242, 22);
this.autoHoldFireToolStripMenuItem.Size = new System.Drawing.Size(253, 22);
this.autoHoldFireToolStripMenuItem.Text = "Auto Hold/Fire";
//
// keepSetPatternsToolStripMenuItem
//
this.keepSetPatternsToolStripMenuItem.CheckOnClick = true;
this.keepSetPatternsToolStripMenuItem.Name = "keepSetPatternsToolStripMenuItem";
this.keepSetPatternsToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.keepSetPatternsToolStripMenuItem.Size = new System.Drawing.Size(171, 22);
this.keepSetPatternsToolStripMenuItem.Text = "Keep set patterns";
//
// sepToolStripMenuItem1
//
this.sepToolStripMenuItem1.Name = "sepToolStripMenuItem1";
this.sepToolStripMenuItem1.Size = new System.Drawing.Size(157, 6);
this.sepToolStripMenuItem1.Size = new System.Drawing.Size(168, 6);
//
// autoHoldToolStripMenuItem
//
@ -779,7 +788,7 @@ namespace BizHawk.Client.EmuHawk
this.autoHoldToolStripMenuItem.CheckOnClick = true;
this.autoHoldToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.autoHoldToolStripMenuItem.Name = "autoHoldToolStripMenuItem";
this.autoHoldToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.autoHoldToolStripMenuItem.Size = new System.Drawing.Size(171, 22);
this.autoHoldToolStripMenuItem.Text = "Auto-Hold";
this.autoHoldToolStripMenuItem.CheckedChanged += new System.EventHandler(this.autoHoldToolStripMenuItem_CheckedChanged);
//
@ -787,7 +796,7 @@ namespace BizHawk.Client.EmuHawk
//
this.autoFireToolStripMenuItem.CheckOnClick = true;
this.autoFireToolStripMenuItem.Name = "autoFireToolStripMenuItem";
this.autoFireToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.autoFireToolStripMenuItem.Size = new System.Drawing.Size(171, 22);
this.autoFireToolStripMenuItem.Text = "Auto-Fire";
this.autoFireToolStripMenuItem.CheckedChanged += new System.EventHandler(this.autoFireToolStripMenuItem_CheckedChanged);
//
@ -795,19 +804,19 @@ namespace BizHawk.Client.EmuHawk
//
this.customPatternToolStripMenuItem.CheckOnClick = true;
this.customPatternToolStripMenuItem.Name = "customPatternToolStripMenuItem";
this.customPatternToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.customPatternToolStripMenuItem.Size = new System.Drawing.Size(171, 22);
this.customPatternToolStripMenuItem.Text = "Custom Pattern";
this.customPatternToolStripMenuItem.CheckedChanged += new System.EventHandler(this.customPatternToolStripMenuItem_CheckedChanged);
//
// setpToolStripMenuItem
//
this.setpToolStripMenuItem.Name = "setpToolStripMenuItem";
this.setpToolStripMenuItem.Size = new System.Drawing.Size(157, 6);
this.setpToolStripMenuItem.Size = new System.Drawing.Size(168, 6);
//
// setCustomsToolStripMenuItem
//
this.setCustomsToolStripMenuItem.Name = "setCustomsToolStripMenuItem";
this.setCustomsToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.setCustomsToolStripMenuItem.Size = new System.Drawing.Size(171, 22);
this.setCustomsToolStripMenuItem.Text = "Set Customs...";
this.setCustomsToolStripMenuItem.Click += new System.EventHandler(this.setCustomsToolStripMenuItem_Click);
//
@ -827,40 +836,40 @@ namespace BizHawk.Client.EmuHawk
// HeaderMenuItem
//
this.HeaderMenuItem.Name = "HeaderMenuItem";
this.HeaderMenuItem.Size = new System.Drawing.Size(229, 22);
this.HeaderMenuItem.Size = new System.Drawing.Size(240, 22);
this.HeaderMenuItem.Text = "&Header...";
this.HeaderMenuItem.Click += new System.EventHandler(this.HeaderMenuItem_Click);
//
// StateHistorySettingsMenuItem
//
this.StateHistorySettingsMenuItem.Name = "StateHistorySettingsMenuItem";
this.StateHistorySettingsMenuItem.Size = new System.Drawing.Size(229, 22);
this.StateHistorySettingsMenuItem.Size = new System.Drawing.Size(240, 22);
this.StateHistorySettingsMenuItem.Text = "&Savestate History Settings...";
this.StateHistorySettingsMenuItem.Click += new System.EventHandler(this.StateHistorySettingsMenuItem_Click);
//
// CommentsMenuItem
//
this.CommentsMenuItem.Name = "CommentsMenuItem";
this.CommentsMenuItem.Size = new System.Drawing.Size(229, 22);
this.CommentsMenuItem.Size = new System.Drawing.Size(240, 22);
this.CommentsMenuItem.Text = "&Comments...";
this.CommentsMenuItem.Click += new System.EventHandler(this.CommentsMenuItem_Click);
//
// SubtitlesMenuItem
//
this.SubtitlesMenuItem.Name = "SubtitlesMenuItem";
this.SubtitlesMenuItem.Size = new System.Drawing.Size(229, 22);
this.SubtitlesMenuItem.Size = new System.Drawing.Size(240, 22);
this.SubtitlesMenuItem.Text = "&Subtitles...";
this.SubtitlesMenuItem.Click += new System.EventHandler(this.SubtitlesMenuItem_Click);
//
// toolStripSeparator21
//
this.toolStripSeparator21.Name = "toolStripSeparator21";
this.toolStripSeparator21.Size = new System.Drawing.Size(226, 6);
this.toolStripSeparator21.Size = new System.Drawing.Size(237, 6);
//
// DefaultStateSettingsMenuItem
//
this.DefaultStateSettingsMenuItem.Name = "DefaultStateSettingsMenuItem";
this.DefaultStateSettingsMenuItem.Size = new System.Drawing.Size(229, 22);
this.DefaultStateSettingsMenuItem.Size = new System.Drawing.Size(240, 22);
this.DefaultStateSettingsMenuItem.Text = "&Default State History Settings...";
this.DefaultStateSettingsMenuItem.Click += new System.EventHandler(this.DefaultStateSettingsMenuItem_Click);
//
@ -882,7 +891,7 @@ namespace BizHawk.Client.EmuHawk
// RotateMenuItem
//
this.RotateMenuItem.Name = "RotateMenuItem";
this.RotateMenuItem.Size = new System.Drawing.Size(177, 22);
this.RotateMenuItem.Size = new System.Drawing.Size(188, 22);
this.RotateMenuItem.Text = "Rotate";
this.RotateMenuItem.Click += new System.EventHandler(this.RotateMenuItem_Click);
//
@ -896,7 +905,7 @@ namespace BizHawk.Client.EmuHawk
this.toolStripSeparator12,
this.hideWasLagFramesToolStripMenuItem});
this.HideLagFramesSubMenu.Name = "HideLagFramesSubMenu";
this.HideLagFramesSubMenu.Size = new System.Drawing.Size(177, 22);
this.HideLagFramesSubMenu.Size = new System.Drawing.Size(188, 22);
this.HideLagFramesSubMenu.Text = "Hide Lag Frames";
this.HideLagFramesSubMenu.DropDownOpened += new System.EventHandler(this.HideLagFramesSubMenu_DropDownOpened);
//
@ -906,7 +915,7 @@ namespace BizHawk.Client.EmuHawk
this.HideLagFrames0.CheckOnClick = true;
this.HideLagFrames0.CheckState = System.Windows.Forms.CheckState.Checked;
this.HideLagFrames0.Name = "HideLagFrames0";
this.HideLagFrames0.Size = new System.Drawing.Size(174, 22);
this.HideLagFrames0.Size = new System.Drawing.Size(185, 22);
this.HideLagFrames0.Tag = 0;
this.HideLagFrames0.Text = "Don\'t Hide";
this.HideLagFrames0.Click += new System.EventHandler(this.HideLagFramesX_Click);
@ -915,7 +924,7 @@ namespace BizHawk.Client.EmuHawk
//
this.HideLagFrames1.CheckOnClick = true;
this.HideLagFrames1.Name = "HideLagFrames1";
this.HideLagFrames1.Size = new System.Drawing.Size(174, 22);
this.HideLagFrames1.Size = new System.Drawing.Size(185, 22);
this.HideLagFrames1.Tag = 1;
this.HideLagFrames1.Text = "1 (30 fps)";
this.HideLagFrames1.Click += new System.EventHandler(this.HideLagFramesX_Click);
@ -923,7 +932,7 @@ namespace BizHawk.Client.EmuHawk
// HideLagFrames2
//
this.HideLagFrames2.Name = "HideLagFrames2";
this.HideLagFrames2.Size = new System.Drawing.Size(174, 22);
this.HideLagFrames2.Size = new System.Drawing.Size(185, 22);
this.HideLagFrames2.Tag = 2;
this.HideLagFrames2.Text = "2 (20 fps)";
this.HideLagFrames2.Click += new System.EventHandler(this.HideLagFramesX_Click);
@ -932,7 +941,7 @@ namespace BizHawk.Client.EmuHawk
//
this.HideLagFrames3.CheckOnClick = true;
this.HideLagFrames3.Name = "HideLagFrames3";
this.HideLagFrames3.Size = new System.Drawing.Size(174, 22);
this.HideLagFrames3.Size = new System.Drawing.Size(185, 22);
this.HideLagFrames3.Tag = 3;
this.HideLagFrames3.Text = "3 (15fps)";
this.HideLagFrames3.Click += new System.EventHandler(this.HideLagFramesX_Click);
@ -940,13 +949,13 @@ namespace BizHawk.Client.EmuHawk
// toolStripSeparator12
//
this.toolStripSeparator12.Name = "toolStripSeparator12";
this.toolStripSeparator12.Size = new System.Drawing.Size(171, 6);
this.toolStripSeparator12.Size = new System.Drawing.Size(182, 6);
//
// hideWasLagFramesToolStripMenuItem
//
this.hideWasLagFramesToolStripMenuItem.CheckOnClick = true;
this.hideWasLagFramesToolStripMenuItem.Name = "hideWasLagFramesToolStripMenuItem";
this.hideWasLagFramesToolStripMenuItem.Size = new System.Drawing.Size(174, 22);
this.hideWasLagFramesToolStripMenuItem.Size = new System.Drawing.Size(185, 22);
this.hideWasLagFramesToolStripMenuItem.Text = "Hide WasLag Frames";
this.hideWasLagFramesToolStripMenuItem.Click += new System.EventHandler(this.hideWasLagFramesToolStripMenuItem_Click);
//
@ -958,7 +967,7 @@ namespace BizHawk.Client.EmuHawk
this.denoteMarkersWithIconsToolStripMenuItem,
this.denoteMarkersWithBGColorToolStripMenuItem});
this.iconsToolStripMenuItem.Name = "iconsToolStripMenuItem";
this.iconsToolStripMenuItem.Size = new System.Drawing.Size(177, 22);
this.iconsToolStripMenuItem.Size = new System.Drawing.Size(188, 22);
this.iconsToolStripMenuItem.Text = "Icons";
this.iconsToolStripMenuItem.DropDownOpened += new System.EventHandler(this.iconsToolStripMenuItem_DropDownOpened);
//
@ -966,7 +975,7 @@ namespace BizHawk.Client.EmuHawk
//
this.denoteStatesWithIconsToolStripMenuItem.CheckOnClick = true;
this.denoteStatesWithIconsToolStripMenuItem.Name = "denoteStatesWithIconsToolStripMenuItem";
this.denoteStatesWithIconsToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
this.denoteStatesWithIconsToolStripMenuItem.Size = new System.Drawing.Size(230, 22);
this.denoteStatesWithIconsToolStripMenuItem.Text = "Denote States With Icons";
this.denoteStatesWithIconsToolStripMenuItem.Click += new System.EventHandler(this.denoteStatesWithIconsToolStripMenuItem_Click);
//
@ -974,7 +983,7 @@ namespace BizHawk.Client.EmuHawk
//
this.denoteStatesWithBGColorToolStripMenuItem.CheckOnClick = true;
this.denoteStatesWithBGColorToolStripMenuItem.Name = "denoteStatesWithBGColorToolStripMenuItem";
this.denoteStatesWithBGColorToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
this.denoteStatesWithBGColorToolStripMenuItem.Size = new System.Drawing.Size(230, 22);
this.denoteStatesWithBGColorToolStripMenuItem.Text = "Denote States With BG Color";
this.denoteStatesWithBGColorToolStripMenuItem.Click += new System.EventHandler(this.denoteStatesWithBGColorToolStripMenuItem_Click);
//
@ -982,7 +991,7 @@ namespace BizHawk.Client.EmuHawk
//
this.denoteMarkersWithIconsToolStripMenuItem.CheckOnClick = true;
this.denoteMarkersWithIconsToolStripMenuItem.Name = "denoteMarkersWithIconsToolStripMenuItem";
this.denoteMarkersWithIconsToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
this.denoteMarkersWithIconsToolStripMenuItem.Size = new System.Drawing.Size(230, 22);
this.denoteMarkersWithIconsToolStripMenuItem.Text = "Denote Markers With Icons";
this.denoteMarkersWithIconsToolStripMenuItem.Click += new System.EventHandler(this.denoteMarkersWithIconsToolStripMenuItem_Click);
//
@ -990,14 +999,14 @@ namespace BizHawk.Client.EmuHawk
//
this.denoteMarkersWithBGColorToolStripMenuItem.CheckOnClick = true;
this.denoteMarkersWithBGColorToolStripMenuItem.Name = "denoteMarkersWithBGColorToolStripMenuItem";
this.denoteMarkersWithBGColorToolStripMenuItem.Size = new System.Drawing.Size(219, 22);
this.denoteMarkersWithBGColorToolStripMenuItem.Size = new System.Drawing.Size(230, 22);
this.denoteMarkersWithBGColorToolStripMenuItem.Text = "Denote Markers With BG Color";
this.denoteMarkersWithBGColorToolStripMenuItem.Click += new System.EventHandler(this.denoteMarkersWithBGColorToolStripMenuItem_Click);
//
// toolStripSeparator23
//
this.toolStripSeparator23.Name = "toolStripSeparator23";
this.toolStripSeparator23.Size = new System.Drawing.Size(174, 6);
this.toolStripSeparator23.Size = new System.Drawing.Size(185, 6);
//
// followCursorToolStripMenuItem
//
@ -1009,7 +1018,7 @@ namespace BizHawk.Client.EmuHawk
this.scrollToBottomToolStripMenuItem,
this.scrollToCenterToolStripMenuItem});
this.followCursorToolStripMenuItem.Name = "followCursorToolStripMenuItem";
this.followCursorToolStripMenuItem.Size = new System.Drawing.Size(177, 22);
this.followCursorToolStripMenuItem.Size = new System.Drawing.Size(188, 22);
this.followCursorToolStripMenuItem.Text = "Follow Cursor";
this.followCursorToolStripMenuItem.DropDownOpened += new System.EventHandler(this.followCursorToolStripMenuItem_DropDownOpened);
//
@ -1017,14 +1026,14 @@ namespace BizHawk.Client.EmuHawk
//
this.alwaysScrollToolStripMenuItem.CheckOnClick = true;
this.alwaysScrollToolStripMenuItem.Name = "alwaysScrollToolStripMenuItem";
this.alwaysScrollToolStripMenuItem.Size = new System.Drawing.Size(149, 22);
this.alwaysScrollToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.alwaysScrollToolStripMenuItem.Text = "Always Scroll";
this.alwaysScrollToolStripMenuItem.Click += new System.EventHandler(this.alwaysScrollToolStripMenuItem_Click);
//
// toolStripSeparator24
//
this.toolStripSeparator24.Name = "toolStripSeparator24";
this.toolStripSeparator24.Size = new System.Drawing.Size(146, 6);
this.toolStripSeparator24.Size = new System.Drawing.Size(157, 6);
//
// scrollToViewToolStripMenuItem
//
@ -1032,7 +1041,7 @@ namespace BizHawk.Client.EmuHawk
this.scrollToViewToolStripMenuItem.CheckOnClick = true;
this.scrollToViewToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked;
this.scrollToViewToolStripMenuItem.Name = "scrollToViewToolStripMenuItem";
this.scrollToViewToolStripMenuItem.Size = new System.Drawing.Size(149, 22);
this.scrollToViewToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.scrollToViewToolStripMenuItem.Text = "Scroll to View";
this.scrollToViewToolStripMenuItem.Click += new System.EventHandler(this.scrollToViewToolStripMenuItem_Click);
//
@ -1040,7 +1049,7 @@ namespace BizHawk.Client.EmuHawk
//
this.scrollToTopToolStripMenuItem.CheckOnClick = true;
this.scrollToTopToolStripMenuItem.Name = "scrollToTopToolStripMenuItem";
this.scrollToTopToolStripMenuItem.Size = new System.Drawing.Size(149, 22);
this.scrollToTopToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.scrollToTopToolStripMenuItem.Text = "Scroll to Top";
this.scrollToTopToolStripMenuItem.Click += new System.EventHandler(this.scrollToTopToolStripMenuItem_Click);
//
@ -1048,7 +1057,7 @@ namespace BizHawk.Client.EmuHawk
//
this.scrollToBottomToolStripMenuItem.CheckOnClick = true;
this.scrollToBottomToolStripMenuItem.Name = "scrollToBottomToolStripMenuItem";
this.scrollToBottomToolStripMenuItem.Size = new System.Drawing.Size(149, 22);
this.scrollToBottomToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.scrollToBottomToolStripMenuItem.Text = "Scroll to Bottom";
this.scrollToBottomToolStripMenuItem.Click += new System.EventHandler(this.scrollToBottomToolStripMenuItem_Click);
//
@ -1056,19 +1065,19 @@ namespace BizHawk.Client.EmuHawk
//
this.scrollToCenterToolStripMenuItem.CheckOnClick = true;
this.scrollToCenterToolStripMenuItem.Name = "scrollToCenterToolStripMenuItem";
this.scrollToCenterToolStripMenuItem.Size = new System.Drawing.Size(149, 22);
this.scrollToCenterToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.scrollToCenterToolStripMenuItem.Text = "Scroll to Center";
this.scrollToCenterToolStripMenuItem.Click += new System.EventHandler(this.scrollToCenterToolStripMenuItem_Click);
//
// toolStripSeparator25
//
this.toolStripSeparator25.Name = "toolStripSeparator25";
this.toolStripSeparator25.Size = new System.Drawing.Size(174, 6);
this.toolStripSeparator25.Size = new System.Drawing.Size(185, 6);
//
// wheelScrollSpeedToolStripMenuItem
//
this.wheelScrollSpeedToolStripMenuItem.Name = "wheelScrollSpeedToolStripMenuItem";
this.wheelScrollSpeedToolStripMenuItem.Size = new System.Drawing.Size(177, 22);
this.wheelScrollSpeedToolStripMenuItem.Size = new System.Drawing.Size(188, 22);
this.wheelScrollSpeedToolStripMenuItem.Text = "Wheel Scroll Speed...";
this.wheelScrollSpeedToolStripMenuItem.Click += new System.EventHandler(this.wheelScrollSpeedToolStripMenuItem_Click);
//
@ -1099,19 +1108,19 @@ namespace BizHawk.Client.EmuHawk
//
this.EnableTooltipsMenuItem.Enabled = false;
this.EnableTooltipsMenuItem.Name = "EnableTooltipsMenuItem";
this.EnableTooltipsMenuItem.Size = new System.Drawing.Size(146, 22);
this.EnableTooltipsMenuItem.Size = new System.Drawing.Size(157, 22);
this.EnableTooltipsMenuItem.Text = "&Enable Tooltips";
//
// toolStripSeparator10
//
this.toolStripSeparator10.Name = "toolStripSeparator10";
this.toolStripSeparator10.Size = new System.Drawing.Size(143, 6);
this.toolStripSeparator10.Size = new System.Drawing.Size(154, 6);
//
// aboutToolStripMenuItem
//
this.aboutToolStripMenuItem.Enabled = false;
this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(146, 22);
this.aboutToolStripMenuItem.Size = new System.Drawing.Size(157, 22);
this.aboutToolStripMenuItem.Text = "&About";
//
// TasView
@ -1674,7 +1683,7 @@ namespace BizHawk.Client.EmuHawk
private System.Windows.Forms.ToolStripMenuItem scrollToCenterToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem applyPatternToPaintedInputToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem onlyOnAutoFireColumnsToolStripMenuItem;
public BookmarksBranchesBox BookMarkControl;
private BookmarksBranchesBox BookMarkControl;
private System.Windows.Forms.ToolStripMenuItem BranchContextMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator25;
private System.Windows.Forms.ToolStripMenuItem wheelScrollSpeedToolStripMenuItem;
@ -1691,5 +1700,6 @@ namespace BizHawk.Client.EmuHawk
private System.Windows.Forms.ToolStripMenuItem NewFromCurrentSaveRamMenuItem;
private System.Windows.Forms.ToolStripMenuItem SetBranchCellHoverIntervalMenuItem;
private System.Windows.Forms.ToolStripMenuItem SetMarkerWithTextContextMenuItem;
private System.Windows.Forms.ToolStripMenuItem SetSeekingCutoffIntervalMenuItem;
}
}

View File

@ -6,7 +6,47 @@ namespace BizHawk.Client.EmuHawk
{
private bool _suppressAskSave = false;
public bool WantsToControlSavestates { get { return true; } }
public void SaveState()
{
BookMarkControl.UpdateBranchExternal();
}
public void LoadState()
{
BookMarkControl.LoadBranchExternal();
}
public void SaveStateAs()
{
// dummy
}
public void LoadStateAs()
{
// dummy
}
public void SaveQuickSave(int slot)
{
BookMarkControl.UpdateBranchExternal(slot);
}
public void LoadQuickSave(int slot)
{
BookMarkControl.LoadBranchExternal(slot);
}
public void SelectSlot(int slot)
{
BookMarkControl.SelectBranchExternal(slot);
}
public void PreviousSlot()
{
BookMarkControl.SelectBranchExternal(false);
}
public void NextSlot()
{
BookMarkControl.SelectBranchExternal(true);
}
public bool WantsToControlReadOnly { get { return false; } }
public void ToggleReadOnly()
{
GlobalWin.OSD.AddMessage("TAStudio does not allow manual readonly toggle");
@ -31,7 +71,7 @@ namespace BizHawk.Client.EmuHawk
public bool Rewind()
{
GoToPreviousFrame();
GoToPreviousFrame(); // todo: behave as normal rewind in differentiating between hitting rewind once and holding it.
return true;
}

View File

@ -45,6 +45,8 @@ namespace BizHawk.Client.EmuHawk
private bool _triggerAutoRestore; // If true, autorestore will be called on mouse up
private int? _autoRestoreFrame; // The frame auto-restore will restore to, if set
private bool? _autoRestorePaused = null;
private int? _seekStartFrame = null;
private void JumpToGreenzone()
{
if (Global.Emulator.Frame > CurrentTasMovie.LastValidFrame)
@ -57,11 +59,33 @@ namespace BizHawk.Client.EmuHawk
}
GoToLastEmulatedFrameIfNecessary(CurrentTasMovie.LastValidFrame);
GlobalWin.MainForm.PauseOnFrame = _autoRestoreFrame;
GlobalWin.MainForm.PauseEmulator();
StartSeeking(_autoRestoreFrame, true);
}
}
private void StartSeeking(int? frame, bool pause = false)
{
if (!frame.HasValue)
return;
_seekStartFrame = Emulator.Frame;
GlobalWin.MainForm.PauseOnFrame = frame.Value;
int? diff = GlobalWin.MainForm.PauseOnFrame - _seekStartFrame;
if (pause)
GlobalWin.MainForm.PauseEmulator();
else
GlobalWin.MainForm.UnpauseEmulator();
if (!_seekBackgroundWorker.IsBusy && diff.Value > TasView.SeekingCutoffInterval)
_seekBackgroundWorker.RunWorkerAsync();
}
public void StopSeeking()
{
_seekBackgroundWorker.CancelAsync();
}
// public static Color CurrentFrame_FrameCol = Color.FromArgb(0xCFEDFC); Why?
public static Color CurrentFrame_InputLog = Color.FromArgb(0xB5E7F7);

View File

@ -695,6 +695,28 @@ namespace BizHawk.Client.EmuHawk
}
}
private void SetSeekingCutoffIntervalMenuItem_Click(object sender, EventArgs e)
{
using (var prompt = new InputPrompt
{
TextInputType = InputPrompt.InputType.Unsigned,
Message = "Seeking Cutoff Interval",
InitialValue = Settings.SeekingCutoffInterval.ToString()
})
{
DialogResult result = prompt.ShowDialog();
if (result == DialogResult.OK)
{
int val = int.Parse(prompt.PromptText);
if (val > 0)
{
Settings.SeekingCutoffInterval = val;
TasView.SeekingCutoffInterval = val;
}
}
}
}
private void ConfigSubMenu_DropDownOpened(object sender, EventArgs e)
{
DrawInputByDraggingMenuItem.Checked = Settings.DrawInput;
@ -1097,7 +1119,7 @@ namespace BizHawk.Client.EmuHawk
index, (byte[])StatableEmulator.SaveStateBinary().Clone());
GlobalWin.MainForm.PauseEmulator();
LoadFile(new FileInfo(newProject.Filename));
LoadFile(new FileInfo(newProject.Filename), true);
}
}
@ -1112,7 +1134,7 @@ namespace BizHawk.Client.EmuHawk
SaveRamEmulator.CloneSaveRam());
GlobalWin.MainForm.PauseEmulator();
LoadFile(new FileInfo(newProject.Filename));
LoadFile(new FileInfo(newProject.Filename), true);
}
}

View File

@ -38,8 +38,6 @@ namespace BizHawk.Client.EmuHawk
StartAtNearestFrameAndEmulate(frame);
MaybeFollowCursor();
//return; seriously? well, maybe it's for some insane speedup, but it skipped updating when putting playback to frame zero.
}
else // Emulate to a future frame
{
@ -58,8 +56,7 @@ namespace BizHawk.Client.EmuHawk
if (lastState > Emulator.Frame)
LoadState(CurrentTasMovie.TasStateManager[lastState]); // STATE ACCESS
GlobalWin.MainForm.UnpauseEmulator();
GlobalWin.MainForm.PauseOnFrame = frame;
StartSeeking(frame);
}
}

View File

@ -26,6 +26,7 @@ namespace BizHawk.Client.EmuHawk
private readonly List<TasClipboardEntry> _tasClipboard = new List<TasClipboardEntry>();
private BackgroundWorker _saveBackgroundWorker;
private BackgroundWorker _seekBackgroundWorker;
private MovieEndAction _originalEndAction; // The movie end behavior selected by the user (that is overridden by TAStudio)
private Dictionary<string, string> GenerateColumnNames()
@ -64,6 +65,7 @@ namespace BizHawk.Client.EmuHawk
FollowCursorAlwaysScroll = false;
FollowCursorScrollMethod = "near";
BranchCellHoverInterval = 1;
SeekingCutoffInterval = 2;
// default to taseditor fashion
denoteStatesWithIcons = false;
denoteStatesWithBGColor = true;
@ -81,6 +83,7 @@ namespace BizHawk.Client.EmuHawk
public bool FollowCursorAlwaysScroll { get; set; }
public string FollowCursorScrollMethod { get; set; }
public int BranchCellHoverInterval { get; set; }
public int SeekingCutoffInterval { get; set; }
public bool denoteStatesWithIcons { get; set; }
public bool denoteStatesWithBGColor { get; set; }
@ -127,6 +130,7 @@ namespace BizHawk.Client.EmuHawk
this.SavingProgressBar.Visible = false;
InitializeSaveWorker();
InitializeSeekWorker();
WantsToControlStopMovie = true;
TasPlaybackBox.Tastudio = this;
@ -178,6 +182,57 @@ namespace BizHawk.Client.EmuHawk
CurrentTasMovie.NewBGWorker(_saveBackgroundWorker);
}
private void InitializeSeekWorker()
{
if (_seekBackgroundWorker != null)
{
_seekBackgroundWorker.Dispose();
_seekBackgroundWorker = null; // Idk if this line is even useful.
}
_seekBackgroundWorker = new BackgroundWorker();
_seekBackgroundWorker.WorkerReportsProgress = true;
_seekBackgroundWorker.WorkerSupportsCancellation = true;
_seekBackgroundWorker.DoWork += (s, e) =>
{
this.Invoke(() => this.MessageStatusLabel.Text = "Seeking...");
this.Invoke(() => this.SavingProgressBar.Visible = true);
for ( ; ; )
{
if (_seekBackgroundWorker.CancellationPending)
{
e.Cancel = true;
break;
}
int diff = Global.Emulator.Frame - _seekStartFrame.Value;
int unit = GlobalWin.MainForm.PauseOnFrame.Value - _seekStartFrame.Value;
double progress = 0;
if (diff != 0 && unit != 0)
progress = (double)100d / unit * diff;
if (progress < 0)
progress = 0;
_seekBackgroundWorker.ReportProgress((int)progress);
System.Threading.Thread.Sleep(1);
}
};
_seekBackgroundWorker.ProgressChanged += (s, e) =>
{
this.Invoke(() => this.SavingProgressBar.Value = e.ProgressPercentage);
};
_seekBackgroundWorker.RunWorkerCompleted += (s, e) =>
{
this.Invoke(() => this.SavingProgressBar.Visible = false);
this.Invoke(() => this.MessageStatusLabel.Text = "");
InitializeSeekWorker(); // Required, or it will error when trying to report progress again.
};
}
private bool _initialized = false;
private void Tastudio_Load(object sender, EventArgs e)
{
@ -207,6 +262,7 @@ namespace BizHawk.Client.EmuHawk
TasView.ScrollSpeed = Settings.ScrollSpeed;
TasView.AlwaysScroll = Settings.FollowCursorAlwaysScroll;
TasView.ScrollMethod = Settings.FollowCursorScrollMethod;
TasView.SeekingCutoffInterval = Settings.SeekingCutoffInterval;
BookMarkControl.HoverInterval = Settings.BranchCellHoverInterval;
TasView.denoteStatesWithIcons = Settings.denoteStatesWithIcons;
@ -296,10 +352,12 @@ namespace BizHawk.Client.EmuHawk
return true;
}
private void SetTasMovieCallbacks()
private void SetTasMovieCallbacks(TasMovie movie = null)
{
CurrentTasMovie.ClientSettingsForSave = ClientSettingsForSave;
CurrentTasMovie.GetClientSettingsOnLoad = GetClientSettingsOnLoad;
if (movie == null)
movie = CurrentTasMovie;
movie.ClientSettingsForSave = ClientSettingsForSave;
movie.GetClientSettingsOnLoad = GetClientSettingsOnLoad;
}
private string ClientSettingsForSave()
@ -343,8 +401,7 @@ namespace BizHawk.Client.EmuHawk
column.Visible = false;
}
TasView.AllColumns.ColumnsChanged();
TasView.AllColumns.ColumnsChanged();
// Patterns
int bStart = 0;
@ -420,7 +477,7 @@ namespace BizHawk.Client.EmuHawk
Settings.RecentTas.Add(Global.MovieSession.Movie.Filename);
}
private bool LoadFile(FileInfo file)
private bool LoadFile(FileInfo file, bool startsFromSavestate = false)
{
if (!file.Exists)
{
@ -428,7 +485,7 @@ namespace BizHawk.Client.EmuHawk
return false;
}
TasMovie newMovie = new TasMovie(false, _saveBackgroundWorker);
TasMovie newMovie = new TasMovie(startsFromSavestate, _saveBackgroundWorker);
newMovie.TasStateManager.InvalidateCallback = GreenzoneInvalidated;
newMovie.Filename = file.FullName;
@ -437,8 +494,13 @@ namespace BizHawk.Client.EmuHawk
if (!HandleMovieLoadStuff(newMovie))
return false;
SetUpColumns();
GoToFrame(CurrentTasMovie.Session.CurrentFrame);
if (TasView.AllColumns.Count() == 0)
SetUpColumns();
if (startsFromSavestate)
GoToFrame(0);
else
GoToFrame(CurrentTasMovie.Session.CurrentFrame);
CurrentTasMovie.PropertyChanged += new PropertyChangedEventHandler(this.TasMovie_OnPropertyChanged);
CurrentTasMovie.CurrentBranch = CurrentTasMovie.Session.CurrentBranch;
// clear all selections
@ -476,9 +538,9 @@ namespace BizHawk.Client.EmuHawk
private bool HandleMovieLoadStuff(TasMovie movie = null)
{
WantsToControlStopMovie = false;
bool result;
WantsToControlStopMovie = false;
if (movie == null)
{
movie = CurrentTasMovie;
@ -486,8 +548,10 @@ namespace BizHawk.Client.EmuHawk
}
else
result = StartNewMovieWrapper(false, movie);
if (!result)
return false;
WantsToControlStopMovie = true;
CurrentTasMovie.ChangeLog.ClearLog();
@ -503,6 +567,7 @@ namespace BizHawk.Client.EmuHawk
_initializing = true;
if (movie == null)
movie = CurrentTasMovie;
SetTasMovieCallbacks(movie as TasMovie);
bool result = GlobalWin.MainForm.StartNewMovie(movie, record);
_initializing = false;
@ -632,8 +697,7 @@ namespace BizHawk.Client.EmuHawk
{
if (_autoRestoreFrame > Emulator.Frame) // Don't unpause if we are already on the desired frame, else runaway seek
{
GlobalWin.MainForm.PauseOnFrame = _autoRestoreFrame;
GlobalWin.MainForm.UnpauseEmulator();
StartSeeking(_autoRestoreFrame);
}
}
else
@ -643,8 +707,6 @@ namespace BizHawk.Client.EmuHawk
_autoRestorePaused = null;
GlobalWin.MainForm.PauseOnFrame = null; // Cancel seek to autorestore point
}
_autoRestoreFrame = null;
}
@ -665,8 +727,7 @@ namespace BizHawk.Client.EmuHawk
{
if (GlobalWin.MainForm.EmulatorPaused || GlobalWin.MainForm.IsSeeking) // make seek frame keep up with emulation on fast scrolls
{
GlobalWin.MainForm.PauseOnFrame = frame;
GlobalWin.MainForm.UnpauseEmulator();
StartSeeking(frame);
}
}
}
@ -686,6 +747,16 @@ namespace BizHawk.Client.EmuHawk
_hackyDontUpdate = false;
}
public void AddBranchExternal()
{
BookMarkControl.AddBranchExternal();
}
public void RemoveBranchExtrenal()
{
BookMarkControl.RemoveBranchExtrenal();
}
private void UpdateOtherTools() // a hack probably, surely there is a better way to do this
{
_hackyDontUpdate = true;

View File

@ -124,18 +124,18 @@
<data name="RecentSubMenu.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALCQAA
CwkBEvpHPgAAAk1JREFUOE+VkktvUlEUhVsfsdHoREcOHJr4C/RPONHoXzBxoOlAJybOlAZtkdSa2piY
NsjjFiiX8qY8ChYL+ECB2lKB8rq0k5bEmiiRbtc+6b2B6MTBR/ZZa+919j3tEBH9RbudHD6E63/2qAwc
treT58BVRVnWl8vBbLEg7wNC/QPaMrwb4GT/jFa024mzQLe56c9GwjM7klXXlcw6ksyPSbLoKByc/lUq
+TbQMwrODARAGAF3SxtexSMbf8vOCVp9ZyK+/euaW9TO+SfksOlprSjvoteAjU5rAYqSuFyvR1PR8Ewv
GJii8rcAoYFSb+d4gDAgNI/8jGTHOFUroT3410QAHuk4Am4Vi/KOzz2JGxfFcLMZI3wK5T7ZqaXEhcYb
WU2PKJM2H7Ra8XE14AQO91dTpk4k9JLq9YgYHghoxcWZPa/bSCH/C2o0orPaBo1GbDQee9VJxF+zoYFP
wtpGWgpN0/uMRWgcyiG1WsSkBhxFwG0E7AV8z2lrKyxuYvgBs2kLr4z1XcLj4SA2gD+nBhxB8p1sxtKZ
t4xR/otTDNdqS1oQw7ezx2/AfxVok1oAmh+WSt7v/MKLLgOtr3tEQD+sseeyPyX0dqHdVAOGq9XQPazX
/JyzH9itY+SQ9LSSnKV8fkHANWvsoYc/JYaZERHAPzicBw9AoZBf+BnwTZEN/4G2N4egZg1eDz05cIHn
tACmUgmeAtdhRsvlwH6x6Dr4+EESoO5B68JLo+eSOjMQwKDpGLgCJtDoBysgBXzQDOBifz8zcPh/aOgP
7nYTiVA2JaoAAAAASUVORK5CYII=
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAAlwSFlzAAALBwAA
CwcBtnMLwAAAAllJREFUOE+VU8tuUlEUFR+x0ehEB40DhyZ+gQ78BSca/QUTB5oOdGLiTGnQFkmtqY2J
aYO8CpRLeVMehRYL+ECB2lKB8qYTS2JNlAjbtU96b2h1IskiZ6+19jr7HA4qIjp08NNuL6v2OCEOD1/5
y6MQHCCj3Y6fBa42m0uaYtGfzuekXYCw/gFuCdoN4MRgj9LcasXOAOrNTW86FJzetpjUXYtBTRbDY7IY
1RT0T/0qFDwb8IwAp+UQEQBiCLhb2HA3XZLut2Qfp9W3euLdv6w5xdo+94RsZg2t5aVv8Gox0SlxfP5q
NmOXqtVwIhyc7vl9k1T86iMYKLE8yw2EBsG5pGck2caoXArsQL8mAlqt+DEE3MrnpW2PcwI7Lojmej1C
OAplPlqp0YwKjicy6R9RKmnoNxrRMTngOIr7qwl9JxR4SdVqSDTvC2hERc2a26mjgPcF1WrhGWWCWi0y
Eo286sSir1lQgCNhbB0tBqboXcooeJ6KQyqVkF4OOIKA2wjY8Xme09ZWUOzE4AtMJ408MsZ3CI2b/ZgA
+qwccBjJd9IpY2fOOErZz3bRXKksKkFc8+6s8R3wrwJuQgmA+WGh4P7ON7zg0NL6uksEDII51hzWpwRv
F9pNOUBVLgfuYbz6p4y1bzWNks2ioZX4DGWz8wK8Zo41ePgoEfQMKe8AxTngAZDLZed/+jyTZMYLNL/Z
A9bMQevBkwHO73uJXJRK/pPAdYjhYtG3m887+h/eWwSw7oHrQkvCc/Gf/wUmYToKXAbGYfQCK0AC8IDT
AhcGm5UjHCT/p/4DPvHsVpirf9UAAAAASUVORK5CYII=
</value>
</data>
<metadata name="TasStatusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">

View File

@ -44,9 +44,9 @@ namespace BizHawk.Client.EmuHawk
return;
if (row == log.UndoIndex)
color = Color.Green;
color = TAStudio.GreenZone_InputLog;
else if (row > log.UndoIndex)
color = Color.Red;
color = TAStudio.LagZone_InputLog;
}
private string _lastUndoAction = null;
@ -55,7 +55,7 @@ namespace BizHawk.Client.EmuHawk
HistoryView.ItemCount = log.Names.Count;
if (AutoScrollCheck.Checked && _lastUndoAction != log.NextUndoStepName)
{
HistoryView.ensureVisible(log.UndoIndex - 1);
HistoryView.ensureVisible(log.UndoIndex);
HistoryView.clearSelection();
HistoryView.SelectItem(log.UndoIndex - 1, true);
}

Some files were not shown because too many files have changed in this diff Show More