diff --git a/.gitignore b/.gitignore
index 9b50ff9..7905424 100644
--- a/.gitignore
+++ b/.gitignore
@@ -188,4 +188,3 @@ Libretro/*
Docs/*
Lua/*
TestHelper/*
-UpdateHelper/*
diff --git a/UI/Dependencies/resources.en.xml b/UI/Dependencies/resources.en.xml
index 159043c..7f37c74 100644
--- a/UI/Dependencies/resources.en.xml
+++ b/UI/Dependencies/resources.en.xml
@@ -557,7 +557,7 @@
Mesen-S
© 2019 M. Bibaud (aka Sour)
Website:
- www.mesen.ca
+ www.mesen.ca/snes/
Version:
Build Date:
If you want to support Mesen-S, please consider donating.
Thank you for your support!
diff --git a/UI/Forms/frmAbout.cs b/UI/Forms/frmAbout.cs
new file mode 100644
index 0000000..d869d1b
--- /dev/null
+++ b/UI/Forms/frmAbout.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Drawing;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Mesen.GUI.Forms
+{
+ partial class frmAbout : BaseForm
+ {
+ public frmAbout()
+ {
+ InitializeComponent();
+
+ lblMesenVersion.Text = EmuApi.GetMesenVersion().ToString(3);
+
+ Version ver = Assembly.GetEntryAssembly().GetName().Version;
+ DateTime buildTime = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddDays(ver.Build).AddSeconds(ver.Revision * 2);
+ lblBuildDate.Text = buildTime.ToShortDateString() + " " + buildTime.ToShortTimeString();
+
+#if AUTOBUILD
+ string devVersion = ResourceManager.ReadZippedResource("DevBuild.txt");
+ if(devVersion != null) {
+ lblMesenVersion.Text = devVersion;
+ }
+#endif
+ }
+
+ private void lblLink_Click(object sender, EventArgs e)
+ {
+ Process.Start("https://www.mesen.ca/snes/");
+ }
+
+ private void picDonate_Click(object sender, EventArgs e)
+ {
+ Process.Start("https://www.mesen.ca/Donate.php?l=" + ResourceHelper.GetLanguageCode());
+ }
+ }
+}
diff --git a/UI/Forms/frmAbout.designer.cs b/UI/Forms/frmAbout.designer.cs
new file mode 100644
index 0000000..d5e9b76
--- /dev/null
+++ b/UI/Forms/frmAbout.designer.cs
@@ -0,0 +1,309 @@
+namespace Mesen.GUI.Forms
+{
+ partial class frmAbout
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ protected override void Dispose(bool disposing)
+ {
+ if(disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmAbout));
+ this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
+ this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel();
+ this.lblBuildDateLabel = new System.Windows.Forms.Label();
+ this.lblBuildDate = new System.Windows.Forms.Label();
+ this.logoPictureBox = new System.Windows.Forms.PictureBox();
+ this.labelProductName = new System.Windows.Forms.Label();
+ this.labelCopyright = new System.Windows.Forms.Label();
+ this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
+ this.lblWebsite = new System.Windows.Forms.Label();
+ this.lblLink = new System.Windows.Forms.Label();
+ this.okButton = new System.Windows.Forms.Button();
+ this.picDonate = new System.Windows.Forms.PictureBox();
+ this.lblDonate = new System.Windows.Forms.Label();
+ this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
+ this.labelVersion = new System.Windows.Forms.Label();
+ this.lblMesenVersion = new System.Windows.Forms.Label();
+ this.tableLayoutPanel.SuspendLayout();
+ this.flowLayoutPanel3.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();
+ this.flowLayoutPanel1.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.picDonate)).BeginInit();
+ this.flowLayoutPanel2.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // tableLayoutPanel
+ //
+ this.tableLayoutPanel.AutoSize = true;
+ this.tableLayoutPanel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
+ this.tableLayoutPanel.ColumnCount = 2;
+ this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 84F));
+ this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel.Controls.Add(this.flowLayoutPanel3, 1, 2);
+ this.tableLayoutPanel.Controls.Add(this.logoPictureBox, 0, 0);
+ this.tableLayoutPanel.Controls.Add(this.labelProductName, 1, 0);
+ this.tableLayoutPanel.Controls.Add(this.labelCopyright, 1, 3);
+ this.tableLayoutPanel.Controls.Add(this.flowLayoutPanel1, 1, 4);
+ this.tableLayoutPanel.Controls.Add(this.okButton, 1, 6);
+ this.tableLayoutPanel.Controls.Add(this.picDonate, 0, 6);
+ this.tableLayoutPanel.Controls.Add(this.lblDonate, 0, 5);
+ this.tableLayoutPanel.Controls.Add(this.flowLayoutPanel2, 1, 1);
+ this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel.Location = new System.Drawing.Point(5, 5);
+ this.tableLayoutPanel.Name = "tableLayoutPanel";
+ this.tableLayoutPanel.RowCount = 8;
+ this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel.Size = new System.Drawing.Size(337, 151);
+ this.tableLayoutPanel.TabIndex = 0;
+ //
+ // flowLayoutPanel3
+ //
+ this.flowLayoutPanel3.Controls.Add(this.lblBuildDateLabel);
+ this.flowLayoutPanel3.Controls.Add(this.lblBuildDate);
+ this.flowLayoutPanel3.Location = new System.Drawing.Point(84, 38);
+ this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0, 3, 0, 0);
+ this.flowLayoutPanel3.Name = "flowLayoutPanel3";
+ this.flowLayoutPanel3.Size = new System.Drawing.Size(250, 15);
+ this.flowLayoutPanel3.TabIndex = 32;
+ //
+ // lblBuildDateLabel
+ //
+ this.lblBuildDateLabel.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblBuildDateLabel.AutoSize = true;
+ this.lblBuildDateLabel.Location = new System.Drawing.Point(6, 0);
+ this.lblBuildDateLabel.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
+ this.lblBuildDateLabel.Name = "lblBuildDateLabel";
+ this.lblBuildDateLabel.Size = new System.Drawing.Size(59, 13);
+ this.lblBuildDateLabel.TabIndex = 0;
+ this.lblBuildDateLabel.Text = "Build Date:";
+ this.lblBuildDateLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // lblBuildDate
+ //
+ this.lblBuildDate.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblBuildDate.AutoSize = true;
+ this.lblBuildDate.Location = new System.Drawing.Point(71, 0);
+ this.lblBuildDate.Name = "lblBuildDate";
+ this.lblBuildDate.Size = new System.Drawing.Size(65, 13);
+ this.lblBuildDate.TabIndex = 1;
+ this.lblBuildDate.Text = "";
+ //
+ // logoPictureBox
+ //
+ this.logoPictureBox.Anchor = System.Windows.Forms.AnchorStyles.Top;
+ this.logoPictureBox.Image = global::Mesen.GUI.Properties.Resources.MesenSIcon;
+ this.logoPictureBox.Location = new System.Drawing.Point(12, 12);
+ this.logoPictureBox.Margin = new System.Windows.Forms.Padding(4, 12, 0, 5);
+ this.logoPictureBox.Name = "logoPictureBox";
+ this.tableLayoutPanel.SetRowSpan(this.logoPictureBox, 5);
+ this.logoPictureBox.Size = new System.Drawing.Size(64, 65);
+ this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+ this.logoPictureBox.TabIndex = 12;
+ this.logoPictureBox.TabStop = false;
+ //
+ // labelProductName
+ //
+ this.labelProductName.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.labelProductName.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.labelProductName.Location = new System.Drawing.Point(90, 0);
+ this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
+ this.labelProductName.Name = "labelProductName";
+ this.labelProductName.Size = new System.Drawing.Size(244, 17);
+ this.labelProductName.TabIndex = 19;
+ this.labelProductName.Text = "Mesen-S";
+ this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // labelCopyright
+ //
+ this.labelCopyright.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.labelCopyright.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.labelCopyright.Location = new System.Drawing.Point(90, 53);
+ this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
+ this.labelCopyright.Name = "labelCopyright";
+ this.labelCopyright.Size = new System.Drawing.Size(244, 17);
+ this.labelCopyright.TabIndex = 21;
+ this.labelCopyright.Text = "© 2019 M. Bibaud (aka Sour)";
+ this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // flowLayoutPanel1
+ //
+ this.flowLayoutPanel1.Controls.Add(this.lblWebsite);
+ this.flowLayoutPanel1.Controls.Add(this.lblLink);
+ this.flowLayoutPanel1.Location = new System.Drawing.Point(84, 70);
+ this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
+ this.flowLayoutPanel1.Name = "flowLayoutPanel1";
+ this.flowLayoutPanel1.Size = new System.Drawing.Size(236, 18);
+ this.flowLayoutPanel1.TabIndex = 26;
+ //
+ // lblWebsite
+ //
+ this.lblWebsite.AutoSize = true;
+ this.lblWebsite.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblWebsite.Location = new System.Drawing.Point(6, 0);
+ this.lblWebsite.Margin = new System.Windows.Forms.Padding(6, 0, 0, 0);
+ this.lblWebsite.Name = "lblWebsite";
+ this.lblWebsite.Size = new System.Drawing.Size(61, 16);
+ this.lblWebsite.TabIndex = 25;
+ this.lblWebsite.Text = "Website:";
+ this.lblWebsite.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // lblLink
+ //
+ this.lblLink.AutoSize = true;
+ this.lblLink.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.lblLink.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblLink.ForeColor = System.Drawing.Color.Blue;
+ this.lblLink.Location = new System.Drawing.Point(67, 2);
+ this.lblLink.Margin = new System.Windows.Forms.Padding(0, 2, 3, 0);
+ this.lblLink.Name = "lblLink";
+ this.lblLink.Size = new System.Drawing.Size(112, 13);
+ this.lblLink.TabIndex = 26;
+ this.lblLink.Text = "www.mesen.ca/snes/";
+ this.lblLink.Click += new System.EventHandler(this.lblLink_Click);
+ //
+ // okButton
+ //
+ this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.okButton.Location = new System.Drawing.Point(259, 122);
+ this.okButton.Name = "okButton";
+ this.okButton.Size = new System.Drawing.Size(75, 23);
+ this.okButton.TabIndex = 24;
+ this.okButton.Text = "&OK";
+ //
+ // picDonate
+ //
+ this.picDonate.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.picDonate.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.picDonate.Image = ((System.Drawing.Image)(resources.GetObject("picDonate.Image")));
+ this.picDonate.Location = new System.Drawing.Point(3, 122);
+ this.picDonate.Name = "picDonate";
+ this.picDonate.Size = new System.Drawing.Size(78, 22);
+ this.picDonate.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+ this.picDonate.TabIndex = 29;
+ this.picDonate.TabStop = false;
+ this.picDonate.Click += new System.EventHandler(this.picDonate_Click);
+ //
+ // lblDonate
+ //
+ this.lblDonate.AutoSize = true;
+ this.tableLayoutPanel.SetColumnSpan(this.lblDonate, 2);
+ this.lblDonate.Location = new System.Drawing.Point(0, 93);
+ this.lblDonate.Margin = new System.Windows.Forms.Padding(0, 5, 0, 0);
+ this.lblDonate.Name = "lblDonate";
+ this.lblDonate.Size = new System.Drawing.Size(281, 26);
+ this.lblDonate.TabIndex = 30;
+ this.lblDonate.Text = "If you want to support Mesen-S, please consider donating.\r\nThank you for your sup" +
+ "port!";
+ //
+ // flowLayoutPanel2
+ //
+ this.flowLayoutPanel2.Controls.Add(this.labelVersion);
+ this.flowLayoutPanel2.Controls.Add(this.lblMesenVersion);
+ this.flowLayoutPanel2.Location = new System.Drawing.Point(84, 20);
+ this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0, 3, 0, 0);
+ this.flowLayoutPanel2.Name = "flowLayoutPanel2";
+ this.flowLayoutPanel2.Size = new System.Drawing.Size(250, 15);
+ this.flowLayoutPanel2.TabIndex = 31;
+ //
+ // labelVersion
+ //
+ this.labelVersion.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.labelVersion.AutoSize = true;
+ this.labelVersion.Location = new System.Drawing.Point(6, 0);
+ this.labelVersion.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);
+ this.labelVersion.Name = "labelVersion";
+ this.labelVersion.Size = new System.Drawing.Size(45, 13);
+ this.labelVersion.TabIndex = 0;
+ this.labelVersion.Text = "Version:";
+ this.labelVersion.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ //
+ // lblMesenVersion
+ //
+ this.lblMesenVersion.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblMesenVersion.AutoSize = true;
+ this.lblMesenVersion.Location = new System.Drawing.Point(57, 0);
+ this.lblMesenVersion.Name = "lblMesenVersion";
+ this.lblMesenVersion.Size = new System.Drawing.Size(53, 13);
+ this.lblMesenVersion.TabIndex = 1;
+ this.lblMesenVersion.Text = "";
+ //
+ // frmAbout
+ //
+ this.AcceptButton = this.okButton;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.AutoSize = true;
+ this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
+ this.CancelButton = this.okButton;
+ this.ClientSize = new System.Drawing.Size(347, 161);
+ this.Controls.Add(this.tableLayoutPanel);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "frmAbout";
+ this.Padding = new System.Windows.Forms.Padding(5);
+ this.ShowInTaskbar = false;
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "About - Mesen";
+ this.tableLayoutPanel.ResumeLayout(false);
+ this.tableLayoutPanel.PerformLayout();
+ this.flowLayoutPanel3.ResumeLayout(false);
+ this.flowLayoutPanel3.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();
+ this.flowLayoutPanel1.ResumeLayout(false);
+ this.flowLayoutPanel1.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.picDonate)).EndInit();
+ this.flowLayoutPanel2.ResumeLayout(false);
+ this.flowLayoutPanel2.PerformLayout();
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
+ private System.Windows.Forms.PictureBox logoPictureBox;
+ private System.Windows.Forms.Label labelProductName;
+ private System.Windows.Forms.Label labelVersion;
+ private System.Windows.Forms.Label labelCopyright;
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
+ private System.Windows.Forms.Label lblWebsite;
+ private System.Windows.Forms.Label lblLink;
+ private System.Windows.Forms.Button okButton;
+ private System.Windows.Forms.PictureBox picDonate;
+ private System.Windows.Forms.Label lblDonate;
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
+ private System.Windows.Forms.Label lblMesenVersion;
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3;
+ private System.Windows.Forms.Label lblBuildDateLabel;
+ private System.Windows.Forms.Label lblBuildDate;
+ }
+}
diff --git a/UI/Forms/frmAbout.resx b/UI/Forms/frmAbout.resx
new file mode 100644
index 0000000..7ff960c
--- /dev/null
+++ b/UI/Forms/frmAbout.resx
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+
+ 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
+ lur5gpmZ/QdCEW0eU8qyCQAAAABJRU5ErkJggg==
+
+
+
\ No newline at end of file
diff --git a/UI/Forms/frmMain.Designer.cs b/UI/Forms/frmMain.Designer.cs
index d822afa..966e1e3 100644
--- a/UI/Forms/frmMain.Designer.cs
+++ b/UI/Forms/frmMain.Designer.cs
@@ -100,8 +100,8 @@
this.mnuBilinearInterpolation = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
this.mnuAudioConfig = new System.Windows.Forms.ToolStripMenuItem();
- this.mnuVideoConfig = new System.Windows.Forms.ToolStripMenuItem();
this.mnuInputConfig = new System.Windows.Forms.ToolStripMenuItem();
+ this.mnuVideoConfig = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEmulationConfig = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
this.mnuPreferences = new System.Windows.Forms.ToolStripMenuItem();
@@ -299,7 +299,7 @@
this.mnuShowFPS});
this.mnuEmulationSpeed.Image = global::Mesen.GUI.Properties.Resources.Speed;
this.mnuEmulationSpeed.Name = "mnuEmulationSpeed";
- this.mnuEmulationSpeed.Size = new System.Drawing.Size(152, 22);
+ this.mnuEmulationSpeed.Size = new System.Drawing.Size(135, 22);
this.mnuEmulationSpeed.Text = "Speed";
this.mnuEmulationSpeed.DropDownOpening += new System.EventHandler(this.mnuEmulationSpeed_DropDownOpening);
//
@@ -387,7 +387,7 @@
this.mnuFullscreen});
this.mnuVideoScale.Image = global::Mesen.GUI.Properties.Resources.Fullscreen;
this.mnuVideoScale.Name = "mnuVideoScale";
- this.mnuVideoScale.Size = new System.Drawing.Size(152, 22);
+ this.mnuVideoScale.Size = new System.Drawing.Size(135, 22);
this.mnuVideoScale.Text = "Video Size";
this.mnuVideoScale.DropDownOpening += new System.EventHandler(this.mnuVideoScale_DropDownOpening);
//
@@ -473,7 +473,7 @@
this.mnuBilinearInterpolation});
this.mnuVideoFilter.Image = global::Mesen.GUI.Properties.Resources.VideoFilter;
this.mnuVideoFilter.Name = "mnuVideoFilter";
- this.mnuVideoFilter.Size = new System.Drawing.Size(152, 22);
+ this.mnuVideoFilter.Size = new System.Drawing.Size(135, 22);
this.mnuVideoFilter.Text = "Video Filter";
this.mnuVideoFilter.DropDownOpening += new System.EventHandler(this.mnuVideoFilter_DropDownOpening);
//
@@ -654,50 +654,50 @@
// toolStripMenuItem4
//
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
- this.toolStripMenuItem4.Size = new System.Drawing.Size(149, 6);
+ this.toolStripMenuItem4.Size = new System.Drawing.Size(132, 6);
//
// mnuAudioConfig
//
this.mnuAudioConfig.Image = global::Mesen.GUI.Properties.Resources.Audio;
this.mnuAudioConfig.Name = "mnuAudioConfig";
- this.mnuAudioConfig.Size = new System.Drawing.Size(152, 22);
+ this.mnuAudioConfig.Size = new System.Drawing.Size(135, 22);
this.mnuAudioConfig.Text = "Audio";
this.mnuAudioConfig.Click += new System.EventHandler(this.mnuAudioConfig_Click);
//
- // mnuVideoConfig
- //
- this.mnuVideoConfig.Image = global::Mesen.GUI.Properties.Resources.VideoOptions;
- this.mnuVideoConfig.Name = "mnuVideoConfig";
- this.mnuVideoConfig.Size = new System.Drawing.Size(152, 22);
- this.mnuVideoConfig.Text = "Video";
- this.mnuVideoConfig.Click += new System.EventHandler(this.mnuVideoConfig_Click);
- //
// mnuInputConfig
//
this.mnuInputConfig.Image = global::Mesen.GUI.Properties.Resources.Controller;
this.mnuInputConfig.Name = "mnuInputConfig";
- this.mnuInputConfig.Size = new System.Drawing.Size(152, 22);
+ this.mnuInputConfig.Size = new System.Drawing.Size(135, 22);
this.mnuInputConfig.Text = "Input";
this.mnuInputConfig.Click += new System.EventHandler(this.mnuInputConfig_Click);
//
+ // mnuVideoConfig
+ //
+ this.mnuVideoConfig.Image = global::Mesen.GUI.Properties.Resources.VideoOptions;
+ this.mnuVideoConfig.Name = "mnuVideoConfig";
+ this.mnuVideoConfig.Size = new System.Drawing.Size(135, 22);
+ this.mnuVideoConfig.Text = "Video";
+ this.mnuVideoConfig.Click += new System.EventHandler(this.mnuVideoConfig_Click);
+ //
// mnuEmulationConfig
//
this.mnuEmulationConfig.Image = global::Mesen.GUI.Properties.Resources.DipSwitches;
this.mnuEmulationConfig.Name = "mnuEmulationConfig";
- this.mnuEmulationConfig.Size = new System.Drawing.Size(152, 22);
+ this.mnuEmulationConfig.Size = new System.Drawing.Size(135, 22);
this.mnuEmulationConfig.Text = "Emulation";
this.mnuEmulationConfig.Click += new System.EventHandler(this.mnuEmulationConfig_Click);
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
- this.toolStripMenuItem3.Size = new System.Drawing.Size(149, 6);
+ this.toolStripMenuItem3.Size = new System.Drawing.Size(132, 6);
//
// mnuPreferences
//
this.mnuPreferences.Image = global::Mesen.GUI.Properties.Resources.Settings;
this.mnuPreferences.Name = "mnuPreferences";
- this.mnuPreferences.Size = new System.Drawing.Size(152, 22);
+ this.mnuPreferences.Size = new System.Drawing.Size(135, 22);
this.mnuPreferences.Text = "Preferences";
this.mnuPreferences.Click += new System.EventHandler(this.mnuPreferences_Click);
//
@@ -794,13 +794,13 @@
this.mnuHelp.Name = "mnuHelp";
this.mnuHelp.Size = new System.Drawing.Size(44, 20);
this.mnuHelp.Text = "Help";
- this.mnuHelp.Visible = false;
//
// mnuCheckForUpdates
//
this.mnuCheckForUpdates.Name = "mnuCheckForUpdates";
this.mnuCheckForUpdates.Size = new System.Drawing.Size(170, 22);
this.mnuCheckForUpdates.Text = "Check for updates";
+ this.mnuCheckForUpdates.Click += new System.EventHandler(this.mnuCheckForUpdates_Click);
//
// toolStripMenuItem20
//
@@ -813,6 +813,7 @@
this.mnuReportBug.Name = "mnuReportBug";
this.mnuReportBug.Size = new System.Drawing.Size(170, 22);
this.mnuReportBug.Text = "Report a bug";
+ this.mnuReportBug.Click += new System.EventHandler(this.mnuReportBug_Click);
//
// toolStripMenuItem5
//
@@ -825,6 +826,7 @@
this.mnuAbout.Name = "mnuAbout";
this.mnuAbout.Size = new System.Drawing.Size(170, 22);
this.mnuAbout.Text = "About";
+ this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
//
// pnlRenderer
//
diff --git a/UI/Forms/frmMain.cs b/UI/Forms/frmMain.cs
index 9f9807b..21cda40 100644
--- a/UI/Forms/frmMain.cs
+++ b/UI/Forms/frmMain.cs
@@ -3,10 +3,12 @@ using Mesen.GUI.Config.Shortcuts;
using Mesen.GUI.Debugger;
using Mesen.GUI.Emulation;
using Mesen.GUI.Forms.Config;
+using Mesen.GUI.Updates;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
+using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
@@ -282,6 +284,23 @@ namespace Mesen.GUI.Forms
new frmLogWindow().Show();
}
+ private void mnuCheckForUpdates_Click(object sender, EventArgs e)
+ {
+ UpdateHelper.CheckForUpdates(false);
+ }
+
+ private void mnuReportBug_Click(object sender, EventArgs e)
+ {
+ Process.Start("https://www.mesen.ca/snes/ReportBug.php");
+ }
+
+ private void mnuAbout_Click(object sender, EventArgs e)
+ {
+ using(frmAbout frm = new frmAbout()) {
+ frm.ShowDialog(this);
+ }
+ }
+
private void mnuFile_DropDownOpening(object sender, EventArgs e)
{
mnuRecentFiles.DropDownItems.Clear();
diff --git a/UI/Interop/EmuApi.cs b/UI/Interop/EmuApi.cs
index 2ec3aff..154416f 100644
--- a/UI/Interop/EmuApi.cs
+++ b/UI/Interop/EmuApi.cs
@@ -19,6 +19,14 @@ namespace Mesen.GUI
[DllImport(DllPath)] public static extern void InitDll();
[DllImport(DllPath, EntryPoint = "GetMesenVersion")] private static extern UInt32 GetMesenVersionWrapper();
+ public static Version GetMesenVersion()
+ {
+ UInt32 version = GetMesenVersionWrapper();
+ UInt32 revision = version & 0xFF;
+ UInt32 minor = (version >> 8) & 0xFF;
+ UInt32 major = (version >> 16) & 0xFFFF;
+ return new Version((int)major, (int)minor, (int)revision, 0);
+ }
[DllImport(DllPath)] public static extern IntPtr RegisterNotificationCallback(NotificationListener.NotificationCallback callback);
[DllImport(DllPath)] public static extern void UnregisterNotificationCallback(IntPtr notificationListener);
diff --git a/UI/Properties/Resources.Designer.cs b/UI/Properties/Resources.Designer.cs
index 0208499..da07a21 100644
--- a/UI/Properties/Resources.Designer.cs
+++ b/UI/Properties/Resources.Designer.cs
@@ -580,6 +580,16 @@ namespace Mesen.GUI.Properties {
}
}
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap MesenSIcon {
+ get {
+ object obj = ResourceManager.GetObject("MesenSIcon", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
diff --git a/UI/Properties/Resources.resx b/UI/Properties/Resources.resx
index bfddda1..e31f212 100644
--- a/UI/Properties/Resources.resx
+++ b/UI/Properties/Resources.resx
@@ -448,4 +448,7 @@
..\Resources\Zoom2x.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ ..\Resources\MesenSIcon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
\ No newline at end of file
diff --git a/UI/ResourceExtractor.cs b/UI/ResourceExtractor.cs
index d943b1d..da93c20 100644
--- a/UI/ResourceExtractor.cs
+++ b/UI/ResourceExtractor.cs
@@ -98,7 +98,7 @@ namespace Mesen.GUI
string outputFilename = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), entry.Name.Replace(suffix, ""));
ExtractFile(entry, outputFilename);
} else if(entry.Name == "MesenUpdater.exe") {
- string outputFilename = Path.Combine(ConfigManager.HomeFolder, entry.Name);
+ string outputFilename = Path.Combine(ConfigManager.HomeFolder, "Resources", entry.Name);
ExtractFile(entry, outputFilename);
} else if(entry.Name == "Font.24.spritefont" || entry.Name == "Font.64.spritefont" || entry.Name == "LICENSE.txt" || entry.Name == "PixelFont.ttf") {
string outputFilename = Path.Combine(ConfigManager.HomeFolder, "Resources", entry.Name);
diff --git a/UI/Resources/MesenSIcon.png b/UI/Resources/MesenSIcon.png
new file mode 100644
index 0000000..8b41e08
Binary files /dev/null and b/UI/Resources/MesenSIcon.png differ
diff --git a/UI/UI.csproj b/UI/UI.csproj
index f1c8a09..c02b47b 100644
--- a/UI/UI.csproj
+++ b/UI/UI.csproj
@@ -542,6 +542,12 @@
+
+ Form
+
+
+ frmAbout.cs
+
Form
@@ -560,6 +566,18 @@
frmSelectRom.cs
+
+ Form
+
+
+ frmDownloadProgress.cs
+
+
+ Form
+
+
+ frmUpdatePrompt.cs
+
@@ -580,7 +598,9 @@
+
+
ctrlPathSelection.cs
@@ -708,6 +728,9 @@
frmVideoConfig.cs
+
+ frmAbout.cs
+
frmLogWindow.cs
@@ -717,6 +740,12 @@
frmSelectRom.cs
+
+ frmDownloadProgress.cs
+
+
+ frmUpdatePrompt.cs
+
ResXFileCodeGenerator
Resources.Designer.cs
diff --git a/UI/Updates/UpdateHelper.cs b/UI/Updates/UpdateHelper.cs
new file mode 100644
index 0000000..0cb65ed
--- /dev/null
+++ b/UI/Updates/UpdateHelper.cs
@@ -0,0 +1,50 @@
+using Mesen.GUI.Forms;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Xml;
+
+namespace Mesen.GUI.Updates
+{
+ public static class UpdateHelper
+ {
+ public static void CheckForUpdates(bool silent)
+ {
+ Task.Run(() => {
+ try {
+ using(var client = new WebClient()) {
+ XmlDocument xmlDoc = new XmlDocument();
+
+ string platform = Program.IsMono ? "linux" : "win";
+ xmlDoc.LoadXml(client.DownloadString("https://www.mesen.ca/snes/Services/GetLatestVersion.php?v=" + EmuApi.GetMesenVersion().ToString(3) + "&p=" + platform + "&l=" + ResourceHelper.GetLanguageCode()));
+ Version currentVersion = EmuApi.GetMesenVersion();
+ Version latestVersion = new Version(xmlDoc.SelectSingleNode("VersionInfo/LatestVersion").InnerText);
+ string changeLog = xmlDoc.SelectSingleNode("VersionInfo/ChangeLog").InnerText;
+ string fileHash = xmlDoc.SelectSingleNode("VersionInfo/Sha1Hash").InnerText;
+ string donateText = xmlDoc.SelectSingleNode("VersionInfo/DonateText")?.InnerText;
+
+ if(latestVersion > currentVersion) {
+ Application.OpenForms[0].BeginInvoke((MethodInvoker)(() => {
+ using(frmUpdatePrompt frmUpdate = new frmUpdatePrompt(currentVersion, latestVersion, changeLog, fileHash, donateText)) {
+ if(frmUpdate.ShowDialog(null, Application.OpenForms[0]) == DialogResult.OK) {
+ Application.Exit();
+ }
+ }
+ }));
+ } else if(!silent) {
+ MesenMsgBox.Show("MesenUpToDate", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ }
+ } catch(Exception ex) {
+ if(!silent) {
+ MesenMsgBox.Show("ErrorWhileCheckingUpdates", MessageBoxButtons.OK, MessageBoxIcon.Error, ex.ToString());
+ }
+ }
+ });
+ }
+ }
+}
diff --git a/UI/Updates/frmDownloadProgress.cs b/UI/Updates/frmDownloadProgress.cs
new file mode 100644
index 0000000..4737584
--- /dev/null
+++ b/UI/Updates/frmDownloadProgress.cs
@@ -0,0 +1,99 @@
+using Mesen.GUI.Forms;
+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.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace Mesen.GUI.Updates
+{
+ public partial class frmDownloadProgress : BaseForm
+ {
+ private string _link;
+ private string _filename;
+ private bool _cancel = false;
+
+ public frmDownloadProgress(string link, string filename)
+ {
+ InitializeComponent();
+
+ _link = link;
+ _filename = filename;
+
+ try {
+ File.Delete(_filename);
+ } catch {}
+
+ lblFilename.Text = link;
+
+ tmrStart.Start();
+ }
+
+ protected override void OnClosing(CancelEventArgs e)
+ {
+ _cancel = true;
+ base.OnClosing(e);
+ }
+
+ private void tmrStart_Tick(object sender, EventArgs e)
+ {
+ tmrStart.Stop();
+
+ DialogResult result = DialogResult.None;
+
+ Task.Run(() => {
+ using(var client = new WebClient()) {
+ client.DownloadProgressChanged += (object s, DownloadProgressChangedEventArgs args) => {
+ this.BeginInvoke((Action)(() => {
+ lblFilename.Text = string.Format("{0} ({1:0.00}Mb)", _link, (double)args.TotalBytesToReceive/1024/1024);
+ progressDownload.Value = args.ProgressPercentage;
+ }));
+ };
+ client.DownloadFileCompleted += (object s, AsyncCompletedEventArgs args) => {
+ if(!args.Cancelled && args.Error == null && File.Exists(_filename)) {
+ result = DialogResult.OK;
+ } else if(args.Error != null) {
+ MesenMsgBox.Show("UnableToDownload", MessageBoxButtons.OK, MessageBoxIcon.Error, args.Error.ToString());
+ result = DialogResult.Cancel;
+ }
+ };
+
+ Task downloadTask = null;
+ try {
+ downloadTask = client.DownloadFileTaskAsync(_link, _filename);
+ } catch(Exception ex) {
+ MesenMsgBox.Show("UnableToDownload", MessageBoxButtons.OK, MessageBoxIcon.Error, ex.ToString());
+ result = DialogResult.Cancel;
+ }
+
+ if(downloadTask == null) {
+ result = DialogResult.Cancel;
+ } else {
+ while(!downloadTask.IsCompleted && !_cancel) {
+ System.Threading.Thread.Sleep(200);
+ }
+
+ if(_cancel) {
+ client.CancelAsync();
+ } else if(result == DialogResult.None) {
+ result = DialogResult.OK;
+ }
+ }
+ }
+
+ //Wait a bit for the progress bar to update to 100% (display updates are slower than the .Value updates)
+ System.Threading.Thread.Sleep(500);
+ this.BeginInvoke((Action)(() => {
+ DialogResult = result;
+ this.Close();
+ }));
+ });
+ }
+ }
+}
diff --git a/UI/Updates/frmDownloadProgress.designer.cs b/UI/Updates/frmDownloadProgress.designer.cs
new file mode 100644
index 0000000..5f32727
--- /dev/null
+++ b/UI/Updates/frmDownloadProgress.designer.cs
@@ -0,0 +1,100 @@
+namespace Mesen.GUI.Updates
+{
+ partial class frmDownloadProgress
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if(disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ this.progressDownload = new System.Windows.Forms.ProgressBar();
+ this.lblFilename = new System.Windows.Forms.Label();
+ this.tmrStart = new System.Windows.Forms.Timer(this.components);
+ this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+ this.tableLayoutPanel1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // progressDownload
+ //
+ this.progressDownload.Dock = System.Windows.Forms.DockStyle.Top;
+ this.progressDownload.Location = new System.Drawing.Point(3, 38);
+ this.progressDownload.Name = "progressDownload";
+ this.progressDownload.Size = new System.Drawing.Size(328, 23);
+ this.progressDownload.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
+ this.progressDownload.TabIndex = 0;
+ //
+ // lblFilename
+ //
+ this.lblFilename.AutoSize = true;
+ this.lblFilename.Location = new System.Drawing.Point(3, 5);
+ this.lblFilename.Margin = new System.Windows.Forms.Padding(3, 5, 3, 0);
+ this.lblFilename.Name = "lblFilename";
+ this.lblFilename.Size = new System.Drawing.Size(100, 13);
+ this.lblFilename.TabIndex = 1;
+ this.lblFilename.Text = "Downloading file: ...";
+ //
+ // tmrStart
+ //
+ this.tmrStart.Tick += new System.EventHandler(this.tmrStart_Tick);
+ //
+ // tableLayoutPanel1
+ //
+ this.tableLayoutPanel1.ColumnCount = 1;
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel1.Controls.Add(this.lblFilename, 0, 0);
+ this.tableLayoutPanel1.Controls.Add(this.progressDownload, 0, 1);
+ this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
+ this.tableLayoutPanel1.Name = "tableLayoutPanel1";
+ this.tableLayoutPanel1.RowCount = 2;
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 35F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(334, 67);
+ this.tableLayoutPanel1.TabIndex = 2;
+ //
+ // frmDownloadProgress
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(334, 67);
+ this.Controls.Add(this.tableLayoutPanel1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
+ this.MaximumSize = new System.Drawing.Size(350, 500);
+ this.Name = "frmDownloadProgress";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
+ this.Text = "Downloading...";
+ this.tableLayoutPanel1.ResumeLayout(false);
+ this.tableLayoutPanel1.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.ProgressBar progressDownload;
+ private System.Windows.Forms.Label lblFilename;
+ private System.Windows.Forms.Timer tmrStart;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
+ }
+}
\ No newline at end of file
diff --git a/UI/Updates/frmDownloadProgress.resx b/UI/Updates/frmDownloadProgress.resx
new file mode 100644
index 0000000..f4157d8
--- /dev/null
+++ b/UI/Updates/frmDownloadProgress.resx
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+ 107, 17
+
+
\ No newline at end of file
diff --git a/UI/Updates/frmUpdatePrompt.cs b/UI/Updates/frmUpdatePrompt.cs
new file mode 100644
index 0000000..5d2c529
--- /dev/null
+++ b/UI/Updates/frmUpdatePrompt.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Diagnostics;
+using System.Drawing;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using Mesen.GUI.Config;
+using Mesen.GUI.Controls;
+using Mesen.GUI.Forms;
+
+namespace Mesen.GUI.Updates
+{
+ public partial class frmUpdatePrompt : BaseForm
+ {
+ private string _fileHash;
+ private string _donateText;
+
+ public frmUpdatePrompt(Version currentVersion, Version latestVersion, string changeLog, string fileHash, string donateText)
+ {
+ InitializeComponent();
+
+ _donateText = donateText;
+
+ this.txtChangelog.Font = new Font(BaseControl.MonospaceFontFamily, 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+
+ _fileHash = fileHash;
+
+ lblCurrentVersionString.Text = currentVersion.ToString();
+ lblLatestVersionString.Text = latestVersion.ToString();
+ txtChangelog.Text = changeLog.Replace("\n", Environment.NewLine);
+ }
+
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
+
+ if(_donateText != null) {
+ if(!string.IsNullOrEmpty(_donateText)) {
+ this.lblDonate.Text = _donateText;
+ }
+ this.lblDonate.Visible = true;
+ this.picDonate.Visible = true;
+ } else {
+ this.lblDonate.Visible = false;
+ this.picDonate.Visible = false;
+ }
+
+ btnUpdate.Focus();
+ }
+
+ private void btnUpdate_Click(object sender, EventArgs e)
+ {
+#if DISABLEAUTOUPDATE
+ MesenMsgBox.Show("AutoUpdateDisabledMessage", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ this.DialogResult = DialogResult.Cancel;
+ this.Close();
+#else
+ string destFilePath = System.Reflection.Assembly.GetEntryAssembly().Location;
+ string srcFilePath = Path.Combine(ConfigManager.DownloadFolder, "Mesen." + lblLatestVersionString.Text + ".exe");
+ string backupFilePath = Path.Combine(ConfigManager.BackupFolder, "Mesen." + lblCurrentVersionString.Text + ".exe");
+ string updateHelper = Path.Combine(ConfigManager.HomeFolder, "Resources", "MesenUpdater.exe");
+
+ if(!File.Exists(updateHelper)) {
+ MesenMsgBox.Show("UpdaterNotFound", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ DialogResult = DialogResult.Cancel;
+ } else if(!string.IsNullOrWhiteSpace(srcFilePath)) {
+ frmDownloadProgress frmDownload = new frmDownloadProgress("https://www.mesen.ca/snes/Services/GetLatestVersion.php?a=download&p=win&v=" + EmuApi.GetMesenVersion().ToString(3), srcFilePath);
+ if(frmDownload.ShowDialog() == DialogResult.OK) {
+ FileInfo fileInfo = new FileInfo(srcFilePath);
+ if(fileInfo.Length > 0 && ResourceExtractor.GetSha1Hash(File.ReadAllBytes(srcFilePath)) == _fileHash) {
+ if(Program.IsMono) {
+ Process.Start("mono", string.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\"", updateHelper, srcFilePath, destFilePath, backupFilePath));
+ } else {
+ Process.Start(updateHelper, string.Format("\"{0}\" \"{1}\" \"{2}\"", srcFilePath, destFilePath, backupFilePath));
+ }
+ } else {
+ //Download failed, mismatching hashes
+ MesenMsgBox.Show("UpdateDownloadFailed", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ DialogResult = DialogResult.Cancel;
+ }
+ }
+ }
+#endif
+ }
+
+ private void picDonate_Click(object sender, EventArgs e)
+ {
+ Process.Start("https://www.mesen.ca/Donate.php?l=" + ResourceHelper.GetLanguageCode());
+ }
+ }
+}
diff --git a/UI/Updates/frmUpdatePrompt.designer.cs b/UI/Updates/frmUpdatePrompt.designer.cs
new file mode 100644
index 0000000..40e1b53
--- /dev/null
+++ b/UI/Updates/frmUpdatePrompt.designer.cs
@@ -0,0 +1,268 @@
+namespace Mesen.GUI.Updates
+{
+ partial class frmUpdatePrompt
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if(disposing && (components != null)) {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmUpdatePrompt));
+ this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
+ this.lblLatestVersionString = new System.Windows.Forms.Label();
+ this.lblLatestVersion = new System.Windows.Forms.Label();
+ this.lblCurrentVersion = new System.Windows.Forms.Label();
+ this.txtChangelog = new System.Windows.Forms.TextBox();
+ this.lblChangeLog = new System.Windows.Forms.Label();
+ this.lblCurrentVersionString = new System.Windows.Forms.Label();
+ this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
+ this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
+ this.btnCancel = new System.Windows.Forms.Button();
+ this.btnUpdate = new System.Windows.Forms.Button();
+ this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
+ this.picDonate = new System.Windows.Forms.PictureBox();
+ this.lblDonate = new System.Windows.Forms.Label();
+ this.tableLayoutPanel1.SuspendLayout();
+ this.tableLayoutPanel2.SuspendLayout();
+ this.flowLayoutPanel1.SuspendLayout();
+ this.flowLayoutPanel2.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.picDonate)).BeginInit();
+ this.SuspendLayout();
+ //
+ // tableLayoutPanel1
+ //
+ this.tableLayoutPanel1.ColumnCount = 4;
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 100F));
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel1.Controls.Add(this.lblLatestVersionString, 1, 0);
+ this.tableLayoutPanel1.Controls.Add(this.lblLatestVersion, 0, 0);
+ this.tableLayoutPanel1.Controls.Add(this.lblCurrentVersion, 2, 0);
+ this.tableLayoutPanel1.Controls.Add(this.txtChangelog, 0, 2);
+ this.tableLayoutPanel1.Controls.Add(this.lblChangeLog, 0, 1);
+ this.tableLayoutPanel1.Controls.Add(this.lblCurrentVersionString, 3, 0);
+ this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 0, 3);
+ this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
+ this.tableLayoutPanel1.Name = "tableLayoutPanel1";
+ this.tableLayoutPanel1.Padding = new System.Windows.Forms.Padding(5, 10, 5, 0);
+ this.tableLayoutPanel1.RowCount = 4;
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
+ this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
+ this.tableLayoutPanel1.Size = new System.Drawing.Size(689, 354);
+ this.tableLayoutPanel1.TabIndex = 0;
+ //
+ // lblLatestVersionString
+ //
+ this.lblLatestVersionString.AutoSize = true;
+ this.lblLatestVersionString.Location = new System.Drawing.Point(91, 10);
+ this.lblLatestVersionString.Name = "lblLatestVersionString";
+ this.lblLatestVersionString.Size = new System.Drawing.Size(28, 13);
+ this.lblLatestVersionString.TabIndex = 7;
+ this.lblLatestVersionString.Text = "x.x.x";
+ //
+ // lblLatestVersion
+ //
+ this.lblLatestVersion.AutoSize = true;
+ this.lblLatestVersion.Location = new System.Drawing.Point(8, 10);
+ this.lblLatestVersion.Name = "lblLatestVersion";
+ this.lblLatestVersion.Size = new System.Drawing.Size(77, 13);
+ this.lblLatestVersion.TabIndex = 2;
+ this.lblLatestVersion.Text = "Latest Version:";
+ //
+ // lblCurrentVersion
+ //
+ this.lblCurrentVersion.AutoSize = true;
+ this.lblCurrentVersion.Location = new System.Drawing.Point(191, 10);
+ this.lblCurrentVersion.Name = "lblCurrentVersion";
+ this.lblCurrentVersion.Size = new System.Drawing.Size(82, 13);
+ this.lblCurrentVersion.TabIndex = 3;
+ this.lblCurrentVersion.Text = "Current Version:";
+ //
+ // txtChangelog
+ //
+ this.txtChangelog.BackColor = System.Drawing.Color.White;
+ this.tableLayoutPanel1.SetColumnSpan(this.txtChangelog, 4);
+ this.txtChangelog.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.txtChangelog.Location = new System.Drawing.Point(8, 49);
+ this.txtChangelog.Multiline = true;
+ this.txtChangelog.Name = "txtChangelog";
+ this.txtChangelog.ReadOnly = true;
+ this.txtChangelog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.txtChangelog.Size = new System.Drawing.Size(673, 271);
+ this.txtChangelog.TabIndex = 4;
+ this.txtChangelog.TabStop = false;
+ //
+ // lblChangeLog
+ //
+ this.lblChangeLog.AutoSize = true;
+ this.lblChangeLog.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.lblChangeLog.Location = new System.Drawing.Point(8, 33);
+ this.lblChangeLog.Margin = new System.Windows.Forms.Padding(3, 10, 3, 0);
+ this.lblChangeLog.Name = "lblChangeLog";
+ this.lblChangeLog.Size = new System.Drawing.Size(61, 13);
+ this.lblChangeLog.TabIndex = 5;
+ this.lblChangeLog.Text = "Changelog:";
+ //
+ // lblCurrentVersionString
+ //
+ this.lblCurrentVersionString.AutoSize = true;
+ this.lblCurrentVersionString.Location = new System.Drawing.Point(279, 10);
+ this.lblCurrentVersionString.Name = "lblCurrentVersionString";
+ this.lblCurrentVersionString.Size = new System.Drawing.Size(28, 13);
+ this.lblCurrentVersionString.TabIndex = 6;
+ this.lblCurrentVersionString.Text = "x.x.x";
+ //
+ // tableLayoutPanel2
+ //
+ this.tableLayoutPanel2.ColumnCount = 2;
+ this.tableLayoutPanel1.SetColumnSpan(this.tableLayoutPanel2, 4);
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+ this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel1, 1, 0);
+ this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel2, 0, 0);
+ this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.tableLayoutPanel2.Location = new System.Drawing.Point(5, 323);
+ this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
+ this.tableLayoutPanel2.Name = "tableLayoutPanel2";
+ this.tableLayoutPanel2.RowCount = 1;
+ this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
+ this.tableLayoutPanel2.Size = new System.Drawing.Size(679, 31);
+ this.tableLayoutPanel2.TabIndex = 9;
+ //
+ // flowLayoutPanel1
+ //
+ this.flowLayoutPanel1.Controls.Add(this.btnCancel);
+ this.flowLayoutPanel1.Controls.Add(this.btnUpdate);
+ this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
+ this.flowLayoutPanel1.Location = new System.Drawing.Point(520, 0);
+ this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
+ this.flowLayoutPanel1.Name = "flowLayoutPanel1";
+ this.flowLayoutPanel1.Size = new System.Drawing.Size(159, 28);
+ this.flowLayoutPanel1.TabIndex = 8;
+ //
+ // btnCancel
+ //
+ this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.btnCancel.Location = new System.Drawing.Point(85, 3);
+ this.btnCancel.Name = "btnCancel";
+ this.btnCancel.Size = new System.Drawing.Size(71, 23);
+ this.btnCancel.TabIndex = 1;
+ this.btnCancel.Text = "Cancel";
+ this.btnCancel.UseVisualStyleBackColor = true;
+ //
+ // btnUpdate
+ //
+ this.btnUpdate.DialogResult = System.Windows.Forms.DialogResult.OK;
+ this.btnUpdate.Location = new System.Drawing.Point(4, 3);
+ this.btnUpdate.Name = "btnUpdate";
+ this.btnUpdate.Size = new System.Drawing.Size(75, 23);
+ this.btnUpdate.TabIndex = 0;
+ this.btnUpdate.Text = "Update";
+ this.btnUpdate.UseVisualStyleBackColor = true;
+ this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click);
+ //
+ // flowLayoutPanel2
+ //
+ this.flowLayoutPanel2.Controls.Add(this.picDonate);
+ this.flowLayoutPanel2.Controls.Add(this.lblDonate);
+ this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.flowLayoutPanel2.Location = new System.Drawing.Point(0, 0);
+ this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
+ this.flowLayoutPanel2.Name = "flowLayoutPanel2";
+ this.flowLayoutPanel2.Size = new System.Drawing.Size(520, 31);
+ this.flowLayoutPanel2.TabIndex = 9;
+ this.flowLayoutPanel2.WrapContents = false;
+ //
+ // picDonate
+ //
+ this.picDonate.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.picDonate.Cursor = System.Windows.Forms.Cursors.Hand;
+ this.picDonate.Image = ((System.Drawing.Image)(resources.GetObject("picDonate.Image")));
+ this.picDonate.Location = new System.Drawing.Point(3, 3);
+ this.picDonate.Name = "picDonate";
+ this.picDonate.Size = new System.Drawing.Size(78, 22);
+ this.picDonate.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
+ this.picDonate.TabIndex = 0;
+ this.picDonate.TabStop = false;
+ this.picDonate.Click += new System.EventHandler(this.picDonate_Click);
+ //
+ // lblDonate
+ //
+ this.lblDonate.Anchor = System.Windows.Forms.AnchorStyles.Left;
+ this.lblDonate.AutoSize = true;
+ this.lblDonate.Location = new System.Drawing.Point(84, 7);
+ this.lblDonate.Margin = new System.Windows.Forms.Padding(0);
+ this.lblDonate.Name = "lblDonate";
+ this.lblDonate.Size = new System.Drawing.Size(331, 13);
+ this.lblDonate.TabIndex = 1;
+ this.lblDonate.Text = "If you want to support Mesen, please consider donating. Thank you!";
+ //
+ // frmUpdatePrompt
+ //
+ this.AcceptButton = this.btnUpdate;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.btnCancel;
+ this.ClientSize = new System.Drawing.Size(689, 354);
+ this.Controls.Add(this.tableLayoutPanel1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "frmUpdatePrompt";
+ this.ShowInTaskbar = false;
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Mesen - Update Available";
+ this.tableLayoutPanel1.ResumeLayout(false);
+ this.tableLayoutPanel1.PerformLayout();
+ this.tableLayoutPanel2.ResumeLayout(false);
+ this.flowLayoutPanel1.ResumeLayout(false);
+ this.flowLayoutPanel2.ResumeLayout(false);
+ this.flowLayoutPanel2.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.picDonate)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
+ private System.Windows.Forms.Label lblLatestVersionString;
+ private System.Windows.Forms.Label lblLatestVersion;
+ private System.Windows.Forms.Label lblCurrentVersion;
+ private System.Windows.Forms.TextBox txtChangelog;
+ private System.Windows.Forms.Label lblChangeLog;
+ private System.Windows.Forms.Label lblCurrentVersionString;
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
+ private System.Windows.Forms.Button btnCancel;
+ private System.Windows.Forms.Button btnUpdate;
+ private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
+ private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
+ private System.Windows.Forms.PictureBox picDonate;
+ private System.Windows.Forms.Label lblDonate;
+ }
+}
\ No newline at end of file
diff --git a/UI/Updates/frmUpdatePrompt.resx b/UI/Updates/frmUpdatePrompt.resx
new file mode 100644
index 0000000..3550ecc
--- /dev/null
+++ b/UI/Updates/frmUpdatePrompt.resx
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 17, 17
+
+
+
+
+ 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
+
+
+
\ No newline at end of file
diff --git a/UpdateHelper/Icon.ico b/UpdateHelper/Icon.ico
new file mode 100644
index 0000000..72c5c76
Binary files /dev/null and b/UpdateHelper/Icon.ico differ
diff --git a/UpdateHelper/Program.cs b/UpdateHelper/Program.cs
new file mode 100644
index 0000000..dbc3274
--- /dev/null
+++ b/UpdateHelper/Program.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.IO;
+using System.Diagnostics;
+using System.Windows.Forms;
+
+namespace MesenUpdater
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ if(args.Length > 2) {
+ string srcFile = args[0];
+ string destFile = args[1];
+ string backupDestFile = args[2];
+ bool isAdmin = args.Length > 3 && args[3] == "admin";
+
+ int retryCount = 0;
+ while(retryCount < 10) {
+ try {
+ using(FileStream file = File.Open(destFile, FileMode.Open, FileAccess.ReadWrite, FileShare.Delete | FileShare.ReadWrite)) { }
+ break;
+ } catch {
+ retryCount++;
+ System.Threading.Thread.Sleep(1000);
+ }
+ }
+
+ try {
+ File.Copy(destFile, backupDestFile, true);
+ File.Copy(srcFile, destFile, true);
+ } catch {
+ try {
+ if(!isAdmin) {
+ ProcessStartInfo proc = new ProcessStartInfo();
+ proc.WindowStyle = ProcessWindowStyle.Normal;
+ proc.FileName = System.Reflection.Assembly.GetEntryAssembly().Location;
+ proc.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\" admin", srcFile, destFile, backupDestFile);
+ proc.UseShellExecute = true;
+ proc.Verb = "runas";
+ Process.Start(proc);
+ return;
+ } else {
+ MessageBox.Show("Update failed. Please try downloading and installing the new version manually.", "Mesen-S", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
+ } catch {
+ MessageBox.Show("Update failed. Please try downloading and installing the new version manually.", "Mesen-S", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
+ }
+ Process.Start(destFile);
+ } else {
+ MessageBox.Show("Please run Mesen-S directly to update.", "Mesen-S");
+ }
+ }
+ }
+}
diff --git a/UpdateHelper/Properties/AssemblyInfo.cs b/UpdateHelper/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..99d5da6
--- /dev/null
+++ b/UpdateHelper/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("MesenUpdater")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("MesenUpdater")]
+[assembly: AssemblyCopyright("Copyright © 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("36abbf1c-66e1-4577-828a-619a2ef0dae9")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/UpdateHelper/UpdateHelper.csproj b/UpdateHelper/UpdateHelper.csproj
new file mode 100644
index 0000000..77bf9e2
--- /dev/null
+++ b/UpdateHelper/UpdateHelper.csproj
@@ -0,0 +1,198 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {36ABBF1C-66E1-4577-828A-619A2EF0DAE9}
+ WinExe
+ Properties
+ MesenUpdater
+ MesenUpdater
+ v4.5
+ 512
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ ..\bin\Any CPU\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ ..\bin\Any CPU\Release\
+ TRACE
+ prompt
+ 4
+ false
+
+
+ true
+ ..\bin\x64\Debug\
+ DEBUG;TRACE
+ full
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\bin\x64\Release\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ true
+ ..\bin\x86\Debug\
+ DEBUG;TRACE
+ full
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\bin\x86\Release\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\bin\Any CPU\PGO Profile\
+ TRACE
+ true
+ pdbonly
+ AnyCPU
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\bin\x64\PGO Profile\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\bin\x86\PGO Profile\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\bin\Any CPU\PGO Profile\
+ TRACE
+ true
+ pdbonly
+ AnyCPU
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\bin\x64\PGO Profile\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ ..\bin\x86\PGO Profile\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+
+
+ Icon.ico
+
+
+ bin\Libretro\
+ TRACE
+ true
+ pdbonly
+ AnyCPU
+ prompt
+ MinimumRecommendedRules.ruleset
+
+
+ bin\x64\Libretro\
+ TRACE
+ true
+ pdbonly
+ x64
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+ bin\x86\Libretro\
+ TRACE
+ true
+ pdbonly
+ x86
+ prompt
+ MinimumRecommendedRules.ruleset
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file