Addition of Settings menu along with assorted small bug fixes and QoL changes regarding relaying information regarding the building status to the user.

This commit is contained in:
ajohns6 2023-02-10 16:05:26 -05:00
parent 8d38b0e29d
commit e7a26e9315
8 changed files with 2236 additions and 27 deletions

View File

@ -23,5 +23,7 @@
private Button build;
private Button launch;
private Button settings;
private Label labelCompileStatus;
private ProgressBar progressCompile;
}
}

View File

@ -17,23 +17,7 @@ namespace Zelda_3_Launcher
if (Directory.Exists(Program.repoDir))
{
Repository repo = new Repository(Program.repoDir);
var status = repo.RetrieveStatus();
if (repo.Head.TrackingDetails.BehindBy > 0) this.build.Text = "Update";
else if (status.IsDirty) this.build.Text = "Restore";
else this.build.Text = "Re-build";
if (File.Exists(Path.Combine(Program.repoDir, "zelda3.exe")))
{
this.launch.Enabled = true;
}
/*
if (File.Exists(Path.Combine(Program.repoDir, "zelda3.ini")))
{
this.settings.Enabled = true;
}*/
UpdateMainForm();
}
}
@ -46,17 +30,19 @@ namespace Zelda_3_Launcher
this.settings.Enabled = false;
this.launch.Text = "Running...";
this.WindowState = FormWindowState.Minimized;
if (runProcess(@".\zelda3\zelda3.exe", ""))
{
MessageBox.Show("Error occurred while launching Zelda 3.\n\nPlease refer to " + Path.Combine(Program.currentDirectory, "log.txt") + " for further details.");
return;
}
this.launch.Text = "Launch Zelda 3";
this.Enabled = true;
this.build.Enabled = true;
//this.settings.Enabled = true;
this.settings.Enabled = true;
this.WindowState = FormWindowState.Normal;
}
private void build_Click(object sender, EventArgs e)
@ -65,6 +51,7 @@ namespace Zelda_3_Launcher
this.build.Enabled = false;
this.launch.Enabled = false;
this.settings.Enabled = false;
using (progressForm cloneRepo = new progressForm("Repository Download", "Downloading a fresh copy of the zelda3 repository..."))
{
@ -82,6 +69,13 @@ namespace Zelda_3_Launcher
}
}
if (!File.Exists(Path.Combine(Program.repoDir, "tables", "zelda3.sfc")))
{
MessageBox.Show("No ROM provided. Process cancelled.", "No ROM", MessageBoxButtons.OK, MessageBoxIcon.Information);
UpdateMainForm();
return;
}
using (progressForm downloadTCC = new progressForm("Downloading TCC", "Downloading TCC build tools..."))
{
if (downloadTCC.ShowDialog() == DialogResult.OK)
@ -115,12 +109,16 @@ namespace Zelda_3_Launcher
this.build.Text = "Building...";
progressCompile.Visible = true;
labelCompileStatus.Visible = true;
var pythonEXE = @".\tables\python.exe";
var python310 = @".\zelda3\tables\python310._pth";
var python310Old = @".\zelda3\tables\python310._pth.old";
File.AppendAllText(Program.currentDirectory + "\\log.txt", "Starting commandline processess...");
labelCompileStatus.Text = "Modifying python310._pth...";
// Modify python310._pth to allow for pip installation
File.Move(python310, python310Old);
using (var pythonFile = File.AppendText(python310))
@ -134,24 +132,31 @@ namespace Zelda_3_Launcher
File.Delete(python310Old);
// Download pip
labelCompileStatus.Text = "Downloading pip...";
if (runProcess("cmd.exe", "/C " + pythonEXE + @" .\tables\get-pip.py"))
{
MessageBox.Show("Error occurred while downloding pip.\n\nPlease refer to " + Path.Combine(Program.currentDirectory, "log.txt") + " for further details.");
return;
}
// Install dependencies
labelCompileStatus.Text = "Installing dependencies...";
if (runProcess("cmd.exe", @"/C " + pythonEXE + " -m pip install --upgrade pip pillow pyyaml"))
{
MessageBox.Show("Error occurred while installing/updating dependencies.\n\nPlease refer to " + Path.Combine(Program.currentDirectory, "log.txt") + " for further details.");
return;
}
// Extract resources
labelCompileStatus.Text = "Extracting assets...";
if (runProcess("cmd.exe", @"/C cd .\tables && python extract_resources.py"))
{
MessageBox.Show("Error occurred while extracting resources.\n\nPlease refer to " + Path.Combine(Program.currentDirectory, "log.txt") + " for further details.");
return;
}
// Compile resources
labelCompileStatus.Text = "Compiling assets...";
if (runProcess("cmd.exe", @"/C cd .\tables && python compile_resources.py"))
{
MessageBox.Show("Error occurred while compiling resources.\n\nPlease refer to " + Path.Combine(Program.currentDirectory, "log.txt") + " for further details.");
@ -159,6 +164,7 @@ namespace Zelda_3_Launcher
}
// Need to make some small modifications to bat before exectuting
labelCompileStatus.Text = "Modifying installation bat...";
var batOld = Path.Combine(Program.repoDir, "run_with_tcc.bat");
var batNew = Path.Combine(Program.repoDir, "radzprower.bat");
using (var pythonFile = File.AppendText(batNew))
@ -172,14 +178,46 @@ namespace Zelda_3_Launcher
}
}
// build zelda3.exe
labelCompileStatus.Text = "Building zelda3.exe...";
if (runProcess("cmd.exe", @"/C radzprower.bat"))
{
MessageBox.Show("Error occurred while building executable.\n\nPlease refer to " + Path.Combine(Program.currentDirectory, "log.txt") + " for further details.");
return;
}
File.AppendAllText(Program.currentDirectory + "\\log.txt", "\n\n\n\n");
labelCompileStatus.Text = "Backing up zelda3.ini...";
var iniFile = Path.Combine(Program.repoDir, "zelda3.ini");
var iniCopy = Path.Combine(Program.repoDir, "saves", "zelda3.ini");
if (File.Exists(iniCopy)) File.Delete(iniCopy);
File.Move(iniFile, iniCopy);
labelCompileStatus.Text = "Modifying zelda3.ini...";
using (var modifiedFile = File.AppendText(iniFile))
{
foreach (var line in File.ReadLines(iniCopy))
{
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);
}
}
}
progressCompile.Text = "Done";
progressCompile.Visible = false;
labelCompileStatus.Visible = false;
File.AppendAllText(Program.currentDirectory + "\\log.txt", "\n\n\n\n");
UpdateMainForm();
}
private void UpdateMainForm()
{
Repository repo = new Repository(Program.repoDir);
var status = repo.RetrieveStatus();
@ -192,12 +230,30 @@ namespace Zelda_3_Launcher
if (File.Exists(Path.Combine(Program.repoDir, "zelda3.exe")))
{
this.launch.Enabled = true;
}
/*
if (File.Exists(Path.Combine(Program.repoDir, "zelda3.ini")))
{
this.settings.Enabled = true;
}*/
if (File.Exists(Path.Combine(Program.repoDir, "zelda3.ini")))
{
this.settings.Text = "Settings";
}
else
{
this.settings.Text = "Restore INI";
}
}
}
private void settings_click(object sender, EventArgs e)
{
using (settingsForm settings = new settingsForm())
{
if (!settings.IsDisposed && settings.ShowDialog() == DialogResult.OK)
{
settings.Dispose();
}
}
UpdateMainForm();
}
private void InitializeComponent()
@ -206,6 +262,8 @@ namespace Zelda_3_Launcher
this.build = new System.Windows.Forms.Button();
this.launch = new System.Windows.Forms.Button();
this.settings = new System.Windows.Forms.Button();
this.labelCompileStatus = new System.Windows.Forms.Label();
this.progressCompile = new System.Windows.Forms.ProgressBar();
this.SuspendLayout();
//
// build
@ -241,12 +299,35 @@ namespace Zelda_3_Launcher
this.settings.TabIndex = 0;
this.settings.Text = "Settings";
this.settings.UseVisualStyleBackColor = true;
this.settings.Click += new System.EventHandler(this.settings_click);
//
// labelCompileStatus
//
this.labelCompileStatus.Location = new System.Drawing.Point(8, 173);
this.labelCompileStatus.Name = "labelCompileStatus";
this.labelCompileStatus.Size = new System.Drawing.Size(175, 23);
this.labelCompileStatus.TabIndex = 1;
this.labelCompileStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
this.labelCompileStatus.Visible = false;
//
// progressCompile
//
this.progressCompile.Location = new System.Drawing.Point(8, 199);
this.progressCompile.Maximum = 2808;
this.progressCompile.Minimum = 543;
this.progressCompile.Name = "progressCompile";
this.progressCompile.Size = new System.Drawing.Size(175, 23);
this.progressCompile.TabIndex = 2;
this.progressCompile.Value = 543;
this.progressCompile.Visible = false;
//
// MainForm
//
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Controls.Add(this.progressCompile);
this.Controls.Add(this.labelCompileStatus);
this.Controls.Add(this.settings);
this.Controls.Add(this.launch);
this.Controls.Add(this.build);
@ -299,6 +380,9 @@ namespace Zelda_3_Launcher
process.BeginErrorReadLine();
while (!process.HasExited)
{
var fileCount = Directory.GetFiles(Program.repoDir, "*", SearchOption.AllDirectories).Count();
if (fileCount > 2808) progressCompile.Value = fileCount - 1000;
else progressCompile.Value = fileCount;
Application.DoEvents();
}

View File

@ -17,5 +17,6 @@ namespace Zelda_3_Launcher
public static string currentDirectory = Directory.GetCurrentDirectory();
public static string repoDir = Path.Combine(currentDirectory, "zelda3");
public static string third_partyDir = Path.Combine(repoDir, "third_party");
public static Boolean messageMSU = false;
}
}

View File

@ -9,6 +9,9 @@
<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>
</PropertyGroup>
<ItemGroup>
@ -23,7 +26,9 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="ini-parser" Version="2.5.2" />
<PackageReference Include="LibGit2Sharp" Version="0.27.0-preview-0182" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="7.0.0" />
<PackageReference Include="XAct.Core.PCL" Version="0.0.5014" />
</ItemGroup>

View File

@ -67,9 +67,9 @@ namespace Zelda_3_Launcher
return;
}
if (File.Exists(Path.Combine(Program.repoDir, "zelda3.sfc")))
if (File.Exists(Path.Combine(Program.currentDirectory, "zelda3.sfc")))
{
File.Move(Path.Combine(Program.repoDir, "zelda3.sfc"), Path.Combine(Program.repoDir, "tables", "zelda3.sfc"));
File.Move(Path.Combine(Program.currentDirectory, "zelda3.sfc"), Path.Combine(Program.repoDir, "tables", "zelda3.sfc"));
this.Close();
return;
}
@ -91,6 +91,7 @@ namespace Zelda_3_Launcher
if (answer == DialogResult.No) exit = true;
}
}
else exit = true;
}
this.Close();

1227
Zelda 3 Launcher/settingsForm.Designer.cs generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,786 @@
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
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
{
public partial class settingsForm : Form
{
private string v;
public settingsForm()
{
InitializeComponent();
try
{
importINI();
}
catch
{
var answer = MessageBox.Show("INI file is corrupted and preventing the settings menu from loading.\n\nDo you want to restore to default settings?", "Corrupted Settings", MessageBoxButtons.YesNo);
if (answer == DialogResult.No)
{
this.Close();
return;
}
restoreINI();
}
if (checkBoxEnableMSU.Checked == false) groupBoxMSUSettings.Enabled = false;
if (checkBoxEnableAudio.Checked == false) groupBoxSound.Enabled= false;
}
private void ToggleCustomSizeTextFields()
{
if (customSize.Checked)
{
width.Enabled = true;
height.Enabled = true;
windowSizeX.Enabled= true;
}
else
{
width.Enabled = false;
height.Enabled = false;
windowSizeX.Enabled = false;
}
}
private void buttonReset_Click(object sender, EventArgs e)
{
this.buttonReset.Text = "Resetting...";
this.Enabled = false;
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;
restoreINI();
importINI();
this.Enabled = true;
this.buttonReset.Text = "Reset";
}
private static void restoreINI()
{
var iniFile = Path.Combine(Program.repoDir, "zelda3.ini");
var iniBackup = Path.Combine(Program.repoDir, "saves", "zelda3.ini");
File.Delete(iniFile);
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"))
{
modifiedFile.WriteLine(line);
}
}
}
}
private void buttonSave_Click(object sender, EventArgs e)
{
buttonSave.Text = "Saving...";
groupBoxGameplay.Enabled = false;
general.Enabled = false;
graphics.Enabled = false;
checkBoxEnableAudio.Enabled = false;
groupBoxSound.Enabled = false;
buttonReset.Enabled = false;
buttonSave.Enabled = false;
buttonCancel.Enabled = false;
SaveToINI();
this.Close();
}
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 checkBoxQuickSwitch_CheckedChanged(object sender, EventArgs e)
{
checkBoxLRLimit.Enabled = checkBoxQuickSwitch.Checked;
}
private void customSizeChange(object sender, EventArgs e)
{
ToggleCustomSizeTextFields();
}
private void checkBoxCustomLinkSprites_CheckedChanged(object sender, EventArgs e)
{
textBoxCustomLink.Enabled = checkBoxCustomLinkSprites.Checked;
buttonOpenSprites.Enabled = checkBoxCustomLinkSprites.Checked;
}
private void checkBoxShader_CheckedChanged(object sender, EventArgs e)
{
textBoxGLSLShader.Enabled = checkBoxShader.Checked;
buttonOpenShader.Enabled = checkBoxShader.Checked;
if (checkBoxShader.Checked)
{
comboRenderMethod.SelectedIndex = 2;
comboRenderMethod.Enabled = false;
}
else
{
comboRenderMethod.Enabled = true;
}
}
private void checkBoxEnableAudio_CheckedChanged(object sender, EventArgs e)
{
groupBoxSound.Enabled = checkBoxEnableAudio.Checked;
}
private void checkBoxEnableMSU_CheckedChanged(object sender, EventArgs e)
{
groupBoxMSUSettings.Enabled = checkBoxEnableMSU.Checked;
}
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");
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"))
{
modifiedFile.WriteLine(line);
}
}
}
}
var iniText = File.ReadAllText(iniFile);
// INI parsing
var config = new IniParserConfiguration();
config.CommentString = "#";
var parser = new IniDataParser(config);
var settings = parser.Parse(iniText);
// General Settings
autosaveCheck.Checked = settings["General"]["Autosave"].ToBool();
performance.Checked = settings["General"]["DisplayPerfInTitle"].ToBool();
disableFrameDelay.Checked = settings["General"]["DisableFrameDelay"].ToBool();
unchangedSprites.Checked = false;
noVisualFixes.Checked = false;
checkBoxExtend.Checked = false;
var ratioSettings = settings["General"]["ExtendedAspectRatio"].Split(',');
foreach(var item in ratioSettings)
{
switch (item.Trim())
{
case "unchanged_sprites":
unchangedSprites.Checked = true;
break;
case "no_visual_fixes":
noVisualFixes.Checked = true;
break;
case "extend_y":
checkBoxExtend.Checked = true;
break;
default:
SetAspectRatio(item.Trim());
break;
}
}
// Graphics Settings
if (!settings["Graphics"]["WindowSize"].Equals("Auto"))
{
var resolution = settings["Graphics"]["WindowSize"].Split("x");
customSize.Checked = true;
height.Text = resolution[0];
width.Text = resolution[1];
}
else
{
windowAuto.Checked = true;
height.Text = "";
width.Text = "";
}
switch (settings["Graphics"]["Fullscreen"])
{
case "0":
radioWindowed.Checked = true;
break;
case "1":
radioFullscreen.Checked = true;
break;
case "2":
radioFullscreenMode.Checked = true;
break;
}
numericWindowScale.Value = Decimal.Parse(settings["Graphics"]["WindowScale"]);
checkPPU.Checked = settings["Graphics"]["NewRenderer"].ToBool();
checkMode7.Checked = settings["Graphics"]["EnhancedMode7"].ToBool();
checkStretch.Checked = settings["Graphics"]["IgnoreAspectRatio"].ToBool();
checkSpriteLimit.Checked = settings["Graphics"]["NoSpriteLimits"].ToBool();
checkLinearFiltering.Checked = settings["Graphics"]["LinearFiltering"].ToBool();
switch (settings["Graphics"]["OutputMethod"])
{
case "SDL":
comboRenderMethod.SelectedIndex = 0;
break;
case "SDL-Software":
comboRenderMethod.SelectedIndex = 1;
break;
case "OpenGL":
comboRenderMethod.SelectedIndex = 2;
break;
}
if (settings["Graphics"]["LinkGraphics"] != null)
{
checkBoxCustomLinkSprites.Checked = true;
textBoxCustomLink.Enabled = true;
textBoxCustomLink.Text = settings["Graphics"]["LinkGraphics"];
buttonOpenSprites.Enabled = true;
}
else
{
checkBoxCustomLinkSprites.Checked = false;
textBoxCustomLink.Enabled = false;
buttonOpenSprites.Enabled = false;
}
if (settings["Graphics"]["Shader"].Equals(""))
{
checkBoxShader.Checked = false;
textBoxGLSLShader.Enabled = false;
textBoxGLSLShader.Text = "";
buttonOpenShader.Enabled = false;
}
else
{
checkBoxShader.Checked = true;
textBoxGLSLShader.Enabled = true;
textBoxGLSLShader.Text = settings["Graphics"]["Shader"];
buttonOpenShader.Enabled = true;
}
// Sound Settings
checkBoxEnableAudio.Checked = settings["Sound"]["EnableAudio"].ToBool();
checkBoxResumeMSU.Checked = settings["Sound"]["ResumeMSU"].ToBool();
textBoxMSUDirectory.Text = settings["Sound"]["MSUPath"];
if (settings["Sound"]["AudioChannels"].Equals("1")) radioButtonMono.Checked = true;
else radioButtonStereo.Checked = true;
switch (settings["Sound"]["AudioFreq"])
{
case "48000":
comboBoxFrequency.SelectedIndex = 0;
break;
case "32000":
comboBoxFrequency.SelectedIndex = 2;
break;
case "22050":
comboBoxFrequency.SelectedIndex = 3;
break;
case "11025":
comboBoxFrequency.SelectedIndex = 4;
break;
default:
comboBoxFrequency.SelectedIndex = 1;
break;
}
switch (settings["Sound"]["AudioSamples"])
{
case "512":
comboBoxSamples.SelectedIndex = 0;
break;
case "1024":
comboBoxSamples.SelectedIndex = 1;
break;
case "2048":
comboBoxSamples.SelectedIndex = 2;
break;
case "4096":
comboBoxSamples.SelectedIndex = 3;
break;
default:
comboBoxSamples.Text = settings["Sound"]["AudioSamples"];
break;
}
var msuVolume = Decimal.Parse(settings["Sound"]["MSUVolume"].Replace("%", ""));
if (msuVolume.IsBetween(0, 100)) numericMSUVolume.Value = msuVolume;
else numericMSUVolume.Value = 100;
if (settings["Sound"]["EnableMSU"].Equals("false"))
{
checkBoxEnableMSU.Checked = false;
}
else
{
checkBoxEnableMSU.Checked = true;
switch (settings["Sound"]["EnableMSU"])
{
case "deluxe":
comboBoxMSU.SelectedIndex = 1;
break;
case "opuz":
comboBoxMSU.SelectedIndex = 2;
break;
case "deluxe-opuz":
comboBoxMSU.SelectedIndex = 3;
break;
default:
comboBoxMSU.SelectedIndex = 0;
break;
}
}
// Gameplay Settings
if (settings["Features"]["ItemSwitchLR"].ToBool())
{
checkBoxQuickSwitch.Checked = true;
checkBoxLRLimit.Enabled= true;
}
else
{
checkBoxQuickSwitch.Checked = false;
checkBoxLRLimit.Enabled = false;
}
checkBoxLRLimit.Checked = settings["Features"]["ItemSwitchLRLimit"].ToBool();
checkBoxDashTurning.Checked = settings["Features"]["TurnWhileDashing"].ToBool();
checkBoxMirrorDark.Checked = settings["Features"]["MirrorToDarkworld"].ToBool();
checkBoxSwordItems.Checked = settings["Features"]["CollectItemsWithSword"].ToBool();
checkBoxSwordPots.Checked = settings["Features"]["BreakPotsWithSword"].ToBool();
checkBoxHeartBeep.Checked = settings["Features"]["DisableLowHealthBeep"].ToBool();
checkBoxIntroSkip.Checked = settings["Features"]["SkipIntroOnKeypress"].ToBool();
checkBoxMaxResources.Checked = settings["Features"]["ShowMaxItemsInYellow"].ToBool();
checkBoxMoreBombs.Checked = settings["Features"]["MoreActiveBombs"].ToBool();
checkBoxLargerWallet.Checked = settings["Features"]["CarryMoreRupees"].ToBool();
checkBoxMiscFixes.Checked = settings["Features"]["MiscBugFixes"].ToBool();
checkBoxMajorFixes.Checked = settings["Features"]["GameChangingBugFixes"].ToBool();
checkBoxCancelBird.Checked = settings["Features"]["CancelBirdTravel"].ToBool();
}
private void SaveToINI()
{
// Build INI data structure from existing zelda3.ini file
var iniFile = Path.Combine(Program.repoDir, "zelda3.ini");
var iniText = File.ReadAllText(iniFile);
var config = new IniParserConfiguration();
config.CommentString = "#";
var parser = new IniDataParser(config);
var settings = parser.Parse(iniText);
//
// General Settings
//
settings["General"]["Autosave"] = Convert.ToInt32(autosaveCheck.Checked).ToString();
settings["General"]["DisplayPerfInTitle"] = Convert.ToInt32(performance.Checked).ToString();
settings["General"]["DisableFrameDelay"] = Convert.ToInt32(disableFrameDelay.Checked).ToString();
// Reading aspect ratio setting
var selection = aspectRatio.Controls.OfType<RadioButton>()
.FirstOrDefault(n => n.Checked).Text;
switch (selection)
{
case "Steam Deck (16:10)":
settings["General"]["ExtendedAspectRatio"] = "16:10";
break;
case "Widescreen (16:9)":
settings["General"]["ExtendedAspectRatio"] = "16:9";
break;
default:
settings["General"]["ExtendedAspectRatio"] = "4:3";
break;
}
if (unchangedSprites.Checked) settings["General"]["ExtendedAspectRatio"] += ", unchanged_sprites";
if (noVisualFixes.Checked) settings["General"]["ExtendedAspectRatio"] += ", no_visual_fixes";
if (checkBoxExtend.Checked) settings["General"]["ExtendedAspectRatio"] += ", extend_y";
//
// Graphics Settings
//
// Reading custom window size or set to auto
selection = windowSize.Controls.OfType<RadioButton>()
.FirstOrDefault(n => n.Checked).Text;
switch (selection)
{
case "Custom":
settings["Graphics"]["WindowSize"] = width.Text + "x" + width.Text;
break;
default:
settings["Graphics"]["WindowSize"] = "Auto";
break;
}
// Reading fullscreen settings
selection = fullscreenMode.Controls.OfType<RadioButton>()
.FirstOrDefault(n => n.Checked).Text;
switch (selection)
{
case "Borderless Fullscreen":
settings["Graphics"]["Fullscreen"] = "1";
break;
case "Fullscreen":
settings["Graphics"]["Fullscreen"] = "2";
break;
default:
settings["Graphics"]["Fullscreen"] = "0";
break;
}
settings["Graphics"]["NewRenderer"] = Convert.ToInt32(checkPPU.Checked).ToString();
settings["Graphics"]["NoSpriteLimits"] = Convert.ToInt32(checkSpriteLimit.Checked).ToString();
settings["Graphics"]["LinearFiltering"] = Convert.ToInt32(checkLinearFiltering.Checked).ToString();
settings["Graphics"]["EnhancedMode7"] = Convert.ToInt32(checkMode7.Checked).ToString();
settings["Graphics"]["IgnoreAspectRatio"] = Convert.ToInt32(checkStretch.Checked).ToString();
settings["Graphics"]["WindowScale"] = Convert.ToInt32(numericWindowScale.Value).ToString();
switch (comboRenderMethod.SelectedIndex)
{
case 0:
settings["Graphics"]["OutputMethod"] = "SDL";
break;
case 1:
settings["Graphics"]["OutputMethod"] = "SDL-Software";
break;
case 2:
settings["Graphics"]["OutputMethod"] = "OpenGL";
break;
}
if (checkBoxCustomLinkSprites.Checked && File.Exists(textBoxCustomLink.Text))
{
if (settings["Graphics"]["LinkGraphics"] == null)
{
settings["Graphics"].AddKey("LinkGraphics", textBoxCustomLink.Text);
var comment = new List<string>();
comment.Add(@" Change the appearance of Link by loading a ZSPR file");
comment.Add(@" See all sprites here: https://snesrev.github.io/sprites-gfx/snes/zelda3/link/");
comment.Add(" Download the files with \"git clone https://github.com/snesrev/sprites-gfx.git\"");
settings["Graphics"].GetKeyData("LinkGraphics").Comments = comment;
}
else settings["Graphics"]["LinkGraphics"] = textBoxCustomLink.Text;
}
else
{
if (settings["Graphics"]["LinkGraphics"] != null)
{
settings["Graphics"].RemoveKey("LinkGraphics");
}
}
if (checkBoxShader.Checked)
{
settings["Graphics"]["Shader"] = textBoxGLSLShader.Text;
}
else
{
settings["Graphics"]["Shader"] = "";
}
//
// Sound Settings
//
// Reading simple settings
settings["Sound"]["EnableAudio"] = Convert.ToInt32(checkBoxEnableAudio.Checked).ToString();
settings["Sound"]["AudioFreq"] = comboBoxFrequency.Text;
settings["Sound"]["ResumeMSU"] = Convert.ToInt32(checkBoxResumeMSU.Checked).ToString();
settings["Sound"]["MSUVolume"] = numericMSUVolume.Value.ToString();
if ((Convert.ToInt32(comboBoxSamples.Text) % 2) == 0)
{
settings["Sound"]["AudioSamples"] = comboBoxSamples.Text;
}
var MSUDir = Path.Combine(Program.repoDir, "msu");
var fileCount = Directory.EnumerateFiles(textBoxMSUDirectory.Text, "*.*", SearchOption.AllDirectories).Count();
progressMSU.Maximum = fileCount;
var msu = textBoxMSUDirectory.Text.Split("/");
if (!msu[0].Equals("msu"))
{
progressMSU.Visible = true;
labelMSUCopy.Visible = true;
labelMSUCopy.Enabled = true;
labelMSUCopy.Refresh();
if (!MSUDir.Equals(textBoxMSUDirectory.Text))
{
if (Directory.Exists(MSUDir)) Directory.Delete(MSUDir, true);
Directory.CreateDirectory(MSUDir);
//Now Create all of the directories
foreach (string dirPath in Directory.GetDirectories(textBoxMSUDirectory.Text, "*", SearchOption.AllDirectories))
{
Directory.CreateDirectory(dirPath.Replace(textBoxMSUDirectory.Text, MSUDir));
}
//Copy all the files & Replaces any files with the same name
foreach (string newPath in Directory.GetFiles(textBoxMSUDirectory.Text, "*.*", SearchOption.AllDirectories))
{
File.Copy(newPath, newPath.Replace(textBoxMSUDirectory.Text, MSUDir), true);
progressMSU.Value = Directory.EnumerateFiles(MSUDir, "*.*", SearchOption.AllDirectories).Count();
}
}
var files = Directory.EnumerateFiles(MSUDir, "*.pcm").Select(Path.GetFileName);
if (files.Count<string>() == 0)
{
files = Directory.EnumerateFiles(MSUDir, "*.opuz").Select(Path.GetFileName);
}
var prefix = findMSUPrefix(files);
settings["Sound"]["MSUPath"] = "msu/" + prefix;
labelMSUCopy.Visible = false;
progressMSU.Visible = false;
}
// Reading audio channels setting
selection = groupBoxAudioChannels.Controls.OfType<RadioButton>()
.FirstOrDefault(n => n.Checked).Text;
switch (selection)
{
case "Mono":
settings["Sound"]["AudioChannels"] = "1";
break;
default:
settings["Sound"]["AudioChannels"] = "2";
break;
}
// Reading MSU version setting
if (checkBoxEnableMSU.Checked)
{
switch (comboBoxMSU.SelectedIndex)
{
case 1:
settings["Sound"]["EnableMSU"] = "deluxe";
settings["Sound"]["AudioFreq"] = "44100";
break;
case 2:
settings["Sound"]["EnableMSU"] = "opuz";
settings["Sound"]["AudioFreq"] = "48000";
break;
case 3:
settings["Sound"]["EnableMSU"] = "deluxe-opuz";
settings["Sound"]["AudioFreq"] = "48000";
break;
default:
settings["Sound"]["EnableMSU"] = "true";
settings["Sound"]["AudioFreq"] = "44100";
break;
}
}
else settings["Sound"]["EnableMSU"] = "false";
//
// Gameplay Settings
//
// Reading simple settings
settings["Features"]["ItemSwitchLR"] = Convert.ToInt32(checkBoxQuickSwitch.Checked).ToString();
settings["Features"]["ItemSwitchLRLimit"] = Convert.ToInt32(checkBoxLRLimit.Checked).ToString();
settings["Features"]["TurnWhileDashing"] = Convert.ToInt32(checkBoxDashTurning.Checked).ToString();
settings["Features"]["MirrorToDarkworld"] = Convert.ToInt32(checkBoxMirrorDark.Checked).ToString();
settings["Features"]["CollectItemsWithSword"] = Convert.ToInt32(checkBoxSwordItems.Checked).ToString();
settings["Features"]["BreakPotsWithSword"] = Convert.ToInt32(checkBoxSwordPots.Checked).ToString();
settings["Features"]["DisableLowHealthBeep"] = Convert.ToInt32(checkBoxHeartBeep.Checked).ToString();
settings["Features"]["SkipIntroOnKeypress"] = Convert.ToInt32(checkBoxIntroSkip.Checked).ToString();
settings["Features"]["ShowMaxItemsInYellow"] = Convert.ToInt32(checkBoxMaxResources.Checked).ToString();
settings["Features"]["MoreActiveBombs"] = Convert.ToInt32(checkBoxMoreBombs.Checked).ToString();
settings["Features"]["CarryMoreRupees"] = Convert.ToInt32(checkBoxLargerWallet.Checked).ToString();
settings["Features"]["MiscBugFixes"] = Convert.ToInt32(checkBoxMiscFixes.Checked).ToString();
settings["Features"]["GameChangingBugFixes"] = Convert.ToInt32(checkBoxMajorFixes.Checked).ToString();
settings["Features"]["CancelBirdTravel"] = Convert.ToInt32(checkBoxCancelBird.Checked).ToString();
// Save settings to zelda3.ini
var filer = new FileIniDataParser();
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
filer.WriteFile(iniFile, settings, Encoding.GetEncoding(1252));
}
private string findMSUPrefix(IEnumerable<string> files)
{
var fileCount = files.Count<string>();
var length = files.Min(n => n.Length);
var reference = files.FirstOrDefault();
var result = "";
for (int i = 0; i < length; i++)
{
for (int j = i + 1; j <= length; j++)
{
int k;
String substring = reference.Substring(i, j - i);
for (k = 1; k < fileCount; k++)
{
if (!files.ElementAt(k).Contains(substring)) break;
}
if (k == fileCount && result.Length < substring.Length) result = substring;
}
}
return result;
}
private void buttonOpenSprites_Click(object sender, EventArgs e)
{
var result = new OpenFileDialog();
result.ShowDialog();
if (result.FileName.Equals("")) return;
if (!result.FileName.EndsWith(".zspr"))
{
MessageBox.Show("Selected file must be of the .zspr format.", "Invalid File Type", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
textBoxCustomLink.Text = result.FileName;
}
private void buttonOpenShader_Click(object sender, EventArgs e)
{
var result = new OpenFileDialog();
result.ShowDialog();
if (result.FileName.Equals("")) return;
if (!result.FileName.EndsWith(".glsl") && !result.FileName.EndsWith(".glslp"))
{
MessageBox.Show("Selected file must be of the .glsl or .glslp formats.", "Invalid File Type", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
textBoxGLSLShader.Text = result.FileName;
}
private void buttonMSUDirectory_Click(object sender, EventArgs e)
{
if (!Program.messageMSU)
{
MessageBox.Show("MSU files MUST be within the zelda3 directory structure. "
+ "Therefore, whatever directory you select will be entirely copied to the proper location. "
+ "Please be cautious in your directory selection.", "Caution", MessageBoxButtons.OK, MessageBoxIcon.Warning);
Program.messageMSU = true;
}
var result = new FolderBrowserDialog();
result.ShowDialog();
if (Directory.GetFiles(result.SelectedPath, "*.pcm").Length.Equals(0))
{
if (Directory.GetFiles(result.SelectedPath, "*.opuz").Length.Equals(0))
{
MessageBox.Show("No MSU files were found in the selected directory. Please verify the correct folder was selected and that the proper .pcm or .opuz files are available.", "No MSU Files Found", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
if (!result.SelectedPath.Equals("")) textBoxMSUDirectory.Text = result.SelectedPath;
}
private void SetAspectRatio(string aspectRatio)
{
switch (aspectRatio)
{
case "4:3":
normal.Checked = true;
break;
case "16:9":
widescreen.Checked = true;
break;
case "16:10":
steamdeck.Checked = true;
break;
}
}
private void linkLabelCustomSprites_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
this.linkLabelCustomSprites.LinkVisited = true;
Process.Start(new ProcessStartInfo("https://snesrev.github.io/sprites-gfx/snes/zelda3/link/") { UseShellExecute = true });
}
private void linkLabelGLSLShaders_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
this.linkLabelCustomSprites.LinkVisited = true;
Process.Start(new ProcessStartInfo("https://github.com/snesrev/glsl-shaders") { UseShellExecute = true });
}
}
}

View File

@ -0,0 +1,103 @@
<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>
<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="checkBoxQuickSwitch.ToolTip" xml:space="preserve">
<value>Allows you to switch items with L/R but also allows you to assign items to X, Y, L, and R.
If X is assigned an item, select will now open the map. To save and quit, you will need to hit Select while in the item menu.
If L and/or R are assigned an item, quick item switching will be disabled.</value>
</data>
<data name="checkBoxEnableMSU.ToolTip" xml:space="preserve">
<value>Enable MSU support for audio.
Supports MSU or MSU Deluxe in PCM or OPUZ format.
PCM MUS requires audio frequency be set to 44100 to work properly.
OPUZ requires audio frequency to be set to 48000.</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAJ0NAACdDQAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAMAAAAAAAKAAAAGQAAABkAAAAKTgwAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAMQcAAAAAACQZBAB6RwsAumIPANRiDwDURgoAuhkEAHoAAAAkMAcAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAQgBAFhbDgDZuxwA/+0jAP/7JQD/+yUA/+0jAP+6HAD/Ww4A2QcB
AFgAAAABAAAAAAAAAAAAAAAAAAAACgAAAF10EQDv8CQA//glAP/mIgD/6CMA/+gjAP/nIgD//SYA/+8k
AP94EgDvBwEAWDAHAAAAAAAAAAAAAAAAAEUKAgDpcBEA//0mAP/mIgD/gBMA/zAHAP82CAD/nRcA//Ik
AP//JgD/7yQA/1sOANkAAAAkAAAAAFEMAAAeBAB5kRYA/zoJAP+WFgD//ycA/6waAP8cBAD/JgYA/9Yg
AP//JgD//yYA//8nAP+6HAD/GQQAek4MAAAAAAAKRwsAuu4kAP+8HAD/MAcA/74cAP+xGgD/IwUA/ywH
AP/YIAD//ycA//8mAP//JgD/6yMA/0YKALoAAAAKAAAAGWIPANT6JQD//ycA/4oUAP83CAD/hxQA/yYG
AP8tBwD/yh4A/88fAP/aIAD//iYA//olAP9iDwDUAAAAGQAAABliDwDU9yUA/6cZAP+GFAD/rxoA/5IW
AP8lBgD/LQcA/8geAP/NHwD/hxQA/5cWAP/3JQD/Yg8A1AAAABkAAAAKSgsAur0cAP83CAD/1yAA//8o
AP+wGgD/IwUA/ywHAP/YIAD//ycA/94hAP84CAD/vxwA/0oLALoAAAAKUAwAACAFAHqCEwD/LwcA/9Ef
AP//JwD/rhoA/xwEAP8lBgD/1SAA//8nAP/OHwD/KgYA/4MTAP8gBQB6TgwAAAAAAAAAAAAkUwwA2XkS
AP9mDwD/khYA/3QRAP8zCAD/NggA/44VAP+pGQD/ahAA/3ERAP9RDADZAAAAJAAAAAAAAAAANQgAAAkB
AFh4EgDv2yEA/+UiAP/mIgD/6SMA/+kjAP/mIgD/5yIA/9kgAP93EgDvCQEAWDUIAAAAAAAAAAAAAAAA
AAAAAAABBwEAWF0OANm8HAD/7SMA//slAP/7JQD/7SMA/7scAP9dDgDZBwEAWAAAAAEAAAAAAAAAAAAA
AAAAAAAAAAAAADEHAAAAAAAkGQQAekcLALpiDwDUYg8A1EYKALoZBAB6AAAAJDAHAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAMAAAAAAAKAAAAGQAAABkAAAAKTwwAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAwAMAAIABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AACAAQAAwAMAAA==
</value>
</data>
</root>