Addition of Keymapping Utility and assorted minor fixes/changes

This commit is contained in:
RadzPrower 2023-02-24 15:54:51 -05:00
parent 61573871e7
commit f25c43275a
13 changed files with 2541 additions and 123 deletions

View File

@ -3,18 +3,30 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33213.308
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Zelda 3 Launcher", "Zelda 3 Launcher\Zelda 3 Launcher.csproj", "{8BE56675-53B7-4952-93C6-8C9477388F34}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Zelda 3 Launcher", "Zelda 3 Launcher\Zelda 3 Launcher.csproj", "{8BE56675-53B7-4952-93C6-8C9477388F34}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8BE56675-53B7-4952-93C6-8C9477388F34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8BE56675-53B7-4952-93C6-8C9477388F34}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8BE56675-53B7-4952-93C6-8C9477388F34}.Debug|x64.ActiveCfg = Debug|x64
{8BE56675-53B7-4952-93C6-8C9477388F34}.Debug|x64.Build.0 = Debug|x64
{8BE56675-53B7-4952-93C6-8C9477388F34}.Debug|x86.ActiveCfg = Debug|x86
{8BE56675-53B7-4952-93C6-8C9477388F34}.Debug|x86.Build.0 = Debug|x86
{8BE56675-53B7-4952-93C6-8C9477388F34}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8BE56675-53B7-4952-93C6-8C9477388F34}.Release|Any CPU.Build.0 = Release|Any CPU
{8BE56675-53B7-4952-93C6-8C9477388F34}.Release|x64.ActiveCfg = Release|x64
{8BE56675-53B7-4952-93C6-8C9477388F34}.Release|x64.Build.0 = Release|x64
{8BE56675-53B7-4952-93C6-8C9477388F34}.Release|x86.ActiveCfg = Release|x86
{8BE56675-53B7-4952-93C6-8C9477388F34}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,145 @@
using System;
using SDL2;
using Timer = System.Timers.Timer;
namespace Zelda_3_Launcher
{
public class MyController
{
private IntPtr controller;
public bool connected = false;
public MyController()
{
// Initialize SDL
SDL.SDL_Init(SDL.SDL_INIT_GAMECONTROLLER);
// Check if any joysticks are connected
if (SDL.SDL_NumJoysticks() > 0)
{
// Open the first joystick
controller = SDL.SDL_GameControllerOpen(0);
connected = true;
}
}
public string? GetButtonName()
{
SDL.SDL_PumpEvents();
SDL.SDL_FlushEvents(SDL.SDL_EventType.SDL_FIRSTEVENT, SDL.SDL_EventType.SDL_LASTEVENT);
var window = SDL.SDL_CreateWindow("Awaiting input...", Form.ActiveForm.Location.X + 292, Form.ActiveForm.Location.Y + 199, 150, 50,
SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_GRABBED |
SDL.SDL_WindowFlags.SDL_WINDOW_BORDERLESS |
SDL.SDL_WindowFlags.SDL_WINDOW_ALWAYS_ON_TOP);
SDL.SDL_ShowCursor(SDL.SDL_DISABLE);
var leftTrigger = false;
var rightTrigger = false;
var stop = DateTime.Now.AddSeconds(5);
while (true)
{
SDL.SDL_Event e;
// Wait for an event to occur
SDL.SDL_PollEvent(out e);
// Check for ESC key
if (e.type == SDL.SDL_EventType.SDL_KEYDOWN)
{
if (SDL.SDL_GetKeyName(e.key.keysym.sym) == "Escape")
{
SDL.SDL_DestroyWindow(window);
return null;
}
}
// Check for trigger axis event
if (e.type == SDL.SDL_EventType.SDL_CONTROLLERAXISMOTION)
{
if (e.caxis.axis == ((byte)SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT))
{
leftTrigger = true;
}
else if (e.caxis.axis == ((byte)SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT))
{
rightTrigger = true;
}
if (e.caxis.axis == ((byte)SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT) && e.caxis.axisValue == 0 && leftTrigger)
{
SDL.SDL_DestroyWindow(window);
return "L2";
}
else if (e.caxis.axis == ((byte)SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT) && e.caxis.axisValue == 0 && rightTrigger)
{
SDL.SDL_DestroyWindow(window);
return "R2";
}
}
// Check if the event was a controller button press
if (e.type == SDL.SDL_EventType.SDL_CONTROLLERBUTTONDOWN)
{
SDL.SDL_DestroyWindow(window);
return (ConvertButtonID(e.cbutton.button));
}
if (DateTime.Now >= stop)
{
SDL.SDL_DestroyWindow(window);
return null;
}
}
}
internal static string? ConvertButtonID(byte button)
{
switch (button)
{
case 0:
return "A";
case 1:
return "B";
case 2:
return "X";
case 3:
return "Y";
case 4:
return "Back";
case 5:
return "Guide";
case 6:
return "Start";
case 7:
return "L3";
case 8:
return "R3";
case 9:
return "Lb";
case 10:
return "Rb";
case 11:
return "DPadUp";
case 12:
return "DPadDown";
case 13:
return "DPadLeft";
case 14:
return "DPadRight";
default:
return null;
}
}
public void Close()
{
// Close the joystick and quit SDL
SDL.SDL_GameControllerClose(controller);
SDL.SDL_Quit();
}
}
}

View File

@ -1,11 +1,5 @@
using System;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Runtime.CompilerServices;
using LibGit2Sharp;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using XAct.Resources;
namespace Zelda_3_Launcher
{
@ -201,7 +195,11 @@ namespace Zelda_3_Launcher
if (!line.Equals("# Change the appearance of Link by loading a ZSPR file") &&
!line.Equals("# See all sprites here: https://snesrev.github.io/sprites-gfx/snes/zelda3/link/") &&
!line.Equals("# Download the files with \"git clone https://github.com/snesrev/sprites-gfx.git\"") &&
!line.Equals("# LinkGraphics = sprites-gfx/snes/zelda3/link/sheets/megaman-x.2.zspr"))
!line.Equals("# LinkGraphics = sprites-gfx/snes/zelda3/link/sheets/megaman-x.2.zspr") &&
!line.Equals("# This default is suitable for QWERTZ keyboards.") &&
!line.Equals("#Controls = Up, Down, Left, Right, Right Shift, Return, x, y, s, a, c, v") &&
!line.Equals("# This one is suitable for AZERTY keyboards.") &&
!line.Equals("#Controls = Up, Down, Left, Right, Right Shift, Return, x, w, s, q, c, v"))
{
modifiedFile.WriteLine(line);
}
@ -272,7 +270,7 @@ namespace Zelda_3_Launcher
this.build.Location = new System.Drawing.Point(8, 8);
this.build.Name = "build";
this.build.Size = new System.Drawing.Size(175, 50);
this.build.TabIndex = 0;
this.build.TabIndex = 1;
this.build.Text = "Download";
this.build.UseVisualStyleBackColor = true;
this.build.Click += new System.EventHandler(this.build_Click);
@ -296,7 +294,7 @@ namespace Zelda_3_Launcher
this.settings.Location = new System.Drawing.Point(8, 120);
this.settings.Name = "settings";
this.settings.Size = new System.Drawing.Size(175, 50);
this.settings.TabIndex = 0;
this.settings.TabIndex = 2;
this.settings.Text = "Settings";
this.settings.UseVisualStyleBackColor = true;
this.settings.Click += new System.EventHandler(this.settings_click);
@ -313,7 +311,7 @@ namespace Zelda_3_Launcher
// progressCompile
//
this.progressCompile.Location = new System.Drawing.Point(8, 199);
this.progressCompile.Maximum = 2808;
this.progressCompile.Maximum = 2875;
this.progressCompile.Minimum = 543;
this.progressCompile.Name = "progressCompile";
this.progressCompile.Size = new System.Drawing.Size(175, 23);
@ -335,6 +333,7 @@ namespace Zelda_3_Launcher
this.MaximizeBox = false;
this.Name = "MainForm";
this.Padding = new System.Windows.Forms.Padding(5);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.ResumeLayout(false);
this.PerformLayout();
@ -381,7 +380,7 @@ namespace Zelda_3_Launcher
while (!process.HasExited)
{
var fileCount = Directory.GetFiles(Program.repoDir, "*", SearchOption.AllDirectories).Count();
if (fileCount > 2808) progressCompile.Value = fileCount - 1000;
if (fileCount > 2875) progressCompile.Value = fileCount - 1000;
else progressCompile.Value = fileCount;
Application.DoEvents();
}

View File

@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Zelda_3_Launcher.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Zelda_3_Launcher.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,120 @@
<?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>
</root>

View File

@ -9,9 +9,10 @@
<ImplicitUsings>enable</ImplicitUsings>
<PackageIcon>ЯP Flat Blue Small.png</PackageIcon>
<ApplicationIcon>RadzPrower.ico</ApplicationIcon>
<FileVersion>1.1.0.0</FileVersion>
<AssemblyVersion>1.1.0.0</AssemblyVersion>
<Version>1.1.0.0</Version>
<FileVersion>1.2.0.0</FileVersion>
<AssemblyVersion>1.2.0.0</AssemblyVersion>
<Version>1.2.0.0</Version>
<Platforms>AnyCPU;x86;x64</Platforms>
</PropertyGroup>
<ItemGroup>
@ -28,8 +29,28 @@
<ItemGroup>
<PackageReference Include="ini-parser" Version="2.5.2" />
<PackageReference Include="LibGit2Sharp" Version="0.27.0-preview-0182" />
<PackageReference Include="ppy.SDL2-CS" Version="1.0.82" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="XAct.Core.PCL" Version="0.0.5014" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
<Exec Command="copy &quot;$(TargetDir)runtimes\win-x64\native\SDL2.dll&quot; &quot;$(TargetDir)&quot;" />
</Target>
</Project>

806
Zelda 3 Launcher/keymapper.Designer.cs generated Normal file
View File

@ -0,0 +1,806 @@
namespace Zelda_3_Launcher
{
partial class keymapper
{
/// <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.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(keymapper));
this.pictureController = new System.Windows.Forms.PictureBox();
this.textBoxDpadLeft = new System.Windows.Forms.TextBox();
this.textBoxDpadRight = new System.Windows.Forms.TextBox();
this.textBoxDpadUp = new System.Windows.Forms.TextBox();
this.textBoxDpadDown = new System.Windows.Forms.TextBox();
this.textBoxSelect = new System.Windows.Forms.TextBox();
this.textBoxStart = new System.Windows.Forms.TextBox();
this.textBoxY = new System.Windows.Forms.TextBox();
this.textBoxA = new System.Windows.Forms.TextBox();
this.textBoxX = new System.Windows.Forms.TextBox();
this.textBoxB = new System.Windows.Forms.TextBox();
this.textBoxL = new System.Windows.Forms.TextBox();
this.textBoxR = new System.Windows.Forms.TextBox();
this.groupBoxController = new System.Windows.Forms.GroupBox();
this.buttonAssignAll = new System.Windows.Forms.Button();
this.groupBoxInput = new System.Windows.Forms.GroupBox();
this.radioButtonController = new System.Windows.Forms.RadioButton();
this.radioButtonKeyboard = new System.Windows.Forms.RadioButton();
this.groupBoxCheats = new System.Windows.Forms.GroupBox();
this.textBoxKey = new System.Windows.Forms.TextBox();
this.textBoxNoClip = new System.Windows.Forms.TextBox();
this.textBoxTurbo = new System.Windows.Forms.TextBox();
this.textBoxLife = new System.Windows.Forms.TextBox();
this.labelKey = new System.Windows.Forms.Label();
this.labelTurbo = new System.Windows.Forms.Label();
this.labelNoClip = new System.Windows.Forms.Label();
this.labelLife = new System.Windows.Forms.Label();
this.groupBoxGame = new System.Windows.Forms.GroupBox();
this.labelVolumeDown = new System.Windows.Forms.Label();
this.labelVolumeUp = new System.Windows.Forms.Label();
this.labelDecreaseWindowSize = new System.Windows.Forms.Label();
this.labelIncreaseWindowSize = new System.Windows.Forms.Label();
this.checkBoxDim = new System.Windows.Forms.CheckBox();
this.textBoxPause = new System.Windows.Forms.TextBox();
this.labelPause = new System.Windows.Forms.Label();
this.textBoxVolumeDown = new System.Windows.Forms.TextBox();
this.textBoxVolumeUp = new System.Windows.Forms.TextBox();
this.textBoxDecreaseWindowSize = new System.Windows.Forms.TextBox();
this.textBoxIncreaseWindowSize = new System.Windows.Forms.TextBox();
this.labelReset = new System.Windows.Forms.Label();
this.textBoxReset = new System.Windows.Forms.TextBox();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.labelReplayToggle = new System.Windows.Forms.Label();
this.labelStopReplay = new System.Windows.Forms.Label();
this.buttonSave = new System.Windows.Forms.Button();
this.buttonReset = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
this.textBoxToggleReplay = new System.Windows.Forms.TextBox();
this.textBoxStopReplay = new System.Windows.Forms.TextBox();
this.groupBoxReplays = new System.Windows.Forms.GroupBox();
this.labelReplaysNote = new System.Windows.Forms.Label();
this.groupBoxReplayControls = new System.Windows.Forms.GroupBox();
this.label1 = new System.Windows.Forms.Label();
this.groupBoxPerformance = new System.Windows.Forms.GroupBox();
this.labelToggleRenderer = new System.Windows.Forms.Label();
this.labelToggleFPS = new System.Windows.Forms.Label();
this.textBoxRenderer = new System.Windows.Forms.TextBox();
this.textBoxFPS = new System.Windows.Forms.TextBox();
this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
((System.ComponentModel.ISupportInitialize)(this.pictureController)).BeginInit();
this.groupBoxController.SuspendLayout();
this.groupBoxInput.SuspendLayout();
this.groupBoxCheats.SuspendLayout();
this.groupBoxGame.SuspendLayout();
this.groupBoxReplays.SuspendLayout();
this.groupBoxReplayControls.SuspendLayout();
this.groupBoxPerformance.SuspendLayout();
this.SuspendLayout();
//
// pictureController
//
this.pictureController.Image = ((System.Drawing.Image)(resources.GetObject("pictureController.Image")));
this.pictureController.Location = new System.Drawing.Point(6, 22);
this.pictureController.Name = "pictureController";
this.pictureController.Size = new System.Drawing.Size(686, 307);
this.pictureController.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pictureController.TabIndex = 0;
this.pictureController.TabStop = false;
this.toolTip1.SetToolTip(this.pictureController, resources.GetString("pictureController.ToolTip"));
//
// textBoxDpadLeft
//
this.textBoxDpadLeft.Location = new System.Drawing.Point(18, 173);
this.textBoxDpadLeft.Name = "textBoxDpadLeft";
this.textBoxDpadLeft.ReadOnly = true;
this.textBoxDpadLeft.Size = new System.Drawing.Size(50, 23);
this.textBoxDpadLeft.TabIndex = 2;
//
// textBoxDpadRight
//
this.textBoxDpadRight.Location = new System.Drawing.Point(210, 173);
this.textBoxDpadRight.Name = "textBoxDpadRight";
this.textBoxDpadRight.ReadOnly = true;
this.textBoxDpadRight.Size = new System.Drawing.Size(50, 23);
this.textBoxDpadRight.TabIndex = 3;
//
// textBoxDpadUp
//
this.textBoxDpadUp.Location = new System.Drawing.Point(114, 88);
this.textBoxDpadUp.Name = "textBoxDpadUp";
this.textBoxDpadUp.ReadOnly = true;
this.textBoxDpadUp.Size = new System.Drawing.Size(50, 23);
this.textBoxDpadUp.TabIndex = 0;
//
// textBoxDpadDown
//
this.textBoxDpadDown.Location = new System.Drawing.Point(114, 256);
this.textBoxDpadDown.Name = "textBoxDpadDown";
this.textBoxDpadDown.ReadOnly = true;
this.textBoxDpadDown.Size = new System.Drawing.Size(50, 23);
this.textBoxDpadDown.TabIndex = 1;
//
// textBoxSelect
//
this.textBoxSelect.Location = new System.Drawing.Point(289, 208);
this.textBoxSelect.Name = "textBoxSelect";
this.textBoxSelect.ReadOnly = true;
this.textBoxSelect.Size = new System.Drawing.Size(50, 23);
this.textBoxSelect.TabIndex = 4;
//
// textBoxStart
//
this.textBoxStart.Location = new System.Drawing.Point(358, 208);
this.textBoxStart.Name = "textBoxStart";
this.textBoxStart.ReadOnly = true;
this.textBoxStart.Size = new System.Drawing.Size(50, 23);
this.textBoxStart.TabIndex = 5;
//
// textBoxY
//
this.textBoxY.Location = new System.Drawing.Point(465, 173);
this.textBoxY.Name = "textBoxY";
this.textBoxY.ReadOnly = true;
this.textBoxY.Size = new System.Drawing.Size(40, 23);
this.textBoxY.TabIndex = 9;
//
// textBoxA
//
this.textBoxA.Location = new System.Drawing.Point(597, 173);
this.textBoxA.Name = "textBoxA";
this.textBoxA.ReadOnly = true;
this.textBoxA.Size = new System.Drawing.Size(40, 23);
this.textBoxA.TabIndex = 6;
//
// textBoxX
//
this.textBoxX.Location = new System.Drawing.Point(531, 107);
this.textBoxX.Name = "textBoxX";
this.textBoxX.ReadOnly = true;
this.textBoxX.Size = new System.Drawing.Size(40, 23);
this.textBoxX.TabIndex = 8;
//
// textBoxB
//
this.textBoxB.Location = new System.Drawing.Point(531, 240);
this.textBoxB.Name = "textBoxB";
this.textBoxB.ReadOnly = true;
this.textBoxB.Size = new System.Drawing.Size(40, 23);
this.textBoxB.TabIndex = 7;
//
// textBoxL
//
this.textBoxL.Location = new System.Drawing.Point(182, 37);
this.textBoxL.Name = "textBoxL";
this.textBoxL.ReadOnly = true;
this.textBoxL.Size = new System.Drawing.Size(50, 23);
this.textBoxL.TabIndex = 10;
//
// textBoxR
//
this.textBoxR.Location = new System.Drawing.Point(466, 37);
this.textBoxR.Name = "textBoxR";
this.textBoxR.ReadOnly = true;
this.textBoxR.Size = new System.Drawing.Size(50, 23);
this.textBoxR.TabIndex = 11;
//
// groupBoxController
//
this.groupBoxController.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.groupBoxController.Controls.Add(this.buttonAssignAll);
this.groupBoxController.Controls.Add(this.groupBoxInput);
this.groupBoxController.Controls.Add(this.textBoxDpadDown);
this.groupBoxController.Controls.Add(this.textBoxDpadLeft);
this.groupBoxController.Controls.Add(this.textBoxDpadUp);
this.groupBoxController.Controls.Add(this.textBoxDpadRight);
this.groupBoxController.Controls.Add(this.textBoxA);
this.groupBoxController.Controls.Add(this.textBoxSelect);
this.groupBoxController.Controls.Add(this.textBoxB);
this.groupBoxController.Controls.Add(this.textBoxStart);
this.groupBoxController.Controls.Add(this.textBoxR);
this.groupBoxController.Controls.Add(this.textBoxY);
this.groupBoxController.Controls.Add(this.textBoxL);
this.groupBoxController.Controls.Add(this.textBoxX);
this.groupBoxController.Controls.Add(this.pictureController);
this.groupBoxController.Location = new System.Drawing.Point(12, 12);
this.groupBoxController.Name = "groupBoxController";
this.groupBoxController.Size = new System.Drawing.Size(698, 337);
this.groupBoxController.TabIndex = 3;
this.groupBoxController.TabStop = false;
this.groupBoxController.Text = "Controller";
this.toolTip1.SetToolTip(this.groupBoxController, resources.GetString("groupBoxController.ToolTip"));
//
// buttonAssignAll
//
this.buttonAssignAll.Anchor = System.Windows.Forms.AnchorStyles.None;
this.buttonAssignAll.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.buttonAssignAll.Location = new System.Drawing.Point(282, 99);
this.buttonAssignAll.Name = "buttonAssignAll";
this.buttonAssignAll.Size = new System.Drawing.Size(134, 25);
this.buttonAssignAll.TabIndex = 9;
this.buttonAssignAll.Text = "Assign All Input";
this.toolTip1.SetToolTip(this.buttonAssignAll, "Set each input sequentially (hit ESC to skip to the next input)");
this.buttonAssignAll.UseVisualStyleBackColor = true;
this.buttonAssignAll.Click += new System.EventHandler(this.buttonAssignAll_Click);
//
// groupBoxInput
//
this.groupBoxInput.Controls.Add(this.radioButtonController);
this.groupBoxInput.Controls.Add(this.radioButtonKeyboard);
this.groupBoxInput.Location = new System.Drawing.Point(306, 130);
this.groupBoxInput.Name = "groupBoxInput";
this.groupBoxInput.Size = new System.Drawing.Size(87, 72);
this.groupBoxInput.TabIndex = 12;
this.groupBoxInput.TabStop = false;
this.groupBoxInput.Text = "Input Type";
this.toolTip1.SetToolTip(this.groupBoxInput, "Select the input type you want to configure");
//
// radioButtonController
//
this.radioButtonController.AutoSize = true;
this.radioButtonController.Enabled = false;
this.radioButtonController.Location = new System.Drawing.Point(6, 47);
this.radioButtonController.Name = "radioButtonController";
this.radioButtonController.Size = new System.Drawing.Size(78, 19);
this.radioButtonController.TabIndex = 1;
this.radioButtonController.Text = "Controller";
this.radioButtonController.UseVisualStyleBackColor = true;
//
// radioButtonKeyboard
//
this.radioButtonKeyboard.AutoSize = true;
this.radioButtonKeyboard.Checked = true;
this.radioButtonKeyboard.Location = new System.Drawing.Point(6, 22);
this.radioButtonKeyboard.Name = "radioButtonKeyboard";
this.radioButtonKeyboard.Size = new System.Drawing.Size(75, 19);
this.radioButtonKeyboard.TabIndex = 0;
this.radioButtonKeyboard.TabStop = true;
this.radioButtonKeyboard.Text = "Keyboard";
this.radioButtonKeyboard.UseVisualStyleBackColor = true;
this.radioButtonKeyboard.CheckedChanged += new System.EventHandler(this.InputType_CheckedChanged);
//
// groupBoxCheats
//
this.groupBoxCheats.Controls.Add(this.textBoxKey);
this.groupBoxCheats.Controls.Add(this.textBoxNoClip);
this.groupBoxCheats.Controls.Add(this.textBoxTurbo);
this.groupBoxCheats.Controls.Add(this.textBoxLife);
this.groupBoxCheats.Controls.Add(this.labelKey);
this.groupBoxCheats.Controls.Add(this.labelTurbo);
this.groupBoxCheats.Controls.Add(this.labelNoClip);
this.groupBoxCheats.Controls.Add(this.labelLife);
this.groupBoxCheats.Location = new System.Drawing.Point(716, 249);
this.groupBoxCheats.Name = "groupBoxCheats";
this.groupBoxCheats.Size = new System.Drawing.Size(210, 140);
this.groupBoxCheats.TabIndex = 6;
this.groupBoxCheats.TabStop = false;
this.groupBoxCheats.Text = "Cheats";
//
// textBoxKey
//
this.textBoxKey.Location = new System.Drawing.Point(139, 51);
this.textBoxKey.Name = "textBoxKey";
this.textBoxKey.ReadOnly = true;
this.textBoxKey.Size = new System.Drawing.Size(63, 23);
this.textBoxKey.TabIndex = 1;
this.textBoxKey.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// textBoxNoClip
//
this.textBoxNoClip.Location = new System.Drawing.Point(139, 80);
this.textBoxNoClip.Name = "textBoxNoClip";
this.textBoxNoClip.ReadOnly = true;
this.textBoxNoClip.Size = new System.Drawing.Size(63, 23);
this.textBoxNoClip.TabIndex = 2;
this.textBoxNoClip.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.toolTip1.SetToolTip(this.textBoxNoClip, "Allows you to walk through walls");
//
// textBoxTurbo
//
this.textBoxTurbo.Location = new System.Drawing.Point(139, 109);
this.textBoxTurbo.Name = "textBoxTurbo";
this.textBoxTurbo.ReadOnly = true;
this.textBoxTurbo.Size = new System.Drawing.Size(63, 23);
this.textBoxTurbo.TabIndex = 3;
this.textBoxTurbo.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// textBoxLife
//
this.textBoxLife.Location = new System.Drawing.Point(139, 22);
this.textBoxLife.Name = "textBoxLife";
this.textBoxLife.ReadOnly = true;
this.textBoxLife.Size = new System.Drawing.Size(63, 23);
this.textBoxLife.TabIndex = 0;
this.textBoxLife.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// labelKey
//
this.labelKey.AutoSize = true;
this.labelKey.Location = new System.Drawing.Point(53, 54);
this.labelKey.Name = "labelKey";
this.labelKey.Size = new System.Drawing.Size(80, 15);
this.labelKey.TabIndex = 5;
this.labelKey.Text = "Give One Key:";
this.toolTip1.SetToolTip(this.labelKey, "If you have no keys, give yourself a single key.");
//
// labelTurbo
//
this.labelTurbo.AutoSize = true;
this.labelTurbo.Location = new System.Drawing.Point(92, 112);
this.labelTurbo.Name = "labelTurbo";
this.labelTurbo.Size = new System.Drawing.Size(41, 15);
this.labelTurbo.TabIndex = 5;
this.labelTurbo.Text = "Turbo:";
this.toolTip1.SetToolTip(this.labelTurbo, "The game plays at an extremely fast speed.");
//
// labelNoClip
//
this.labelNoClip.AutoSize = true;
this.labelNoClip.Location = new System.Drawing.Point(83, 83);
this.labelNoClip.Name = "labelNoClip";
this.labelNoClip.Size = new System.Drawing.Size(50, 15);
this.labelNoClip.TabIndex = 5;
this.labelNoClip.Text = "No Clip:";
this.toolTip1.SetToolTip(this.labelNoClip, "Allows you to walk through walls");
//
// labelLife
//
this.labelLife.AutoSize = true;
this.labelLife.Location = new System.Drawing.Point(46, 25);
this.labelLife.Name = "labelLife";
this.labelLife.Size = new System.Drawing.Size(87, 15);
this.labelLife.TabIndex = 5;
this.labelLife.Text = "Restore Health:";
this.toolTip1.SetToolTip(this.labelLife, "Restores all health. Holding \"Shift\" when pushing the button will refill your oth" +
"er resources.");
//
// groupBoxGame
//
this.groupBoxGame.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.groupBoxGame.Controls.Add(this.labelVolumeDown);
this.groupBoxGame.Controls.Add(this.labelVolumeUp);
this.groupBoxGame.Controls.Add(this.labelDecreaseWindowSize);
this.groupBoxGame.Controls.Add(this.labelIncreaseWindowSize);
this.groupBoxGame.Controls.Add(this.checkBoxDim);
this.groupBoxGame.Controls.Add(this.textBoxPause);
this.groupBoxGame.Controls.Add(this.labelPause);
this.groupBoxGame.Controls.Add(this.textBoxVolumeDown);
this.groupBoxGame.Controls.Add(this.textBoxVolumeUp);
this.groupBoxGame.Controls.Add(this.textBoxDecreaseWindowSize);
this.groupBoxGame.Controls.Add(this.textBoxIncreaseWindowSize);
this.groupBoxGame.Controls.Add(this.labelReset);
this.groupBoxGame.Controls.Add(this.textBoxReset);
this.groupBoxGame.Location = new System.Drawing.Point(716, 20);
this.groupBoxGame.Name = "groupBoxGame";
this.groupBoxGame.Size = new System.Drawing.Size(210, 223);
this.groupBoxGame.TabIndex = 4;
this.groupBoxGame.TabStop = false;
this.groupBoxGame.Text = "Game Functions";
//
// labelVolumeDown
//
this.labelVolumeDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.labelVolumeDown.AutoSize = true;
this.labelVolumeDown.Location = new System.Drawing.Point(47, 193);
this.labelVolumeDown.Name = "labelVolumeDown";
this.labelVolumeDown.Size = new System.Drawing.Size(84, 15);
this.labelVolumeDown.TabIndex = 7;
this.labelVolumeDown.Text = "Volume Down:";
this.labelVolumeDown.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.toolTip1.SetToolTip(this.labelVolumeDown, "Decreases the volume output of the game");
//
// labelVolumeUp
//
this.labelVolumeUp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.labelVolumeUp.AutoSize = true;
this.labelVolumeUp.Location = new System.Drawing.Point(63, 164);
this.labelVolumeUp.Name = "labelVolumeUp";
this.labelVolumeUp.Size = new System.Drawing.Size(68, 15);
this.labelVolumeUp.TabIndex = 7;
this.labelVolumeUp.Text = "Volume Up:";
this.labelVolumeUp.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.toolTip1.SetToolTip(this.labelVolumeUp, "Increases the volume output of the game");
//
// labelDecreaseWindowSize
//
this.labelDecreaseWindowSize.AutoSize = true;
this.labelDecreaseWindowSize.Location = new System.Drawing.Point(4, 135);
this.labelDecreaseWindowSize.Name = "labelDecreaseWindowSize";
this.labelDecreaseWindowSize.Size = new System.Drawing.Size(127, 15);
this.labelDecreaseWindowSize.TabIndex = 7;
this.labelDecreaseWindowSize.Text = "Decrease Window Size:";
this.labelDecreaseWindowSize.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.toolTip1.SetToolTip(this.labelDecreaseWindowSize, "Decrease window scale by a factor of 1");
//
// labelIncreaseWindowSize
//
this.labelIncreaseWindowSize.AutoSize = true;
this.labelIncreaseWindowSize.Location = new System.Drawing.Point(8, 106);
this.labelIncreaseWindowSize.Name = "labelIncreaseWindowSize";
this.labelIncreaseWindowSize.Size = new System.Drawing.Size(123, 15);
this.labelIncreaseWindowSize.TabIndex = 7;
this.labelIncreaseWindowSize.Text = "Increase Window Size:";
this.toolTip1.SetToolTip(this.labelIncreaseWindowSize, "Increase window scale by a factor of 1");
//
// checkBoxDim
//
this.checkBoxDim.AutoSize = true;
this.checkBoxDim.Location = new System.Drawing.Point(79, 78);
this.checkBoxDim.Name = "checkBoxDim";
this.checkBoxDim.Size = new System.Drawing.Size(123, 19);
this.checkBoxDim.TabIndex = 6;
this.checkBoxDim.Text = "Dim When Paused";
this.toolTip1.SetToolTip(this.checkBoxDim, "If enabled, the game will dim when paused via the special pause key");
this.checkBoxDim.UseVisualStyleBackColor = true;
//
// textBoxPause
//
this.textBoxPause.Location = new System.Drawing.Point(137, 49);
this.textBoxPause.Name = "textBoxPause";
this.textBoxPause.ReadOnly = true;
this.textBoxPause.Size = new System.Drawing.Size(65, 23);
this.textBoxPause.TabIndex = 1;
this.textBoxPause.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// labelPause
//
this.labelPause.AutoSize = true;
this.labelPause.Location = new System.Drawing.Point(90, 52);
this.labelPause.Name = "labelPause";
this.labelPause.Size = new System.Drawing.Size(41, 15);
this.labelPause.TabIndex = 5;
this.labelPause.Text = "Pause:";
this.toolTip1.SetToolTip(this.labelPause, "Pause the game without opening the menu");
//
// textBoxVolumeDown
//
this.textBoxVolumeDown.Location = new System.Drawing.Point(137, 190);
this.textBoxVolumeDown.Name = "textBoxVolumeDown";
this.textBoxVolumeDown.ReadOnly = true;
this.textBoxVolumeDown.Size = new System.Drawing.Size(65, 23);
this.textBoxVolumeDown.TabIndex = 5;
this.textBoxVolumeDown.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// textBoxVolumeUp
//
this.textBoxVolumeUp.Location = new System.Drawing.Point(137, 161);
this.textBoxVolumeUp.Name = "textBoxVolumeUp";
this.textBoxVolumeUp.ReadOnly = true;
this.textBoxVolumeUp.Size = new System.Drawing.Size(65, 23);
this.textBoxVolumeUp.TabIndex = 4;
this.textBoxVolumeUp.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// textBoxDecreaseWindowSize
//
this.textBoxDecreaseWindowSize.Location = new System.Drawing.Point(137, 132);
this.textBoxDecreaseWindowSize.Name = "textBoxDecreaseWindowSize";
this.textBoxDecreaseWindowSize.ReadOnly = true;
this.textBoxDecreaseWindowSize.Size = new System.Drawing.Size(65, 23);
this.textBoxDecreaseWindowSize.TabIndex = 3;
this.textBoxDecreaseWindowSize.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// textBoxIncreaseWindowSize
//
this.textBoxIncreaseWindowSize.Location = new System.Drawing.Point(137, 103);
this.textBoxIncreaseWindowSize.Name = "textBoxIncreaseWindowSize";
this.textBoxIncreaseWindowSize.ReadOnly = true;
this.textBoxIncreaseWindowSize.Size = new System.Drawing.Size(65, 23);
this.textBoxIncreaseWindowSize.TabIndex = 2;
this.textBoxIncreaseWindowSize.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// labelReset
//
this.labelReset.AutoSize = true;
this.labelReset.Location = new System.Drawing.Point(93, 23);
this.labelReset.Name = "labelReset";
this.labelReset.Size = new System.Drawing.Size(38, 15);
this.labelReset.TabIndex = 7;
this.labelReset.Text = "Reset:";
this.toolTip1.SetToolTip(this.labelReset, "Reset the game");
//
// textBoxReset
//
this.textBoxReset.Location = new System.Drawing.Point(137, 20);
this.textBoxReset.Name = "textBoxReset";
this.textBoxReset.ReadOnly = true;
this.textBoxReset.Size = new System.Drawing.Size(65, 23);
this.textBoxReset.TabIndex = 0;
this.textBoxReset.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// labelReplayToggle
//
this.labelReplayToggle.AutoSize = true;
this.labelReplayToggle.Location = new System.Drawing.Point(10, 21);
this.labelReplayToggle.Name = "labelReplayToggle";
this.labelReplayToggle.Size = new System.Drawing.Size(118, 15);
this.labelReplayToggle.TabIndex = 5;
this.labelReplayToggle.Text = "Toggle Replay Speed:";
this.toolTip1.SetToolTip(this.labelReplayToggle, "Toggle between Turbo and regular speed of the replays.");
//
// labelStopReplay
//
this.labelStopReplay.AutoSize = true;
this.labelStopReplay.Location = new System.Drawing.Point(205, 21);
this.labelStopReplay.Name = "labelStopReplay";
this.labelStopReplay.Size = new System.Drawing.Size(72, 15);
this.labelStopReplay.TabIndex = 5;
this.labelStopReplay.Text = "Stop Replay:";
this.toolTip1.SetToolTip(this.labelStopReplay, "Stop the current replay in progress.");
//
// buttonSave
//
this.buttonSave.Location = new System.Drawing.Point(716, 440);
this.buttonSave.Name = "buttonSave";
this.buttonSave.Size = new System.Drawing.Size(210, 40);
this.buttonSave.TabIndex = 1;
this.buttonSave.Text = "Save";
this.toolTip1.SetToolTip(this.buttonSave, "Save all controller settings and close menu");
this.buttonSave.UseVisualStyleBackColor = true;
this.buttonSave.Click += new System.EventHandler(this.buttonSave_Click);
//
// buttonReset
//
this.buttonReset.Location = new System.Drawing.Point(716, 395);
this.buttonReset.Name = "buttonReset";
this.buttonReset.Size = new System.Drawing.Size(210, 40);
this.buttonReset.TabIndex = 2;
this.buttonReset.Text = "Reset";
this.toolTip1.SetToolTip(this.buttonReset, "Reset all controller related settings");
this.buttonReset.UseVisualStyleBackColor = true;
this.buttonReset.Click += new System.EventHandler(this.buttonReset_Click);
//
// buttonCancel
//
this.buttonCancel.Location = new System.Drawing.Point(716, 485);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(210, 40);
this.buttonCancel.TabIndex = 0;
this.buttonCancel.Text = "Cancel";
this.toolTip1.SetToolTip(this.buttonCancel, "Close keymapping utility without saving any changes");
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
//
// textBoxToggleReplay
//
this.textBoxToggleReplay.Location = new System.Drawing.Point(134, 17);
this.textBoxToggleReplay.Name = "textBoxToggleReplay";
this.textBoxToggleReplay.ReadOnly = true;
this.textBoxToggleReplay.Size = new System.Drawing.Size(65, 23);
this.textBoxToggleReplay.TabIndex = 0;
this.textBoxToggleReplay.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// textBoxStopReplay
//
this.textBoxStopReplay.Location = new System.Drawing.Point(283, 17);
this.textBoxStopReplay.Name = "textBoxStopReplay";
this.textBoxStopReplay.ReadOnly = true;
this.textBoxStopReplay.Size = new System.Drawing.Size(65, 23);
this.textBoxStopReplay.TabIndex = 1;
this.textBoxStopReplay.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// groupBoxReplays
//
this.groupBoxReplays.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.groupBoxReplays.Controls.Add(this.textBoxToggleReplay);
this.groupBoxReplays.Controls.Add(this.labelReplayToggle);
this.groupBoxReplays.Controls.Add(this.textBoxStopReplay);
this.groupBoxReplays.Controls.Add(this.labelStopReplay);
this.groupBoxReplays.Location = new System.Drawing.Point(12, 347);
this.groupBoxReplays.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0);
this.groupBoxReplays.Name = "groupBoxReplays";
this.groupBoxReplays.Padding = new System.Windows.Forms.Padding(3, 3, 3, 0);
this.groupBoxReplays.Size = new System.Drawing.Size(360, 49);
this.groupBoxReplays.TabIndex = 5;
this.groupBoxReplays.TabStop = false;
this.groupBoxReplays.Text = "Replays";
//
// labelReplaysNote
//
this.labelReplaysNote.Font = new System.Drawing.Font("Lucida Sans Typewriter", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
this.labelReplaysNote.Location = new System.Drawing.Point(6, 39);
this.labelReplaysNote.Name = "labelReplaysNote";
this.labelReplaysNote.Size = new System.Drawing.Size(686, 80);
this.labelReplaysNote.TabIndex = 7;
this.labelReplaysNote.Text = resources.GetString("labelReplaysNote.Text");
//
// groupBoxReplayControls
//
this.groupBoxReplayControls.Controls.Add(this.labelReplaysNote);
this.groupBoxReplayControls.Controls.Add(this.label1);
this.groupBoxReplayControls.Location = new System.Drawing.Point(12, 399);
this.groupBoxReplayControls.Name = "groupBoxReplayControls";
this.groupBoxReplayControls.Size = new System.Drawing.Size(698, 126);
this.groupBoxReplayControls.TabIndex = 7;
this.groupBoxReplayControls.TabStop = false;
this.groupBoxReplayControls.Text = "Replay Controls";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Segoe UI", 9F, ((System.Drawing.FontStyle)((System.Drawing.FontStyle.Bold | System.Drawing.FontStyle.Underline))), System.Drawing.GraphicsUnit.Point);
this.label1.Location = new System.Drawing.Point(6, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(426, 15);
this.label1.TabIndex = 0;
this.label1.Text = "The game has an integrated replay/savestate system. Here are the controls:";
//
// groupBoxPerformance
//
this.groupBoxPerformance.Controls.Add(this.labelToggleRenderer);
this.groupBoxPerformance.Controls.Add(this.labelToggleFPS);
this.groupBoxPerformance.Controls.Add(this.textBoxRenderer);
this.groupBoxPerformance.Controls.Add(this.textBoxFPS);
this.groupBoxPerformance.Location = new System.Drawing.Point(378, 347);
this.groupBoxPerformance.Name = "groupBoxPerformance";
this.groupBoxPerformance.Size = new System.Drawing.Size(332, 49);
this.groupBoxPerformance.TabIndex = 8;
this.groupBoxPerformance.TabStop = false;
this.groupBoxPerformance.Text = "Performance";
//
// labelToggleRenderer
//
this.labelToggleRenderer.AutoSize = true;
this.labelToggleRenderer.Location = new System.Drawing.Point(11, 21);
this.labelToggleRenderer.Name = "labelToggleRenderer";
this.labelToggleRenderer.Size = new System.Drawing.Size(95, 15);
this.labelToggleRenderer.TabIndex = 9;
this.labelToggleRenderer.Text = "Toggle Renderer:";
//
// labelToggleFPS
//
this.labelToggleFPS.AutoSize = true;
this.labelToggleFPS.Location = new System.Drawing.Point(183, 21);
this.labelToggleFPS.Name = "labelToggleFPS";
this.labelToggleFPS.Size = new System.Drawing.Size(64, 15);
this.labelToggleFPS.TabIndex = 10;
this.labelToggleFPS.Text = "ToggleFPS:";
//
// textBoxRenderer
//
this.textBoxRenderer.Location = new System.Drawing.Point(112, 17);
this.textBoxRenderer.Name = "textBoxRenderer";
this.textBoxRenderer.ReadOnly = true;
this.textBoxRenderer.Size = new System.Drawing.Size(65, 23);
this.textBoxRenderer.TabIndex = 0;
this.textBoxRenderer.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// textBoxFPS
//
this.textBoxFPS.Location = new System.Drawing.Point(253, 17);
this.textBoxFPS.Name = "textBoxFPS";
this.textBoxFPS.ReadOnly = true;
this.textBoxFPS.Size = new System.Drawing.Size(65, 23);
this.textBoxFPS.TabIndex = 0;
this.textBoxFPS.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// contextMenuStrip1
//
this.contextMenuStrip1.Name = "contextMenuStrip1";
this.contextMenuStrip1.Size = new System.Drawing.Size(61, 4);
//
// keymapper
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ClientSize = new System.Drawing.Size(975, 569);
this.Controls.Add(this.groupBoxPerformance);
this.Controls.Add(this.groupBoxReplayControls);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonReset);
this.Controls.Add(this.buttonSave);
this.Controls.Add(this.groupBoxReplays);
this.Controls.Add(this.groupBoxGame);
this.Controls.Add(this.groupBoxCheats);
this.Controls.Add(this.groupBoxController);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "keymapper";
this.Padding = new System.Windows.Forms.Padding(6);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Keymapper Utility";
((System.ComponentModel.ISupportInitialize)(this.pictureController)).EndInit();
this.groupBoxController.ResumeLayout(false);
this.groupBoxController.PerformLayout();
this.groupBoxInput.ResumeLayout(false);
this.groupBoxInput.PerformLayout();
this.groupBoxCheats.ResumeLayout(false);
this.groupBoxCheats.PerformLayout();
this.groupBoxGame.ResumeLayout(false);
this.groupBoxGame.PerformLayout();
this.groupBoxReplays.ResumeLayout(false);
this.groupBoxReplays.PerformLayout();
this.groupBoxReplayControls.ResumeLayout(false);
this.groupBoxReplayControls.PerformLayout();
this.groupBoxPerformance.ResumeLayout(false);
this.groupBoxPerformance.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private PictureBox pictureController;
private TextBox textBoxDpadLeft;
private TextBox textBoxDpadRight;
private TextBox textBoxDpadUp;
private TextBox textBoxDpadDown;
private TextBox textBoxSelect;
private TextBox textBoxStart;
private TextBox textBoxY;
private TextBox textBoxA;
private TextBox textBoxX;
private TextBox textBoxB;
private TextBox textBoxL;
private TextBox textBoxR;
private GroupBox groupBoxController;
private GroupBox groupBoxCheats;
private TextBox textBoxKey;
private TextBox textBoxNoClip;
private ToolTip toolTip1;
private TextBox textBoxTurbo;
private TextBox textBoxLife;
private Label labelKey;
private Label labelTurbo;
private Label labelNoClip;
private Label labelLife;
private GroupBox groupBoxMisc;
private TextBox textBoxPause;
private Label labelPause;
private TextBox textBoxReset;
private TextBox textBoxToggleReplay;
private Label labelReset;
private Label labelReplayToggle;
private GroupBox groupBoxGame;
private Label labelStopReplay;
private TextBox textBoxStopReplay;
private GroupBox groupBoxReplays;
private Label labelVolumeDown;
private Label labelVolumeUp;
private Label labelDecreaseWindowSize;
private Label labelIncreaseWindowSize;
private CheckBox checkBoxDim;
private TextBox textBoxVolumeDown;
private TextBox textBoxVolumeUp;
private TextBox textBoxDecreaseWindowSize;
private TextBox textBoxIncreaseWindowSize;
private Label labelReplaysNote;
private Button buttonSave;
private Button buttonReset;
private Button buttonCancel;
private GroupBox groupBoxReplayControls;
private Label label1;
private GroupBox groupBoxInput;
private RadioButton radioButtonController;
private RadioButton radioButtonKeyboard;
private GroupBox groupBoxPerformance;
private Label labelToggleRenderer;
private Label labelToggleFPS;
private TextBox textBoxRenderer;
private TextBox textBoxFPS;
private ContextMenuStrip contextMenuStrip1;
private Button buttonAssignAll;
}
}

View File

@ -0,0 +1,662 @@
using IniParser;
using IniParser.Model;
using IniParser.Model.Configuration;
using IniParser.Parser;
using Microsoft.VisualBasic.Devices;
using SDL2;
using System.Net.Quic;
using System.Text;
using XAct;
namespace Zelda_3_Launcher
{
public partial class keymapper : Form
{
bool changed = false;
IniData settings = new IniData();
string iniFile = Path.Combine(Program.repoDir, "zelda3.ini");
MyController controller = new MyController();
public keymapper()
{
InitializeComponent();
ImportINI();
if (controller.connected)
{
radioButtonController.Enabled = true;
radioButtonController.Checked = true;
}
// Controller specific inputs since both keyboard and controller inputs can be set simultaneously
textBoxDpadLeft.Click += ControllerMappings_Click;
textBoxDpadUp.Click += ControllerMappings_Click;
textBoxDpadDown.Click += ControllerMappings_Click;
textBoxDpadRight.Click += ControllerMappings_Click;
textBoxSelect.Click += ControllerMappings_Click;
textBoxStart.Click += ControllerMappings_Click;
textBoxA.Click += ControllerMappings_Click;
textBoxB.Click += ControllerMappings_Click;
textBoxX.Click += ControllerMappings_Click;
textBoxY.Click += ControllerMappings_Click;
textBoxL.Click += ControllerMappings_Click;
textBoxR.Click += ControllerMappings_Click;
// All other inputs can only be one key/button at a time
textBoxReset.Click += AssortedMappings_Click;
textBoxPause.Click += AssortedMappings_Click;
textBoxIncreaseWindowSize.Click += AssortedMappings_Click;
textBoxDecreaseWindowSize.Click += AssortedMappings_Click;
textBoxVolumeDown.Click += AssortedMappings_Click;
textBoxVolumeUp.Click += AssortedMappings_Click;
textBoxLife.Click += AssortedMappings_Click;
textBoxKey.Click += AssortedMappings_Click;
textBoxNoClip.Click += AssortedMappings_Click;
textBoxTurbo.Click += AssortedMappings_Click;
textBoxRenderer.Click += AssortedMappings_Click;
textBoxFPS.Click += AssortedMappings_Click;
textBoxToggleReplay.Click += AssortedMappings_Click;
textBoxStopReplay.Click += AssortedMappings_Click;
}
private void AssortedMappings_Click(object? sender, EventArgs e)
{
EnableWindow(false);
AssortedMappings(sender);
EnableWindow(true);
}
private void AssortedMappings(object? sender)
{
TextBox textBox = sender as TextBox;
var original = textBox.Text;
string result;
var leftTrigger = false;
var rightTrigger = false;
// Clear textbox
textBox.Text = "";
this.Refresh();
SDL.SDL_PumpEvents();
SDL.SDL_FlushEvents(SDL.SDL_EventType.SDL_FIRSTEVENT, SDL.SDL_EventType.SDL_LASTEVENT);
var window = SDL.SDL_CreateWindow("Awaiting input...", Form.ActiveForm.Location.X + 292, Form.ActiveForm.Location.Y + 199, 150, 50,
SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_GRABBED |
SDL.SDL_WindowFlags.SDL_WINDOW_BORDERLESS |
SDL.SDL_WindowFlags.SDL_WINDOW_ALWAYS_ON_TOP);
SDL.SDL_ShowCursor(SDL.SDL_DISABLE);
var stop = DateTime.Now.AddSeconds(5);
while (true)
{
SDL.SDL_Event ev;
// Wait for an event to occur
SDL.SDL_PollEvent(out ev);
switch (ev.type)
{
case SDL.SDL_EventType.SDL_KEYDOWN:
if (SDL.SDL_GetKeyName(ev.key.keysym.sym) == "Escape")
{
textBox.Text = original;
SDL.SDL_DestroyWindow(window);
return;
}
else
{
textBox.Text = FormatKeyInput(ev.key.keysym.sym);
SDL.SDL_DestroyWindow(window);
return;
}
case SDL.SDL_EventType.SDL_CONTROLLERBUTTONDOWN:
textBox.Text = (MyController.ConvertButtonID(ev.cbutton.button));
SDL.SDL_DestroyWindow(window);
return;
case SDL.SDL_EventType.SDL_CONTROLLERAXISMOTION:
if (ev.caxis.axis == ((byte)SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT) && ev.caxis.axisValue == 0 && leftTrigger)
{
textBox.Text = "L2";
SDL.SDL_DestroyWindow(window);
return;
}
else if (ev.caxis.axis == ((byte)SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT) && ev.caxis.axisValue == 0 && rightTrigger)
{
textBox.Text = "R2";
SDL.SDL_DestroyWindow(window);
return;
}
else if (ev.caxis.axis == ((byte)SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERLEFT))
{
leftTrigger = true;
}
else if (ev.caxis.axis == ((byte)SDL.SDL_GameControllerAxis.SDL_CONTROLLER_AXIS_TRIGGERRIGHT))
{
rightTrigger = true;
}
break;
}
if (DateTime.Now >= stop)
{
textBox.Text = original;
SDL.SDL_DestroyWindow(window);
return;
}
}
}
private string? FormatKeyInput(SDL.SDL_Keycode key)
{
var result = SDL.SDL_GetKeyName(key);
if (result.Length.Equals(1))
{
result = result.ToLower();
}
if (result.Contains("Shift"))
{
MessageBox.Show("The Shift keys are not recognized by zelda3.exe and thus cannot be used.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
if (result.Contains("Ctrl"))
{
MessageBox.Show("The Control keys are not recognized by zelda3.exe and thus cannot be used.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
if (result.Contains("Alt"))
{
MessageBox.Show("The Alt keys are not recognized by zelda3.exe and thus cannot be used.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
if (result.Contains("F") && result.Length == 2 | result.Length == 3)
{
MessageBox.Show("The function keys are utilized by zelda3.exe's replay/savestate functionality and thus cannot be used for other inputs.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
if (result.IsNumeric())
{
MessageBox.Show("The number keys are utilized by zelda3.exe's replay/savestate functionality and thus cannot be used for other inputs.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
if (result.Equals("-") | result.Equals("=") | result.Equals("Backspace"))
{
MessageBox.Show("The " + result + " key is utilized by zelda3.exe's replay/savestate functionality and thus cannot be used for other inputs.", "Invalid Input", MessageBoxButtons.OK, MessageBoxIcon.Error);
return null;
}
return result;
}
private void ControllerMappings_Click(object? sender, EventArgs e)
{
EnableWindow(false);
ControllerMappings(sender);
EnableWindow(true);
}
private void ControllerMappings(object? sender)
{
TextBox textBox = sender as TextBox;
var original = textBox.Text;
string result;
var selection = groupBoxInput.Controls.OfType<RadioButton>()
.FirstOrDefault(n => n.Checked).Text;
// Clear textbox
textBox.Text = "";
this.Refresh();
if (selection == "Controller") result = controller.GetButtonName();
else result = GetKeyInput();
if (result is null) textBox.Text = original;
else
{
textBox.Text = result;
changed = true;
}
}
private string? GetKeyInput()
{
SDL.SDL_PumpEvents();
SDL.SDL_FlushEvent(SDL.SDL_EventType.SDL_CONTROLLERBUTTONDOWN);
var window = SDL.SDL_CreateWindow("Awaiting input...", Form.ActiveForm.Location.X + 292, Form.ActiveForm.Location.Y + 199, 150, 50,
SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_GRABBED |
SDL.SDL_WindowFlags.SDL_WINDOW_BORDERLESS |
SDL.SDL_WindowFlags.SDL_WINDOW_ALWAYS_ON_TOP);
SDL.SDL_ShowCursor(SDL.SDL_DISABLE);
var stop = DateTime.Now.AddSeconds(5);
while (true)
{
SDL.SDL_Event ek;
// Wait for an event to occur
SDL.SDL_PollEvent(out ek);
// Check if the event was a joystick button press
if (ek.type == SDL.SDL_EventType.SDL_KEYDOWN)
{
if (SDL.SDL_GetKeyName(ek.key.keysym.sym) == "Escape")
{
SDL.SDL_DestroyWindow(window);
return null;
}
else
{
SDL.SDL_DestroyWindow(window);
return FormatKeyInput(ek.key.keysym.sym);
}
}
if (DateTime.Now >= stop)
{
SDL.SDL_DestroyWindow(window);
return null;
}
}
}
private void SaveINI()
{
var selection = groupBoxInput.Controls.OfType<RadioButton>()
.FirstOrDefault(n => n.Checked).Text;
SaveControllerSettings(selection);
SaveAdditionalSettings();
FileINI();
}
private void SaveAdditionalSettings()
{
settings["KeyMap"]["CheatLife"] = textBoxLife.Text;
settings["KeyMap"]["CheatKeys"] = textBoxKey.Text;
settings["KeyMap"]["CheatWalkThroughWalls"] = textBoxNoClip.Text;
settings["KeyMap"]["StopReplay"] = textBoxStopReplay.Text;
settings["KeyMap"]["Reset"] = textBoxReset.Text;
settings["KeyMap"]["Turbo"] = textBoxTurbo.Text;
settings["KeyMap"]["ReplayTurbo"] = textBoxToggleReplay.Text;
settings["KeyMap"]["WindowBigger"] = textBoxIncreaseWindowSize.Text;
settings["KeyMap"]["WindowSmaller"] = textBoxDecreaseWindowSize.Text;
settings["KeyMap"]["VolumeUp"] = textBoxVolumeUp.Text;
settings["KeyMap"]["VolumeDown"] = textBoxVolumeDown.Text;
settings["KeyMap"]["ToggleRenderer"] = textBoxRenderer.Text;
settings["KeyMap"]["DisplayPerf"] = textBoxFPS.Text;
if (checkBoxDim.Checked)
{
settings["KeyMap"]["Pause"] = "Shift+" + textBoxPause.Text;
settings["KeyMap"]["PauseDimmed"] = textBoxPause.Text;
}
else
{
settings["KeyMap"]["PauseDimmed"] = "Shift+" + textBoxPause.Text;
settings["KeyMap"]["Pause"] = textBoxPause.Text;
}
}
private void ImportINI()
{
// Check for INI and if missing restore from initial install backup
if (!File.Exists(iniFile))
{
var iniBackup = Path.Combine(Program.repoDir, "saves", "zelda3.ini");
if (!File.Exists(iniBackup)) settingsForm.DownloadFreshINI();
using (var modifiedFile = File.AppendText(iniFile))
{
foreach (var line in File.ReadLines(iniBackup))
{
if (!line.Equals("# Change the appearance of Link by loading a ZSPR file") &&
!line.Equals("# See all sprites here: https://snesrev.github.io/sprites-gfx/snes/zelda3/link/") &&
!line.Equals("# Download the files with \"git clone https://github.com/snesrev/sprites-gfx.git\"") &&
!line.Equals("# LinkGraphics = sprites-gfx/snes/zelda3/link/sheets/megaman-x.2.zspr") &&
!line.Equals("# This default is suitable for QWERTZ keyboards.") &&
!line.Equals("#Controls = Up, Down, Left, Right, Right Shift, Return, x, y, s, a, c, v") &&
!line.Equals("# This one is suitable for AZERTY keyboards.") &&
!line.Equals("#Controls = Up, Down, Left, Right, Right Shift, Return, x, w, s, q, c, v"))
{
modifiedFile.WriteLine(line);
}
}
}
}
var iniText = File.ReadAllText(iniFile);
// INI parsing
var config = new IniParserConfiguration();
config.CommentString = "#";
var parser = new IniDataParser(config);
settings = parser.Parse(iniText);
// KeyMap Settings
DisplayController();
// Additional Settings
textBoxLife.Text = settings["KeyMap"]["CheatLife"];
textBoxKey.Text = settings["KeyMap"]["CheatKeys"];
textBoxNoClip.Text = settings["KeyMap"]["CheatWalkThroughWalls"];
textBoxStopReplay.Text = settings["KeyMap"]["StopReplay"];
textBoxReset.Text = settings["KeyMap"]["Reset"];
textBoxTurbo.Text = settings["KeyMap"]["Turbo"];
textBoxToggleReplay.Text = settings["KeyMap"]["ReplayTurbo"];
textBoxIncreaseWindowSize.Text = settings["KeyMap"]["WindowBigger"];
textBoxDecreaseWindowSize.Text = settings["KeyMap"]["WindowSmaller"];
textBoxVolumeUp.Text = settings["KeyMap"]["VolumeUp"];
textBoxVolumeDown.Text = settings["KeyMap"]["VolumeDown"];
if (settings["KeyMap"]["ToggleRenderer"] != null)
{
textBoxRenderer.Text = settings["KeyMap"]["ToggleRenderer"];
}
else
{
textBoxRenderer.Text = "r";
}
if (settings["KeyMap"]["DisplayPerf"] != null)
{
textBoxFPS.Text = settings["KeyMap"]["DisplayPerf"];
}
else
{
textBoxFPS.Text = "f";
}
if (settings["KeyMap"]["Pause"].Contains("Shift"))
{
checkBoxDim.Checked = true;
textBoxPause.Text = settings["KeyMap"]["PauseDimmed"];
}
else
{
checkBoxDim.Checked = false;
textBoxPause.Text = settings["KeyMap"]["Pause"];
}
}
private void DisplayController()
{
var selection = groupBoxInput.Controls.OfType<RadioButton>()
.FirstOrDefault(n => n.Checked).Text;
if (selection == "Controller")
{
var controllerControls = settings["GamepadMap"]["Controls"].Replace(" ", "").Split(",");
textBoxDpadUp.Text = controllerControls[0];
textBoxDpadDown.Text = controllerControls[1];
textBoxDpadLeft.Text = controllerControls[2];
textBoxDpadRight.Text = controllerControls[3];
textBoxSelect.Text = controllerControls[4];
textBoxStart.Text = controllerControls[5];
textBoxA.Text = controllerControls[6];
textBoxB.Text = controllerControls[7];
textBoxX.Text = controllerControls[8];
textBoxY.Text = controllerControls[9];
textBoxL.Text = controllerControls[10];
textBoxR.Text = controllerControls[11];
}
else
{
var keyControls = settings["KeyMap"]["Controls"].Replace(" ", "").Split(",");
textBoxDpadUp.Text = keyControls[0];
textBoxDpadDown.Text = keyControls[1];
textBoxDpadLeft.Text = keyControls[2];
textBoxDpadRight.Text = keyControls[3];
textBoxSelect.Text = keyControls[4];
textBoxStart.Text = keyControls[5];
textBoxA.Text = keyControls[6];
textBoxB.Text = keyControls[7];
textBoxX.Text = keyControls[8];
textBoxY.Text = keyControls[9];
textBoxL.Text = keyControls[10];
textBoxR.Text = keyControls[11];
if (textBoxSelect.Text.Contains("Shift")) textBoxSelect.Text = @"\";
}
}
private void InputType_CheckedChanged(object sender, EventArgs e)
{
var selection = groupBoxInput.Controls.OfType<RadioButton>()
.FirstOrDefault(n => !n.Checked).Text;
if (changed)
{
var answer = MessageBox.Show("Do you want to save your changes to " + selection + " settings?", "Save Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
if (answer == DialogResult.Yes)
{
SaveControllerSettings(selection);
FileINI();
}
}
DisplayController();
}
private void FileINI()
{
var filer = new FileIniDataParser();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
filer.WriteFile(iniFile, settings, Encoding.GetEncoding(1252));
}
private void SaveControllerSettings(string selection)
{
if (selection == "Controller")
{
settings["GamepadMap"]["Controls"] =
textBoxDpadUp.Text + ", " +
textBoxDpadDown.Text + ", " +
textBoxDpadLeft.Text + ", " +
textBoxDpadRight.Text + ", " +
textBoxSelect.Text + ", " +
textBoxStart.Text + ", " +
textBoxA.Text + ", " +
textBoxB.Text + ", " +
textBoxX.Text + ", " +
textBoxY.Text + ", " +
textBoxL.Text + ", " +
textBoxR.Text;
}
else
{
settings["KeyMap"]["Controls"] =
textBoxDpadUp.Text + ", " +
textBoxDpadDown.Text + ", " +
textBoxDpadLeft.Text + ", " +
textBoxDpadRight.Text + ", " +
textBoxSelect.Text + ", " +
textBoxStart.Text + ", " +
textBoxA.Text + ", " +
textBoxB.Text + ", " +
textBoxX.Text + ", " +
textBoxY.Text + ", " +
textBoxL.Text + ", " +
textBoxR.Text;
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
SaveINI();
this.Close();
}
private void buttonReset_Click(object sender, EventArgs e)
{
RestoreFromBackupINI();
FileINI();
ImportINI();
}
private void RestoreFromBackupINI()
{
var iniBackup = Path.Combine(Program.repoDir, "saves", "zelda3.ini");
if (!File.Exists(iniBackup)) settingsForm.DownloadFreshINI();
var iniText = File.ReadAllText(iniBackup);
// INI parsing
var config = new IniParserConfiguration();
config.CommentString = "#";
var parser = new IniDataParser(config);
var backupSettings = parser.Parse(iniText);
foreach (var option in backupSettings["KeyMap"])
{
settings["KeyMap"][option.KeyName] = option.Value;
}
foreach (var option in backupSettings["GamepadMap"])
{
settings["GamepadMap"][option.KeyName] = option.Value;
}
}
private void buttonCancel_Click(object sender, EventArgs e)
{
var answer = MessageBox.Show("The changes that you have made will not be saved.\n\nDo you wish to continue?", "Confirmation", MessageBoxButtons.YesNo);
if (answer == DialogResult.No) return;
this.Close();
}
private void buttonAssignAll_Click(object sender, EventArgs e)
{
EnableWindow(false);
var selection = groupBoxInput.Controls.OfType<RadioButton>()
.FirstOrDefault(n => n.Checked).Text;
// Controller assignments
buttonAssignAll.Text = "Up";
ControllerMappings(textBoxDpadUp);
buttonAssignAll.Text = "Down";
ControllerMappings(textBoxDpadDown);
buttonAssignAll.Text = "Left";
ControllerMappings(textBoxDpadLeft);
buttonAssignAll.Text = "Right";
ControllerMappings(textBoxDpadRight);
buttonAssignAll.Text = "Select";
ControllerMappings(textBoxSelect);
buttonAssignAll.Text = "Start";
ControllerMappings(textBoxStart);
buttonAssignAll.Text = "A";
ControllerMappings(textBoxA);
buttonAssignAll.Text = "B";
ControllerMappings(textBoxB);
buttonAssignAll.Text = "X";
ControllerMappings(textBoxX);
buttonAssignAll.Text = "Y";
ControllerMappings(textBoxY);
buttonAssignAll.Text = "L";
ControllerMappings(textBoxL);
buttonAssignAll.Text = "R";
ControllerMappings(textBoxR);
// Assorted functionality assignments
buttonAssignAll.Text = "Reset";
AssortedMappings(textBoxReset);
buttonAssignAll.Text = "Pause";
AssortedMappings(textBoxPause);
buttonAssignAll.Text = "Increase Window Size";
AssortedMappings(textBoxIncreaseWindowSize);
buttonAssignAll.Text = "Decrease Window Size";
AssortedMappings(textBoxDecreaseWindowSize);
buttonAssignAll.Text = "Volume Up";
AssortedMappings(textBoxVolumeUp);
buttonAssignAll.Text = "Volume Down";
AssortedMappings(textBoxVolumeDown);
buttonAssignAll.Text = "Restore Health";
AssortedMappings(textBoxLife);
buttonAssignAll.Text = "One Key";
AssortedMappings(textBoxKey);
buttonAssignAll.Text = "No Clip";
AssortedMappings(textBoxNoClip);
buttonAssignAll.Text = "Turbo";
AssortedMappings(textBoxTurbo);
buttonAssignAll.Text = "Toggle Replay Speed";
AssortedMappings(textBoxToggleReplay);
buttonAssignAll.Text = "Stop Replay";
AssortedMappings(textBoxStopReplay);
buttonAssignAll.Text = "Toggle Renderer";
AssortedMappings(textBoxRenderer);
buttonAssignAll.Text = "Toggle FPS";
AssortedMappings(textBoxFPS);
buttonAssignAll.Text = "Assign All";
EnableWindow(true);
}
private void EnableWindow(bool input)
{
groupBoxCheats.Enabled = input;
groupBoxController.Enabled = input;
groupBoxGame.Enabled = input;
groupBoxReplays.Enabled = input;
groupBoxPerformance.Enabled = input;
buttonReset.Enabled = input;
buttonCancel.Enabled = input;
buttonSave.Enabled = input;
}
}
}

View File

@ -0,0 +1,465 @@
<root>
<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>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="pictureController.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
Ruji0x+gNIPXsLGIiPb91qC115aBZlY/8r8nn3ySm+Mz00wzjfvPf/5TuR0NTF555ZVKLc1VV11V02ej
jTaqVsaN23333Stt3/2uLkYfN+7DDz8cN/nkk9f0f+ghbXv/abLB7rPPPlttGZ+lllqq5n6iQdW///3v
ao9x4/773/+Om2SSSXr10wA1yscffzxu7rnnrul7/fXXV6u10YAz7bfSStpJunc0yE373XijDgz2zoEH
HljTb6i+/nVtwDU+++2337hzztEqZuOz1lpr1fT9/e+1r0DvrL322jX9nnrqqWplXK/vp36GymuvvVbT
nrrvvvsqfZQZZpihp12D/74y5ZRT9vSbYIIJxr344ouV9scee6zSNttss4375JNPKm1777232jxwtSEj
Whar53euD12x5BqZFtqk4KSoXkRhY9GQY/EsvIWrWYOQmoHrjjtqlZTx2WSTTdShRjZw/de//tWrltGR
sw8++KDS79prr620/fGP2qRp3LjLLrusV//8wHXjjTeuDJY0CE0TDVwXXli7ktYmf/RQ0oHrrbfeOu4X
v9CupOOzzTbb1PRNB65f+9rXxv3vfxofjRv3yCOP1PRLB646CpnWUunAVd/TbKD94IMPhv3rVc/AVYPD
z3/+89XquMr3YezYsb2OqjZr4Cr6fAcddFC1Om7cEUccUWnTYDXtpyP+igars8wyS2WwquiNVfUxPXC1
ISM6g6sLlGp+7xIPRvfrVGR6aHe9I6N60YSNRUK0bIqWa6lZVNvMhofUDFx/9jPtFDpu3EcffdTryKgM
ZuAqV199daXfu+++WxlIZtlwww179c0PXI8++ujKIDWfaOC65ZZbVqufZtttt+3VLx24/vSnPx23117a
5n98dtlll5q+6cBVp6z1f1CeeeaZmn5DGbgussgi4955553KbQ3mo/71qmfgKpqqkUWn3fN1aebAVfSG
IIsGsfm6rLHGGtUe4yrTT+68887K7Ztvvjnr44GrDQs5t/q7FDk0uk8nI7Phz6jsnFdkYWNRkK9BW5XN
E9XNbOhIzcD1zTffrPx7yy23qNjLYAeuO+ygbeXHRwMN5Y033uh1ZE/yA9frrrtu3Pbbb1/96NNEA1cd
rVP09fzzn/+s3D722GN79SvSwDV7vHYccZWyDFw1Hzb7fbztttt6prDod6PaxwNXGxaijT16fudylo/u
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
UdjHF0X33wAAAABJRU5ErkJggg==
</value>
</data>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<data name="pictureController.ToolTip" xml:space="preserve">
<value>When you click on one of the fields for a given input selection, you will have 5 seconds to hit a key or button on your controller to set the value. If you let the time expire, the setting will not be changed.</value>
</data>
<data name="groupBoxController.ToolTip" xml:space="preserve">
<value>When you click on one of the fields for a given input selection, you will have 5 seconds to hit a key or button on your controller to set the value. If you let the time expire, the setting will not be changed.</value>
</data>
<data name="labelReplaysNote.Text" xml:space="preserve">
<value> 1 - Backspace: Built-in post-dunegon savestates/replays
F1 - F10: Personal savestates/replays
Shift+F1 - F10: Saves a savestate/replay to the pressed function key.
Ctrl: When pressed with a function or preset key, replays the game up to point of the savestate rather than immediately load the savestate.</value>
</data>
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>114, 17</value>
</metadata>
</root>

View File

@ -1,24 +1,10 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Permissions;
using System.Runtime.CompilerServices;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using LibGit2Sharp;
using LibGit2Sharp.Handlers;
using System.Net.NetworkInformation;
using XSystem.Security.Cryptography;
using System.IO.Compression;
using System.Diagnostics;
namespace Zelda_3_Launcher
{

View File

@ -48,7 +48,10 @@ namespace Zelda_3_Launcher
this.ClientSize = new System.Drawing.Size(1191, 806);
this.Controls.Add(this.updateLabel);
this.Controls.Add(this.progBar);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "progressForm";
this.Padding = new System.Windows.Forms.Padding(12, 6, 12, 6);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.ResumeLayout(false);
}

View File

@ -45,8 +45,8 @@
this.radioFullscreenMode = new System.Windows.Forms.RadioButton();
this.radioFullscreen = new System.Windows.Forms.RadioButton();
this.radioWindowed = new System.Windows.Forms.RadioButton();
this.width = new System.Windows.Forms.TextBox();
this.height = new System.Windows.Forms.TextBox();
this.width = new System.Windows.Forms.TextBox();
this.customSize = new System.Windows.Forms.RadioButton();
this.windowAuto = new System.Windows.Forms.RadioButton();
this.checkPPU = new System.Windows.Forms.CheckBox();
@ -99,6 +99,8 @@
this.labelRenderMethod = new System.Windows.Forms.Label();
this.comboRenderMethod = new System.Windows.Forms.ComboBox();
this.linkLabelCustomSprites = new System.Windows.Forms.LinkLabel();
this.buttonKeymapping = new System.Windows.Forms.Button();
this.linkLabelMinorFixes = new System.Windows.Forms.LinkLabel();
this.graphics = new System.Windows.Forms.GroupBox();
this.linkLabelGLSLShaders = new System.Windows.Forms.LinkLabel();
this.fullscreenMode = new System.Windows.Forms.GroupBox();
@ -107,6 +109,7 @@
this.groupBoxSound = new System.Windows.Forms.GroupBox();
this.groupBoxAudioChannels = new System.Windows.Forms.GroupBox();
this.groupBoxGameplay = new System.Windows.Forms.GroupBox();
this.linkLabelMajorFixes = new System.Windows.Forms.LinkLabel();
this.labelHoverNote = new System.Windows.Forms.Label();
this.labelMSUCopy = new System.Windows.Forms.Label();
this.progressMSU = new System.Windows.Forms.ProgressBar();
@ -135,7 +138,7 @@
this.general.Location = new System.Drawing.Point(220, 35);
this.general.Name = "general";
this.general.Size = new System.Drawing.Size(381, 127);
this.general.TabIndex = 0;
this.general.TabIndex = 5;
this.general.TabStop = false;
this.general.Text = "General";
//
@ -145,7 +148,7 @@
this.checkBoxExtend.Location = new System.Drawing.Point(6, 47);
this.checkBoxExtend.Name = "checkBoxExtend";
this.checkBoxExtend.Size = new System.Drawing.Size(72, 19);
this.checkBoxExtend.TabIndex = 6;
this.checkBoxExtend.TabIndex = 3;
this.checkBoxExtend.Text = "Extend Y";
this.toolTip1.SetToolTip(this.checkBoxExtend, "Displays 240 vertical lines rather than the default 224");
this.checkBoxExtend.UseVisualStyleBackColor = true;
@ -156,7 +159,7 @@
this.disableFrameDelay.Location = new System.Drawing.Point(99, 47);
this.disableFrameDelay.Name = "disableFrameDelay";
this.disableFrameDelay.Size = new System.Drawing.Size(132, 19);
this.disableFrameDelay.TabIndex = 5;
this.disableFrameDelay.TabIndex = 4;
this.disableFrameDelay.Text = "Disable Frame Delay";
this.toolTip1.SetToolTip(this.disableFrameDelay, "Disable the SDL_Delay that happens on each frame (Gives slightly better performan" +
"ce if your display is set to exactly 60Hz)");
@ -168,7 +171,7 @@
this.noVisualFixes.Location = new System.Drawing.Point(250, 47);
this.noVisualFixes.Name = "noVisualFixes";
this.noVisualFixes.Size = new System.Drawing.Size(105, 19);
this.noVisualFixes.TabIndex = 4;
this.noVisualFixes.TabIndex = 5;
this.noVisualFixes.Text = "No Visual Fixes";
this.toolTip1.SetToolTip(this.noVisualFixes, "Avoid fixing some graphics glitches. If enabled, memory compare will not work.");
this.noVisualFixes.UseVisualStyleBackColor = true;
@ -179,7 +182,7 @@
this.unchangedSprites.Location = new System.Drawing.Point(250, 22);
this.unchangedSprites.Name = "unchangedSprites";
this.unchangedSprites.Size = new System.Drawing.Size(125, 19);
this.unchangedSprites.TabIndex = 3;
this.unchangedSprites.TabIndex = 2;
this.unchangedSprites.Text = "Unchanged Sprites";
this.toolTip1.SetToolTip(this.unchangedSprites, "Avoid changing sprite spawn/die behavior. (Required for replay compatibility)");
this.unchangedSprites.UseVisualStyleBackColor = true;
@ -193,7 +196,7 @@
this.aspectRatio.Location = new System.Drawing.Point(6, 72);
this.aspectRatio.Name = "aspectRatio";
this.aspectRatio.Size = new System.Drawing.Size(369, 50);
this.aspectRatio.TabIndex = 2;
this.aspectRatio.TabIndex = 6;
this.aspectRatio.TabStop = false;
this.aspectRatio.Text = "Aspect Ratio";
this.toolTip1.SetToolTip(this.aspectRatio, "This is the aspect ratio which the game will render. All aspect ratios other than" +
@ -216,7 +219,7 @@
this.widescreen.Location = new System.Drawing.Point(107, 22);
this.widescreen.Name = "widescreen";
this.widescreen.Size = new System.Drawing.Size(118, 19);
this.widescreen.TabIndex = 2;
this.widescreen.TabIndex = 1;
this.widescreen.Text = "Widescreen (16:9)";
this.toolTip1.SetToolTip(this.widescreen, "Traditional widescreen screens");
this.widescreen.UseVisualStyleBackColor = true;
@ -228,7 +231,7 @@
this.normal.Location = new System.Drawing.Point(6, 22);
this.normal.Name = "normal";
this.normal.Size = new System.Drawing.Size(91, 19);
this.normal.TabIndex = 2;
this.normal.TabIndex = 0;
this.normal.TabStop = true;
this.normal.Text = "Normal (4:3)";
this.toolTip1.SetToolTip(this.normal, "Original output of the SNES");
@ -296,25 +299,25 @@
"nd window scaling");
this.radioWindowed.UseVisualStyleBackColor = true;
//
// width
//
this.width.Enabled = false;
this.width.Location = new System.Drawing.Point(59, 71);
this.width.MaxLength = 4;
this.width.Name = "width";
this.width.Size = new System.Drawing.Size(35, 23);
this.width.TabIndex = 4;
this.toolTip1.SetToolTip(this.width, "Height");
//
// height
//
this.height.Enabled = false;
this.height.Location = new System.Drawing.Point(6, 71);
this.height.Location = new System.Drawing.Point(59, 71);
this.height.MaxLength = 4;
this.height.Name = "height";
this.height.Size = new System.Drawing.Size(35, 23);
this.height.TabIndex = 2;
this.toolTip1.SetToolTip(this.height, "Width");
this.height.TabIndex = 3;
this.toolTip1.SetToolTip(this.height, "Height");
//
// width
//
this.width.Enabled = false;
this.width.Location = new System.Drawing.Point(6, 71);
this.width.MaxLength = 4;
this.width.Name = "width";
this.width.Size = new System.Drawing.Size(35, 23);
this.width.TabIndex = 2;
this.toolTip1.SetToolTip(this.width, "Width");
//
// customSize
//
@ -349,7 +352,7 @@
this.checkPPU.Location = new System.Drawing.Point(6, 130);
this.checkPPU.Name = "checkPPU";
this.checkPPU.Size = new System.Drawing.Size(136, 19);
this.checkPPU.TabIndex = 3;
this.checkPPU.TabIndex = 2;
this.checkPPU.Text = "Optimized SNES PPU";
this.toolTip1.SetToolTip(this.checkPPU, "Use an optimized SNES PPU implementation (potentially buggy)");
this.checkPPU.UseVisualStyleBackColor = true;
@ -364,7 +367,7 @@
0});
this.numericWindowScale.Name = "numericWindowScale";
this.numericWindowScale.Size = new System.Drawing.Size(35, 23);
this.numericWindowScale.TabIndex = 5;
this.numericWindowScale.TabIndex = 7;
this.toolTip1.SetToolTip(this.numericWindowScale, "1 = 100%\r\n2 = 200%\r\n3 = 300%\r\netc.");
this.numericWindowScale.Value = new decimal(new int[] {
3,
@ -390,7 +393,7 @@
this.checkMode7.Location = new System.Drawing.Point(6, 155);
this.checkMode7.Name = "checkMode7";
this.checkMode7.Size = new System.Drawing.Size(118, 19);
this.checkMode7.TabIndex = 6;
this.checkMode7.TabIndex = 5;
this.checkMode7.Text = "Enhanced Mode7";
this.toolTip1.SetToolTip(this.checkMode7, "Display the world map with higher resolution");
this.checkMode7.UseVisualStyleBackColor = true;
@ -401,7 +404,7 @@
this.checkStretch.Location = new System.Drawing.Point(152, 155);
this.checkStretch.Name = "checkStretch";
this.checkStretch.Size = new System.Drawing.Size(63, 19);
this.checkStretch.TabIndex = 7;
this.checkStretch.TabIndex = 6;
this.checkStretch.Text = "Stretch";
this.toolTip1.SetToolTip(this.checkStretch, "Stretches the graphics to take up the entire window/screen regardless of aspect r" +
"atio.");
@ -415,7 +418,7 @@
this.checkSpriteLimit.Location = new System.Drawing.Point(152, 130);
this.checkSpriteLimit.Name = "checkSpriteLimit";
this.checkSpriteLimit.Size = new System.Drawing.Size(105, 19);
this.checkSpriteLimit.TabIndex = 8;
this.checkSpriteLimit.TabIndex = 3;
this.checkSpriteLimit.Text = "No Sprite Limit";
this.toolTip1.SetToolTip(this.checkSpriteLimit, "Remove the sprite limit per scan line");
this.checkSpriteLimit.UseVisualStyleBackColor = true;
@ -426,7 +429,7 @@
this.checkLinearFiltering.Location = new System.Drawing.Point(270, 130);
this.checkLinearFiltering.Name = "checkLinearFiltering";
this.checkLinearFiltering.Size = new System.Drawing.Size(104, 19);
this.checkLinearFiltering.TabIndex = 9;
this.checkLinearFiltering.TabIndex = 4;
this.checkLinearFiltering.Text = "Linear Filtering";
this.toolTip1.SetToolTip(this.checkLinearFiltering, "Use linear filter. Softens image and results in less crisp pixels.");
this.checkLinearFiltering.UseVisualStyleBackColor = true;
@ -438,7 +441,7 @@
this.buttonOpenShader.Location = new System.Drawing.Point(348, 284);
this.buttonOpenShader.Name = "buttonOpenShader";
this.buttonOpenShader.Size = new System.Drawing.Size(26, 25);
this.buttonOpenShader.TabIndex = 14;
this.buttonOpenShader.TabIndex = 13;
this.buttonOpenShader.Text = "...";
this.toolTip1.SetToolTip(this.buttonOpenShader, "Opens a dialog for selecting your GLSL shader file.");
this.buttonOpenShader.UseVisualStyleBackColor = true;
@ -449,7 +452,7 @@
this.textBoxGLSLShader.Location = new System.Drawing.Point(6, 285);
this.textBoxGLSLShader.Name = "textBoxGLSLShader";
this.textBoxGLSLShader.Size = new System.Drawing.Size(336, 23);
this.textBoxGLSLShader.TabIndex = 16;
this.textBoxGLSLShader.TabIndex = 12;
this.toolTip1.SetToolTip(this.textBoxGLSLShader, "The path where your .glsl or .slslp file is located");
//
// buttonOpenSprites
@ -459,7 +462,7 @@
this.buttonOpenSprites.Location = new System.Drawing.Point(348, 233);
this.buttonOpenSprites.Name = "buttonOpenSprites";
this.buttonOpenSprites.Size = new System.Drawing.Size(26, 25);
this.buttonOpenSprites.TabIndex = 14;
this.buttonOpenSprites.TabIndex = 10;
this.buttonOpenSprites.Text = "...";
this.toolTip1.SetToolTip(this.buttonOpenSprites, "Opens a dialog for selecting your ZSPR custom sprite file.");
this.buttonOpenSprites.UseVisualStyleBackColor = true;
@ -470,7 +473,7 @@
this.textBoxCustomLink.Location = new System.Drawing.Point(6, 234);
this.textBoxCustomLink.Name = "textBoxCustomLink";
this.textBoxCustomLink.Size = new System.Drawing.Size(336, 23);
this.textBoxCustomLink.TabIndex = 13;
this.textBoxCustomLink.TabIndex = 9;
this.toolTip1.SetToolTip(this.textBoxCustomLink, "The path where your .zspr file is located");
//
// checkBoxCustomLinkSprites
@ -506,7 +509,7 @@
this.checkBoxEnableAudio.Location = new System.Drawing.Point(619, 47);
this.checkBoxEnableAudio.Name = "checkBoxEnableAudio";
this.checkBoxEnableAudio.Size = new System.Drawing.Size(96, 19);
this.checkBoxEnableAudio.TabIndex = 0;
this.checkBoxEnableAudio.TabIndex = 7;
this.checkBoxEnableAudio.Text = "Enable Audio";
this.toolTip1.SetToolTip(this.checkBoxEnableAudio, "Enable audio output by the game");
this.checkBoxEnableAudio.UseVisualStyleBackColor = true;
@ -701,7 +704,7 @@
this.groupBoxMSUSettings.Location = new System.Drawing.Point(6, 155);
this.groupBoxMSUSettings.Name = "groupBoxMSUSettings";
this.groupBoxMSUSettings.Size = new System.Drawing.Size(190, 145);
this.groupBoxMSUSettings.TabIndex = 7;
this.groupBoxMSUSettings.TabIndex = 4;
this.groupBoxMSUSettings.TabStop = false;
this.groupBoxMSUSettings.Text = "MSU Settings";
this.toolTip1.SetToolTip(this.groupBoxMSUSettings, "Settings specifically for MSU");
@ -718,7 +721,7 @@
this.comboBoxMSU.MaxDropDownItems = 4;
this.comboBoxMSU.Name = "comboBoxMSU";
this.comboBoxMSU.Size = new System.Drawing.Size(99, 23);
this.comboBoxMSU.TabIndex = 6;
this.comboBoxMSU.TabIndex = 2;
this.comboBoxMSU.Text = "MSU";
this.toolTip1.SetToolTip(this.comboBoxMSU, "Select the version of MSU you wish to use");
//
@ -727,7 +730,7 @@
this.textBoxMSUDirectory.Location = new System.Drawing.Point(6, 115);
this.textBoxMSUDirectory.Name = "textBoxMSUDirectory";
this.textBoxMSUDirectory.Size = new System.Drawing.Size(146, 23);
this.textBoxMSUDirectory.TabIndex = 8;
this.textBoxMSUDirectory.TabIndex = 3;
this.toolTip1.SetToolTip(this.textBoxMSUDirectory, "MSU directory path");
//
// labelMSUVersion
@ -754,7 +757,7 @@
this.numericMSUVolume.Location = new System.Drawing.Point(90, 39);
this.numericMSUVolume.Name = "numericMSUVolume";
this.numericMSUVolume.Size = new System.Drawing.Size(42, 23);
this.numericMSUVolume.TabIndex = 8;
this.numericMSUVolume.TabIndex = 1;
this.toolTip1.SetToolTip(this.numericMSUVolume, "Volume of MSU output (0-100)");
this.numericMSUVolume.Value = new decimal(new int[] {
100,
@ -768,7 +771,7 @@
this.checkBoxResumeMSU.Location = new System.Drawing.Point(6, 20);
this.checkBoxResumeMSU.Name = "checkBoxResumeMSU";
this.checkBoxResumeMSU.Size = new System.Drawing.Size(96, 19);
this.checkBoxResumeMSU.TabIndex = 8;
this.checkBoxResumeMSU.TabIndex = 0;
this.checkBoxResumeMSU.Text = "Resume MSU";
this.toolTip1.SetToolTip(this.checkBoxResumeMSU, "Resume MSU music from the same point in the track when returning to an area");
this.checkBoxResumeMSU.UseVisualStyleBackColor = true;
@ -790,7 +793,7 @@
this.buttonMSUDirectory.Location = new System.Drawing.Point(158, 114);
this.buttonMSUDirectory.Name = "buttonMSUDirectory";
this.buttonMSUDirectory.Size = new System.Drawing.Size(26, 25);
this.buttonMSUDirectory.TabIndex = 14;
this.buttonMSUDirectory.TabIndex = 4;
this.buttonMSUDirectory.Text = "...";
this.toolTip1.SetToolTip(this.buttonMSUDirectory, "Open dialog to select MSU directory");
this.buttonMSUDirectory.UseVisualStyleBackColor = true;
@ -808,7 +811,7 @@
this.comboBoxSamples.MaxDropDownItems = 4;
this.comboBoxSamples.Name = "comboBoxSamples";
this.comboBoxSamples.Size = new System.Drawing.Size(55, 23);
this.comboBoxSamples.TabIndex = 5;
this.comboBoxSamples.TabIndex = 2;
this.toolTip1.SetToolTip(this.comboBoxSamples, "Audio buffer size in samples");
//
// comboBoxFrequency
@ -824,7 +827,7 @@
this.comboBoxFrequency.MaxDropDownItems = 5;
this.comboBoxFrequency.Name = "comboBoxFrequency";
this.comboBoxFrequency.Size = new System.Drawing.Size(55, 23);
this.comboBoxFrequency.TabIndex = 4;
this.comboBoxFrequency.TabIndex = 1;
this.toolTip1.SetToolTip(this.comboBoxFrequency, "DSP frequency in samples per second");
//
// checkBoxEnableMSU
@ -833,7 +836,7 @@
this.checkBoxEnableMSU.Location = new System.Drawing.Point(6, 130);
this.checkBoxEnableMSU.Name = "checkBoxEnableMSU";
this.checkBoxEnableMSU.Size = new System.Drawing.Size(89, 19);
this.checkBoxEnableMSU.TabIndex = 6;
this.checkBoxEnableMSU.TabIndex = 3;
this.checkBoxEnableMSU.Text = "Enable MSU";
this.toolTip1.SetToolTip(this.checkBoxEnableMSU, resources.GetString("checkBoxEnableMSU.ToolTip"));
this.checkBoxEnableMSU.UseVisualStyleBackColor = true;
@ -869,7 +872,7 @@
this.buttonReset.Location = new System.Drawing.Point(607, 373);
this.buttonReset.Name = "buttonReset";
this.buttonReset.Size = new System.Drawing.Size(202, 35);
this.buttonReset.TabIndex = 4;
this.buttonReset.TabIndex = 3;
this.buttonReset.Text = "Reset";
this.toolTip1.SetToolTip(this.buttonReset, "Reset all settings to their default values");
this.buttonReset.UseVisualStyleBackColor = true;
@ -880,7 +883,7 @@
this.buttonSave.Location = new System.Drawing.Point(607, 412);
this.buttonSave.Name = "buttonSave";
this.buttonSave.Size = new System.Drawing.Size(202, 35);
this.buttonSave.TabIndex = 4;
this.buttonSave.TabIndex = 2;
this.buttonSave.Text = "Save";
this.toolTip1.SetToolTip(this.buttonSave, "Save current settings and close window");
this.buttonSave.UseVisualStyleBackColor = true;
@ -891,7 +894,7 @@
this.buttonCancel.Location = new System.Drawing.Point(607, 450);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(202, 35);
this.buttonCancel.TabIndex = 4;
this.buttonCancel.TabIndex = 1;
this.buttonCancel.Text = "Cancel";
this.toolTip1.SetToolTip(this.buttonCancel, "Close window without saving any settings");
this.buttonCancel.UseVisualStyleBackColor = true;
@ -919,7 +922,7 @@
this.comboRenderMethod.MaxDropDownItems = 3;
this.comboRenderMethod.Name = "comboRenderMethod";
this.comboRenderMethod.Size = new System.Drawing.Size(144, 23);
this.comboRenderMethod.TabIndex = 10;
this.comboRenderMethod.TabIndex = 8;
this.toolTip1.SetToolTip(this.comboRenderMethod, "Rendering software used. SDL-software rendering may give better performance on Ra" +
"spberry Pi");
//
@ -929,12 +932,35 @@
this.linkLabelCustomSprites.Location = new System.Drawing.Point(230, 210);
this.linkLabelCustomSprites.Name = "linkLabelCustomSprites";
this.linkLabelCustomSprites.Size = new System.Drawing.Size(144, 15);
this.linkLabelCustomSprites.TabIndex = 18;
this.linkLabelCustomSprites.TabIndex = 11;
this.linkLabelCustomSprites.TabStop = true;
this.linkLabelCustomSprites.Text = "Custom Sprite Downloads";
this.toolTip1.SetToolTip(this.linkLabelCustomSprites, "Click here for some custom sprites you can download");
this.linkLabelCustomSprites.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelCustomSprites_LinkClicked);
//
// buttonKeymapping
//
this.buttonKeymapping.Location = new System.Drawing.Point(12, 450);
this.buttonKeymapping.Name = "buttonKeymapping";
this.buttonKeymapping.Size = new System.Drawing.Size(202, 35);
this.buttonKeymapping.TabIndex = 0;
this.buttonKeymapping.Text = "Keymapping";
this.toolTip1.SetToolTip(this.buttonKeymapping, "Open a new settings menu exclusively for configuring keymappings for the game");
this.buttonKeymapping.UseVisualStyleBackColor = true;
this.buttonKeymapping.Click += new System.EventHandler(this.buttonKeymapping_Click);
//
// linkLabelMinorFixes
//
this.linkLabelMinorFixes.AutoSize = true;
this.linkLabelMinorFixes.Location = new System.Drawing.Point(165, 298);
this.linkLabelMinorFixes.Name = "linkLabelMinorFixes";
this.linkLabelMinorFixes.Size = new System.Drawing.Size(12, 15);
this.linkLabelMinorFixes.TabIndex = 9;
this.linkLabelMinorFixes.TabStop = true;
this.linkLabelMinorFixes.Text = "?";
this.toolTip1.SetToolTip(this.linkLabelMinorFixes, "This webpage will list the specific fixes");
this.linkLabelMinorFixes.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelMinorFixes_LinkClicked);
//
// graphics
//
this.graphics.Controls.Add(this.linkLabelGLSLShaders);
@ -959,7 +985,7 @@
this.graphics.Location = new System.Drawing.Point(220, 168);
this.graphics.Name = "graphics";
this.graphics.Size = new System.Drawing.Size(381, 317);
this.graphics.TabIndex = 1;
this.graphics.TabIndex = 6;
this.graphics.TabStop = false;
this.graphics.Text = "Graphics";
//
@ -969,7 +995,7 @@
this.linkLabelGLSLShaders.Location = new System.Drawing.Point(268, 264);
this.linkLabelGLSLShaders.Name = "linkLabelGLSLShaders";
this.linkLabelGLSLShaders.Size = new System.Drawing.Size(106, 15);
this.linkLabelGLSLShaders.TabIndex = 19;
this.linkLabelGLSLShaders.TabIndex = 14;
this.linkLabelGLSLShaders.TabStop = true;
this.linkLabelGLSLShaders.Text = "Suggested Shaders";
this.linkLabelGLSLShaders.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelGLSLShaders_LinkClicked);
@ -983,22 +1009,22 @@
this.fullscreenMode.Location = new System.Drawing.Point(189, 22);
this.fullscreenMode.Name = "fullscreenMode";
this.fullscreenMode.Size = new System.Drawing.Size(185, 102);
this.fullscreenMode.TabIndex = 2;
this.fullscreenMode.TabIndex = 1;
this.fullscreenMode.TabStop = false;
this.fullscreenMode.Text = "Fullscreen Mode";
//
// windowSize
//
this.windowSize.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.windowSize.Controls.Add(this.width);
this.windowSize.Controls.Add(this.windowSizeX);
this.windowSize.Controls.Add(this.height);
this.windowSize.Controls.Add(this.windowSizeX);
this.windowSize.Controls.Add(this.width);
this.windowSize.Controls.Add(this.customSize);
this.windowSize.Controls.Add(this.windowAuto);
this.windowSize.Location = new System.Drawing.Point(6, 22);
this.windowSize.Name = "windowSize";
this.windowSize.Size = new System.Drawing.Size(177, 102);
this.windowSize.TabIndex = 1;
this.windowSize.TabIndex = 0;
this.windowSize.TabStop = false;
this.windowSize.Text = "Window Size";
//
@ -1025,7 +1051,7 @@
this.groupBoxSound.Location = new System.Drawing.Point(607, 66);
this.groupBoxSound.Name = "groupBoxSound";
this.groupBoxSound.Size = new System.Drawing.Size(202, 305);
this.groupBoxSound.TabIndex = 2;
this.groupBoxSound.TabIndex = 8;
this.groupBoxSound.TabStop = false;
this.groupBoxSound.Text = "Sound";
//
@ -1037,17 +1063,19 @@
this.groupBoxAudioChannels.Location = new System.Drawing.Point(6, 22);
this.groupBoxAudioChannels.Name = "groupBoxAudioChannels";
this.groupBoxAudioChannels.Size = new System.Drawing.Size(190, 54);
this.groupBoxAudioChannels.TabIndex = 3;
this.groupBoxAudioChannels.TabIndex = 0;
this.groupBoxAudioChannels.TabStop = false;
this.groupBoxAudioChannels.Text = "Audio Channels";
//
// groupBoxGameplay
//
this.groupBoxGameplay.Controls.Add(this.linkLabelMajorFixes);
this.groupBoxGameplay.Controls.Add(this.checkBoxCancelBird);
this.groupBoxGameplay.Controls.Add(this.linkLabelMinorFixes);
this.groupBoxGameplay.Controls.Add(this.checkBoxMajorFixes);
this.groupBoxGameplay.Controls.Add(this.checkBoxMiscFixes);
this.groupBoxGameplay.Controls.Add(this.checkBoxLargerWallet);
this.groupBoxGameplay.Controls.Add(this.checkBoxMoreBombs);
this.groupBoxGameplay.Controls.Add(this.checkBoxMiscFixes);
this.groupBoxGameplay.Controls.Add(this.checkBoxMaxResources);
this.groupBoxGameplay.Controls.Add(this.checkBoxIntroSkip);
this.groupBoxGameplay.Controls.Add(this.checkBoxHeartBeep);
@ -1059,11 +1087,22 @@
this.groupBoxGameplay.Controls.Add(this.checkBoxQuickSwitch);
this.groupBoxGameplay.Location = new System.Drawing.Point(12, 35);
this.groupBoxGameplay.Name = "groupBoxGameplay";
this.groupBoxGameplay.Size = new System.Drawing.Size(202, 450);
this.groupBoxGameplay.TabIndex = 3;
this.groupBoxGameplay.Size = new System.Drawing.Size(202, 409);
this.groupBoxGameplay.TabIndex = 4;
this.groupBoxGameplay.TabStop = false;
this.groupBoxGameplay.Text = "Gameplay";
//
// linkLabelMajorFixes
//
this.linkLabelMajorFixes.AutoSize = true;
this.linkLabelMajorFixes.Location = new System.Drawing.Point(165, 323);
this.linkLabelMajorFixes.Name = "linkLabelMajorFixes";
this.linkLabelMajorFixes.Size = new System.Drawing.Size(12, 15);
this.linkLabelMajorFixes.TabIndex = 9;
this.linkLabelMajorFixes.TabStop = true;
this.linkLabelMajorFixes.Text = "?";
this.linkLabelMajorFixes.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel2_LinkClicked);
//
// labelHoverNote
//
this.labelHoverNote.Location = new System.Drawing.Point(6, 9);
@ -1098,7 +1137,8 @@
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ClientSize = new System.Drawing.Size(821, 675);
this.ClientSize = new System.Drawing.Size(821, 619);
this.Controls.Add(this.buttonKeymapping);
this.Controls.Add(this.progressMSU);
this.Controls.Add(this.labelMSUCopy);
this.Controls.Add(this.labelHoverNote);
@ -1115,6 +1155,7 @@
this.MaximizeBox = false;
this.Name = "settingsForm";
this.Padding = new System.Windows.Forms.Padding(6);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Settings";
this.general.ResumeLayout(false);
this.general.PerformLayout();
@ -1157,9 +1198,9 @@
private GroupBox graphics;
private RadioButton windowAuto;
private GroupBox windowSize;
private TextBox height;
private RadioButton customSize;
private TextBox width;
private RadioButton customSize;
private TextBox height;
private Label windowSizeX;
private GroupBox fullscreenMode;
private RadioButton radioFullscreenMode;
@ -1223,5 +1264,8 @@
private LinkLabel linkLabelGLSLShaders;
private Label labelMSUCopy;
private ProgressBar progressMSU;
private Button buttonKeymapping;
private LinkLabel linkLabelMinorFixes;
private LinkLabel linkLabelMajorFixes;
}
}

View File

@ -1,19 +1,10 @@
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using IniParser;
using IniParser.Model;
using IniParser.Model.Configuration;
using IniParser.Parser;
using LibGit2Sharp;
using XAct;
namespace Zelda_3_Launcher
@ -22,13 +13,15 @@ namespace Zelda_3_Launcher
{
private string v;
private static volatile int progress = 0;
public settingsForm()
{
InitializeComponent();
try
{
importINI();
ImportINI();
}
catch
{
@ -39,8 +32,8 @@ namespace Zelda_3_Launcher
this.Close();
return;
}
restoreINI();
buttonReset_Click(this, new EventArgs());
}
if (checkBoxEnableMSU.Checked == false) groupBoxMSUSettings.Enabled = false;
@ -51,14 +44,14 @@ namespace Zelda_3_Launcher
{
if (customSize.Checked)
{
width.Enabled = true;
height.Enabled = true;
width.Enabled = true;
windowSizeX.Enabled= true;
}
else
{
width.Enabled = false;
height.Enabled = false;
width.Enabled = false;
windowSizeX.Enabled = false;
}
}
@ -71,30 +64,55 @@ namespace Zelda_3_Launcher
var answer = MessageBox.Show("This will reset the INI file immediately and cannot be reversed.\n\nDo you wish to continue?", "Confirmation", MessageBoxButtons.YesNo);
if (answer == DialogResult.No) return;
if (answer == DialogResult.No)
{
this.Enabled = true;
this.buttonReset.Text = "Reset";
return;
}
restoreINI();
importINI();
try
{
ImportINI();
}
catch
{
answer = MessageBox.Show("INI backup file is corrupted and preventing the settings menu from loading.\n\nDo you want to download a clean copy from the zelda3 repository?", "Corrupted Settings", MessageBoxButtons.YesNo);
if (answer == DialogResult.No)
{
this.Close();
return;
}
File.Delete(Path.Combine(Program.repoDir, "saves", "zelda3.ini"));
restoreINI();
ImportINI();
}
this.Enabled = true;
this.buttonReset.Text = "Reset";
}
private static void restoreINI()
private void restoreINI()
{
var iniFile = Path.Combine(Program.repoDir, "zelda3.ini");
var iniBackup = Path.Combine(Program.repoDir, "saves", "zelda3.ini");
File.Delete(iniFile);
if (!File.Exists(iniBackup)) DownloadFreshINI();
using (var modifiedFile = File.AppendText(iniFile))
{
foreach (var line in File.ReadLines(iniBackup))
{
if (!line.Equals("# Change the appearance of Link by loading a ZSPR file") ||
!line.Equals("# See all sprites here: https://snesrev.github.io/sprites-gfx/snes/zelda3/link/") ||
!line.Equals("# Download the files with \"git clone https://github.com/snesrev/sprites-gfx.git\"") ||
if (!line.Equals("# Change the appearance of Link by loading a ZSPR file") &&
!line.Equals("# See all sprites here: https://snesrev.github.io/sprites-gfx/snes/zelda3/link/") &&
!line.Equals("# Download the files with \"git clone https://github.com/snesrev/sprites-gfx.git\"") &&
!line.Equals("# LinkGraphics = sprites-gfx/snes/zelda3/link/sheets/megaman-x.2.zspr"))
{
modifiedFile.WriteLine(line);
@ -103,6 +121,49 @@ namespace Zelda_3_Launcher
}
}
internal static void DownloadFreshINI()
{
var filename = "zelda3.ini";
Uri uri = new Uri("https://raw.githubusercontent.com/snesrev/zelda3/master/zelda3.ini");
var directory = Path.Combine(Program.repoDir, "saves");
var destination = Path.Combine(Program.repoDir, "saves", filename);
if (!progressForm.IsConnectedToInternet())
{
MessageBox.Show("Your INI backup file is missing and you are unable to connect to the internet to download a fresh copy.\n\nPlease ensure you have a stable internet connection before attempting to reset settings.",
"No Connection", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
Task.Run(() =>
{
using (var client = new WebClient())
{
if (!Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(downloadProgress);
client.DownloadFileAsync(uri, destination);
}
});
while (!File.Exists(destination))
{
Application.DoEvents();
}
do
{
} while (progress < 100);
}
private static void downloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
progress = e.ProgressPercentage;
}
private void buttonSave_Click(object sender, EventArgs e)
{
buttonSave.Text = "Saving...";
@ -172,23 +233,29 @@ namespace Zelda_3_Launcher
groupBoxMSUSettings.Enabled = checkBoxEnableMSU.Checked;
}
private void importINI()
private void ImportINI()
{
var iniFile = Path.Combine(Program.repoDir, "zelda3.ini");
// Check for INI and if missing restore from initial install backup
if (!File.Exists(iniFile))
{
var iniBackup = Path.Combine(Program.repoDir, "saves", "zelda3.ini");
if (!File.Exists(iniBackup)) DownloadFreshINI();
using (var modifiedFile = File.AppendText(iniFile))
{
foreach (var line in File.ReadLines(iniBackup))
{
if (!line.Equals("# Change the appearance of Link by loading a ZSPR file") ||
!line.Equals("# See all sprites here: https://snesrev.github.io/sprites-gfx/snes/zelda3/link/") ||
!line.Equals("# Download the files with \"git clone https://github.com/snesrev/sprites-gfx.git\"") ||
!line.Equals("# LinkGraphics = sprites-gfx/snes/zelda3/link/sheets/megaman-x.2.zspr"))
if (!line.Equals("# Change the appearance of Link by loading a ZSPR file") &&
!line.Equals("# See all sprites here: https://snesrev.github.io/sprites-gfx/snes/zelda3/link/") &&
!line.Equals("# Download the files with \"git clone https://github.com/snesrev/sprites-gfx.git\"") &&
!line.Equals("# LinkGraphics = sprites-gfx/snes/zelda3/link/sheets/megaman-x.2.zspr") &&
!line.Equals("# This default is suitable for QWERTZ keyboards.") &&
!line.Equals("#Controls = Up, Down, Left, Right, Right Shift, Return, x, y, s, a, c, v") &&
!line.Equals("# This one is suitable for AZERTY keyboards.") &&
!line.Equals("#Controls = Up, Down, Left, Right, Right Shift, Return, x, w, s, q, c, v"))
{
modifiedFile.WriteLine(line);
}
@ -241,14 +308,14 @@ namespace Zelda_3_Launcher
var resolution = settings["Graphics"]["WindowSize"].Split("x");
customSize.Checked = true;
height.Text = resolution[0];
width.Text = resolution[1];
width.Text = resolution[0];
height.Text = resolution[1];
}
else
{
windowAuto.Checked = true;
height.Text = "";
width.Text = "";
height.Text = "";
}
switch (settings["Graphics"]["Fullscreen"])
@ -467,7 +534,7 @@ namespace Zelda_3_Launcher
switch (selection)
{
case "Custom":
settings["Graphics"]["WindowSize"] = width.Text + "x" + width.Text;
settings["Graphics"]["WindowSize"] = width.Text + "x" + height.Text;
break;
default:
settings["Graphics"]["WindowSize"] = "Auto";
@ -785,5 +852,30 @@ namespace Zelda_3_Launcher
Process.Start(new ProcessStartInfo("https://github.com/snesrev/glsl-shaders") { UseShellExecute = true });
}
private void buttonKeymapping_Click(object sender, EventArgs e)
{
using (keymapper keymapper = new keymapper())
{
if (!keymapper.IsDisposed && keymapper.ShowDialog() == DialogResult.OK)
{
keymapper.Dispose();
}
}
}
private void linkLabelMinorFixes_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
this.linkLabelMinorFixes.LinkVisited = true;
Process.Start(new ProcessStartInfo("https://github.com/snesrev/zelda3/wiki/Bug-Fixes-:-Misc.") { UseShellExecute = true });
}
private void linkLabel2_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
this.linkLabelMajorFixes.LinkVisited = true;
Process.Start(new ProcessStartInfo("https://github.com/snesrev/zelda3/wiki/Bug-Fixes-:-Game-Changing") { UseShellExecute = true });
}
}
}