commit 1ef84fd1329f0a8dd5fd47da25365ac88b109b2b Author: Alessio Date: Tue Apr 21 10:40:12 2026 +0200 Add disassembly of GradientTool diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7c5f2df --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vs +bin/ +obj/ +Backup/ diff --git a/AboutBox.cs b/AboutBox.cs new file mode 100644 index 0000000..232f0a7 --- /dev/null +++ b/AboutBox.cs @@ -0,0 +1,197 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.AboutBox +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Reflection; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal class AboutBox : Form +{ + private IContainer components; + private TableLayoutPanel tableLayoutPanel; + private Label labelProductName; + private Label labelVersion; + private Label labelCopyright; + private Button okButton; + private LinkLabel linkLabel1; + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.tableLayoutPanel = new TableLayoutPanel(); + this.labelProductName = new Label(); + this.labelVersion = new Label(); + this.labelCopyright = new Label(); + this.okButton = new Button(); + this.linkLabel1 = new LinkLabel(); + this.tableLayoutPanel.SuspendLayout(); + this.SuspendLayout(); + this.tableLayoutPanel.ColumnCount = 1; + this.tableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel.Controls.Add((Control) this.labelProductName, 0, 0); + this.tableLayoutPanel.Controls.Add((Control) this.labelVersion, 0, 1); + this.tableLayoutPanel.Controls.Add((Control) this.labelCopyright, 0, 2); + this.tableLayoutPanel.Controls.Add((Control) this.okButton, 0, 4); + this.tableLayoutPanel.Controls.Add((Control) this.linkLabel1, 0, 3); + this.tableLayoutPanel.Dock = DockStyle.Fill; + this.tableLayoutPanel.Location = new Point(9, 9); + this.tableLayoutPanel.Name = "tableLayoutPanel"; + this.tableLayoutPanel.RowCount = 5; + this.tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 25.00001f)); + this.tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 24.99999f)); + this.tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 25f)); + this.tableLayoutPanel.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel.Size = new Size(246, 124); + this.tableLayoutPanel.TabIndex = 0; + this.labelProductName.AutoEllipsis = true; + this.labelProductName.Dock = DockStyle.Fill; + this.labelProductName.Location = new Point(6, 0); + this.labelProductName.Margin = new Padding(6, 0, 3, 0); + this.labelProductName.MaximumSize = new Size(0, 17); + this.labelProductName.Name = "labelProductName"; + this.labelProductName.Size = new Size(237, 17); + this.labelProductName.TabIndex = 19; + this.labelProductName.Text = "Product Name"; + this.labelProductName.TextAlign = ContentAlignment.MiddleLeft; + this.labelVersion.AutoEllipsis = true; + this.labelVersion.Dock = DockStyle.Fill; + this.labelVersion.Location = new Point(6, 23); + this.labelVersion.Margin = new Padding(6, 0, 3, 0); + this.labelVersion.MaximumSize = new Size(0, 17); + this.labelVersion.Name = "labelVersion"; + this.labelVersion.Size = new Size(237, 17); + this.labelVersion.TabIndex = 0; + this.labelVersion.Text = "Version"; + this.labelVersion.TextAlign = ContentAlignment.MiddleLeft; + this.labelCopyright.AutoEllipsis = true; + this.labelCopyright.Dock = DockStyle.Fill; + this.labelCopyright.Location = new Point(6, 46); + this.labelCopyright.Margin = new Padding(6, 0, 3, 0); + this.labelCopyright.MaximumSize = new Size(0, 17); + this.labelCopyright.Name = "labelCopyright"; + this.labelCopyright.Size = new Size(237, 17); + this.labelCopyright.TabIndex = 21; + this.labelCopyright.Text = "Copyright"; + this.labelCopyright.TextAlign = ContentAlignment.MiddleLeft; + this.okButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.okButton.DialogResult = DialogResult.Cancel; + this.okButton.Location = new Point(168, 98); + this.okButton.Name = "okButton"; + this.okButton.Size = new Size(75, 23); + this.okButton.TabIndex = 24; + this.okButton.Text = "&OK"; + this.linkLabel1.AutoEllipsis = true; + this.linkLabel1.Dock = DockStyle.Fill; + this.linkLabel1.LinkArea = new LinkArea(14, 17); + this.linkLabel1.LinkBehavior = LinkBehavior.HoverUnderline; + this.linkLabel1.Location = new Point(6, 69); + this.linkLabel1.Margin = new Padding(6, 0, 3, 0); + this.linkLabel1.MaximumSize = new Size(0, 17); + this.linkLabel1.Name = "linkLabel1"; + this.linkLabel1.Size = new Size(237, 17); + this.linkLabel1.TabIndex = 25; + this.linkLabel1.TabStop = true; + this.linkLabel1.Text = "Some icons by Yusuke Kamiyamane."; + this.linkLabel1.TextAlign = ContentAlignment.MiddleLeft; + this.linkLabel1.UseCompatibleTextRendering = true; + this.linkLabel1.LinkClicked += new LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked); + this.AcceptButton = (IButtonControl) this.okButton; + this.AutoScaleDimensions = new SizeF(6f, 13f); + this.AutoScaleMode = AutoScaleMode.Font; + this.ClientSize = new Size(264, 142); + this.Controls.Add((Control) this.tableLayoutPanel); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof (AboutBox); + this.Padding = new Padding(9); + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = FormStartPosition.CenterParent; + this.Text = "About GradientTool"; + this.tableLayoutPanel.ResumeLayout(false); + this.ResumeLayout(false); + } + + public AboutBox() + { + this.InitializeComponent(); + this.labelProductName.Text = this.AssemblyProduct; + this.labelVersion.Text = $"Version {this.AssemblyVersion}"; + this.labelCopyright.Text = this.AssemblyCopyright; + } + + public string AssemblyTitle + { + get + { + object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof (AssemblyTitleAttribute), false); + if (customAttributes.Length > 0) + { + AssemblyTitleAttribute assemblyTitleAttribute = (AssemblyTitleAttribute) customAttributes[0]; + if (assemblyTitleAttribute.Title != "") + return assemblyTitleAttribute.Title; + } + return Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase); + } + } + + public string AssemblyVersion => Assembly.GetExecutingAssembly().GetName().Version.ToString(); + + public string AssemblyDescription + { + get + { + object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof (AssemblyDescriptionAttribute), false); + return customAttributes.Length == 0 ? "" : ((AssemblyDescriptionAttribute) customAttributes[0]).Description; + } + } + + public string AssemblyProduct + { + get + { + object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof (AssemblyProductAttribute), false); + return customAttributes.Length == 0 ? "" : ((AssemblyProductAttribute) customAttributes[0]).Product; + } + } + + public string AssemblyCopyright + { + get + { + object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof (AssemblyCopyrightAttribute), false); + return customAttributes.Length == 0 ? "" : ((AssemblyCopyrightAttribute) customAttributes[0]).Copyright; + } + } + + public string AssemblyCompany + { + get + { + object[] customAttributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof (AssemblyCompanyAttribute), false); + return customAttributes.Length == 0 ? "" : ((AssemblyCompanyAttribute) customAttributes[0]).Company; + } + } + + private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + Process.Start("http://p.yusukekamiyamane.com/"); + } +} diff --git a/AboutBox.resx b/AboutBox.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/AboutBox.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file diff --git a/AssemblyInfo.cs b/AssemblyInfo.cs new file mode 100644 index 0000000..1541cef --- /dev/null +++ b/AssemblyInfo.cs @@ -0,0 +1,9 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security.Permissions; + +[assembly: Guid("1c485639-0f77-473c-890e-22b93fca5923")] +[assembly: ComVisible(false)] +[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] diff --git a/BitmapCalc.cs b/BitmapCalc.cs new file mode 100644 index 0000000..c57abb1 --- /dev/null +++ b/BitmapCalc.cs @@ -0,0 +1,281 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.BitmapCalc +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA; +using System; +using System.Drawing; +using System.Drawing.Imaging; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal static class BitmapCalc +{ + public static unsafe void Fill48BppBitmap( + this Bitmap bmp, + double[] r, + double[] g, + double[] b, + bool addPadding = true) + { + BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format48bppRgb); + try + { + ushort* scan0 = (ushort*) (void*) bitmapdata.Scan0; + ushort* numPtr1 = scan0 + (addPadding ? (IntPtr) bitmapdata.Stride : IntPtr.Zero).ToInt64(); + ushort num1 = 0; + ushort num2 = 0; + ushort num3 = 0; + for (int index1 = 0; index1 < r.Length; ++index1) + { + ushort* numPtr2 = numPtr1; + for (int index2 = 0; index2 < bitmapdata.Width; ++index2) + { + ushort* numPtr3 = numPtr2; + ushort* numPtr4 = (ushort*) ((IntPtr) numPtr3 + new IntPtr(2)); + int word1; + ushort num4 = (ushort) (word1 = (int) Utils.RoundToWord(b[index1].Clamp() * (double) ushort.MaxValue)); + *numPtr3 = (ushort) word1; + num3 = num4; + ushort* numPtr5 = numPtr4; + ushort* numPtr6 = (ushort*) ((IntPtr) numPtr5 + new IntPtr(2)); + int word2; + ushort num5 = (ushort) (word2 = (int) Utils.RoundToWord(g[index1].Clamp() * (double) ushort.MaxValue)); + *numPtr5 = (ushort) word2; + num2 = num5; + ushort* numPtr7 = numPtr6; + numPtr2 = (ushort*) ((IntPtr) numPtr7 + new IntPtr(2)); + int word3; + ushort num6 = (ushort) (word3 = (int) Utils.RoundToWord(r[index1].Clamp() * (double) ushort.MaxValue)); + *numPtr7 = (ushort) word3; + num1 = num6; + } + numPtr1 += bitmapdata.Stride; + } + if (!addPadding) + return; + *numPtr1 = (ushort) (*(short*) (numPtr1 + 3) = (short) num3); + numPtr1[1] = (ushort) (*(short*) (numPtr1 + 4) = (short) num2); + numPtr1[2] = (ushort) (*(short*) (numPtr1 + 5) = (short) num1); + ushort* numPtr8 = scan0 + bitmapdata.Stride; + *scan0 = (ushort) (*(short*) (scan0 + 3) = (short) *numPtr8); + scan0[1] = (ushort) (*(short*) (scan0 + 4) = (short) numPtr8[1]); + scan0[2] = (ushort) (*(short*) (scan0 + 5) = (short) numPtr8[2]); + } + finally + { + bmp.UnlockBits(bitmapdata); + } + } + + public static unsafe void Fill24BppBitmap( + this Bitmap bmp, + double[] r, + double[] g, + double[] b, + bool addPadding = true) + { + BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb); + try + { + byte* scan0 = (byte*) (void*) bitmapdata.Scan0; + byte* numPtr1 = scan0 + (addPadding ? bitmapdata.Stride : 0); + byte num1 = 0; + byte num2 = 0; + byte num3 = 0; + for (int index1 = 0; index1 < r.Length; ++index1) + { + byte* numPtr2 = numPtr1; + for (int index2 = 0; index2 < bitmapdata.Width; ++index2) + { + byte* numPtr3 = numPtr2; + byte* numPtr4 = numPtr3 + 1; + int num4; + byte num5 = (byte) (num4 = (int) Utils.RoundToByte(b[index1].Clamp() * (double) byte.MaxValue)); + *numPtr3 = (byte) num4; + num3 = num5; + byte* numPtr5 = numPtr4; + byte* numPtr6 = numPtr5 + 1; + int num6; + byte num7 = (byte) (num6 = (int) Utils.RoundToByte(g[index1].Clamp() * (double) byte.MaxValue)); + *numPtr5 = (byte) num6; + num2 = num7; + byte* numPtr7 = numPtr6; + numPtr2 = numPtr7 + 1; + int num8; + byte num9 = (byte) (num8 = (int) Utils.RoundToByte(r[index1].Clamp() * (double) byte.MaxValue)); + *numPtr7 = (byte) num8; + num1 = num9; + } + numPtr1 += bitmapdata.Stride; + } + if (!addPadding) + return; + *numPtr1 = (byte) (*(sbyte*) (numPtr1 + 3) = (sbyte) num3); + numPtr1[1] = (byte) (*(sbyte*) (numPtr1 + 4) = (sbyte) num2); + numPtr1[2] = (byte) (*(sbyte*) (numPtr1 + 5) = (sbyte) num1); + byte* numPtr8 = scan0 + bitmapdata.Stride; + *scan0 = (byte) (*(sbyte*) (scan0 + 3) = (sbyte) *numPtr8); + scan0[1] = (byte) (*(sbyte*) (scan0 + 4) = (sbyte) numPtr8[1]); + scan0[2] = (byte) (*(sbyte*) (scan0 + 5) = (sbyte) numPtr8[2]); + } + finally + { + bmp.UnlockBits(bitmapdata); + } + } + + private static double Combine(double v, double x, double y, Combiner combiner) + { + switch (combiner) + { + case Combiner.Normal: + return v; + case Combiner.AverageWithX: + return (v + x) / 2.0; + case Combiner.AverageWithY: + return (v + y) / 2.0; + default: + return 0.0; + } + } + + public static void Fill15BppBitmap( + this Bitmap bmp, + double[] r, + double[] g, + double[] b, + GradientChannels channels) + { + switch (channels) + { + case GradientChannels.RedGreenBlue: + bmp.Fill15BppBitmap(r, g, b, Combiner.Normal, Combiner.Normal, Combiner.Normal); + break; + case GradientChannels.RedGreen: + bmp.Fill15BppBitmap(r, g, b, Combiner.Normal, Combiner.Normal, Combiner.Drop); + break; + case GradientChannels.GreenBlue: + bmp.Fill15BppBitmap(r, g, b, Combiner.Drop, Combiner.Normal, Combiner.Normal); + break; + case GradientChannels.RedBlue: + bmp.Fill15BppBitmap(r, g, b, Combiner.Normal, Combiner.Drop, Combiner.Normal); + break; + case GradientChannels.CyanRed: + bmp.Fill15BppBitmap(r, g, b, Combiner.Normal, Combiner.AverageWithY, Combiner.AverageWithY); + break; + case GradientChannels.YellowBlue: + bmp.Fill15BppBitmap(r, g, b, Combiner.AverageWithX, Combiner.AverageWithX, Combiner.Normal); + break; + case GradientChannels.MagentaGreen: + bmp.Fill15BppBitmap(r, g, b, Combiner.AverageWithY, Combiner.Normal, Combiner.AverageWithX); + break; + case GradientChannels.Red: + bmp.Fill15BppBitmap(r, g, b, Combiner.Normal, Combiner.Drop, Combiner.Drop); + break; + case GradientChannels.Green: + bmp.Fill15BppBitmap(r, g, b, Combiner.Drop, Combiner.Normal, Combiner.Drop); + break; + case GradientChannels.Blue: + bmp.Fill15BppBitmap(r, g, b, Combiner.Drop, Combiner.Drop, Combiner.Normal); + break; + case GradientChannels.Cyan: + bmp.Fill15BppBitmap(r, g, b, Combiner.Drop, Combiner.AverageWithY, Combiner.AverageWithY); + break; + case GradientChannels.Yellow: + bmp.Fill15BppBitmap(r, g, b, Combiner.AverageWithX, Combiner.AverageWithX, Combiner.Drop); + break; + case GradientChannels.Magenta: + bmp.Fill15BppBitmap(r, g, b, Combiner.AverageWithY, Combiner.Drop, Combiner.AverageWithX); + break; + case GradientChannels.Grey: + bmp.Fill15BppBitmapGreyscale(r, g, b); + break; + case GradientChannels.Brightness: + break; + default: + throw new ArgumentException("Invalid gradient channels."); + } + } + + public static unsafe void Fill15BppBitmap( + this Bitmap bmp, + double[] r, + double[] g, + double[] b, + Combiner redCombiner, + Combiner greenCombiner, + Combiner blueCombiner) + { + BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format16bppRgb555); + try + { + byte* scan0 = (byte*) (void*) bitmapdata.Scan0; + for (int index1 = 0; index1 < r.Length; ++index1) + { + double num1 = BitmapCalc.Combine(r[index1], g[index1], b[index1], redCombiner).Clamp(); + double num2 = BitmapCalc.Combine(g[index1], r[index1], b[index1], greenCombiner).Clamp(); + double num3 = BitmapCalc.Combine(b[index1], r[index1], g[index1], blueCombiner).Clamp(); + ushort* numPtr = (ushort*) scan0; + for (int index2 = 0; index2 < bitmapdata.Width; ++index2) + *numPtr++ = (ushort) ((int) Utils.RoundToByte(num3 * 31.0) | (int) Utils.RoundToByte(num2 * 31.0) << 5 | (int) Utils.RoundToByte(num1 * 31.0) << 10); + scan0 += bitmapdata.Stride; + } + } + finally + { + bmp.UnlockBits(bitmapdata); + } + } + + public static unsafe void Fill15BppBitmapGreyscale( + this Bitmap bmp, + double[] r, + double[] g, + double[] b) + { + BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format16bppRgb555); + try + { + byte* scan0 = (byte*) (void*) bitmapdata.Scan0; + for (int index1 = 0; index1 < r.Length; ++index1) + { + double max = 3.0; + byte num = Utils.RoundToByte((r[index1] + g[index1] + b[index1]).Clamp(max) * (31.0 / 3.0)); + ushort* numPtr = (ushort*) scan0; + for (int index2 = 0; index2 < bitmapdata.Width; ++index2) + *numPtr++ = (ushort) ((int) num | (int) num << 5 | (int) num << 10); + scan0 += bitmapdata.Stride; + } + } + finally + { + bmp.UnlockBits(bitmapdata); + } + } + + public static unsafe void Fill4BppBitmap(this Bitmap bmp, double[] r, double[] g, double[] b) + { + BitmapData bitmapdata = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format4bppIndexed); + try + { + byte* scan0 = (byte*) (void*) bitmapdata.Scan0; + for (int index1 = 0; index1 < r.Length; ++index1) + { + double max = 3.0; + byte num = Utils.RoundToByte((r[index1] + g[index1] + b[index1]).Clamp(max) * 5.0); + byte* numPtr = scan0; + for (int index2 = 0; index2 < bitmapdata.Stride; ++index2) + *numPtr++ = (byte) ((uint) num | (uint) num << 4); + scan0 += bitmapdata.Stride; + } + } + finally + { + bmp.UnlockBits(bitmapdata); + } + } +} diff --git a/CodeGen.cs b/CodeGen.cs new file mode 100644 index 0000000..8e87ab4 --- /dev/null +++ b/CodeGen.cs @@ -0,0 +1,312 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.CodeGen +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.IO; +using System.Text; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal sealed class CodeGen +{ + private StringBuilder m_rtf; + private StringBuilder m_plain; + + public CodeGen() + { + this.m_rtf = new StringBuilder(); + this.m_plain = new StringBuilder(); + } + + public void AppendPlainText(string text) + { + this.m_rtf.Append(text); + this.m_plain.Append(text); + } + + public void AppendPlainText(char ch) + { + this.m_rtf.Append(ch); + this.m_plain.Append(ch); + } + + public void AppendComment(string text) + { + this.m_rtf.Append($"\\cf1{text}\\cf0"); + this.m_plain.Append(text); + } + + public void AppendKeyword(string text) + { + this.m_rtf.Append($"\\cf2{text}\\cf0"); + this.m_plain.Append(text); + } + + public void AppendNumeric(string text) + { + this.m_rtf.Append($"\\cf3{text}\\cf0"); + this.m_plain.Append(text); + } + + public void AppendNumeric(char ch) + { + this.m_rtf.Append($"\\cf3{(object) ch}\\cf0"); + this.m_plain.Append(ch); + } + + public void AppendLabel(string text) + { + this.m_rtf.Append($"\\cf4{text}\\cf0"); + this.m_plain.Append(text); + } + + public void AppendLine() + { + this.m_rtf.Append("\\line"); + this.m_plain.AppendLine(); + } + + public void AppendHardTab() + { + this.m_rtf.Append("\\tab"); + this.m_plain.Append('\t'); + } + + public void AppendSpace() + { + this.m_rtf.Append("\\ "); + this.m_plain.Append(' '); + } + + public void WriteComment(string comment = null, bool tab = false, bool space = false) + { + if (tab) + this.AppendHardTab(); + else if (space) + this.AppendSpace(); + string text = "; "; + if (comment != null) + text += comment; + this.AppendComment(text); + this.AppendLine(); + } + + public void WriteBanner() + { + this.AppendComment(";======================================="); + this.AppendLine(); + } + + public void Write16BitMode(int w = 0, bool tab = true) + { + if (tab) + this.AppendHardTab(); + this.AppendKeyword("REP".PadRight(w)); + this.AppendSpace(); + this.AppendNumeric("#$20"); + this.AppendSpace(); + this.AppendComment("; 16-bit A"); + this.AppendLine(); + } + + public void Write8BitMode(int w = 0, bool tab = true) + { + if (tab) + this.AppendHardTab(); + this.AppendKeyword("SEP".PadRight(w)); + this.AppendSpace(); + this.AppendNumeric("#$20"); + this.AppendSpace(); + this.AppendComment("; 8-bit A"); + this.AppendLine(); + } + + public void WriteTSB(ushort addr, int w = 0, bool tab = true) + { + if (tab) + this.AppendHardTab(); + this.AppendKeyword("TSB".PadRight(w)); + this.AppendSpace(); + this.WriteHexAddress(addr); + this.AppendLine(); + } + + public void WriteLDAIfNonzero(ushort value, int w = 0, bool tab = true) + { + if (value == (ushort) 0) + return; + int w1 = w; + bool tab1 = tab; + this.WriteLDA_c(value, w1, tab1); + } + + public void WriteSTAIfNonzero(ushort addr, ushort value, int w = 0, string comment = null, bool tab = true) + { + if (value != (ushort) 0) + { + int w1 = w; + string comment1 = comment; + bool tab1 = tab; + this.WriteSTA(addr, w1, comment1, tab1); + } + else + { + int w2 = w; + string comment2 = comment; + bool tab2 = tab; + this.WriteSTZ(addr, w2, comment2, tab2); + } + } + + public void WriteKeywordLine(string keyword, bool tab = true) + { + if (tab) + this.AppendHardTab(); + this.AppendKeyword(keyword); + this.AppendLine(); + } + + public void WriteHexAddress(byte address) + { + this.AppendNumeric('$'.ToString() + address.ToString("X2")); + } + + public void WriteHexAddress(ushort address) + { + this.AppendNumeric('$'.ToString() + address.ToString("X4")); + } + + public void WriteHexConstant(byte constant) => this.AppendNumeric("#$" + constant.ToString("X2")); + + public void WriteHexConstant(ushort constant) + { + this.AppendNumeric("#$" + constant.ToString("X4")); + } + + public void WriteBinaryConstant(byte constant) + { + this.AppendNumeric("#%" + Convert.ToString(constant, 2).PadLeft(8, '0')); + } + + private void WriteLDAInternal(string addr, int w, bool tab) + { + if (tab) + this.AppendHardTab(); + this.AppendKeyword("LDA".PadRight(w)); + this.AppendSpace(); + this.AppendNumeric(addr); + this.AppendLine(); + } + + public void WriteLDA(byte addr, int w = 0, bool tab = true) + { + this.WriteLDAInternal('$'.ToString() + addr.ToString("X2"), w, tab); + } + + public void WriteLDA(ushort addr, int w = 0, bool tab = true) + { + this.WriteLDAInternal('$'.ToString() + addr.ToString("X4"), w, tab); + } + + public void WriteLDA(int addr, int w = 0, bool tab = true) + { + this.WriteLDAInternal('$'.ToString() + (addr & 16777215 /*0xFFFFFF*/).ToString("X6"), w, tab); + } + + public void WriteLDA_c(byte addr, int w = 0, bool tab = true) + { + this.WriteLDAInternal("#$" + addr.ToString("X2"), w, tab); + } + + public void WriteLDA_c(ushort addr, int w = 0, bool tab = true) + { + this.WriteLDAInternal("#$" + addr.ToString("X2"), w, tab); + } + + public void WriteLDA_b_c_bin(byte val, int w = 0, bool tab = true) + { + if (tab) + this.AppendHardTab(); + this.AppendKeyword("LDA.b".PadRight(w)); + this.AppendSpace(); + this.WriteBinaryConstant(val); + this.AppendLine(); + } + + public void WriteLDA_Label(string label, int w = 0, bool tab = true) + { + if (tab) + this.AppendHardTab(); + this.AppendKeyword("LDA".PadRight(w)); + this.AppendSpace(); + this.AppendNumeric('#'); + this.AppendLabel(label); + this.AppendLine(); + } + + private void WriteSTAInternal( + string addr, + int w, + bool storeAccumulator, + string comment, + bool tab) + { + if (tab) + this.AppendHardTab(); + this.AppendKeyword((storeAccumulator ? "STA" : "STZ").PadRight(w)); + this.AppendSpace(); + this.AppendNumeric(addr); + if (comment != null) + { + this.AppendSpace(); + this.AppendComment("; " + comment); + } + this.AppendLine(); + } + + public void WriteSTA(byte addr, int w = 0, string comment = null, bool tab = true) + { + this.WriteSTAInternal('$'.ToString() + addr.ToString("X2"), w, true, comment, tab); + } + + public void WriteSTA(ushort addr, int w = 0, string comment = null, bool tab = true) + { + this.WriteSTAInternal('$'.ToString() + addr.ToString("X4"), w, true, comment, tab); + } + + public void WriteSTA(int addr, int w = 0, string comment = null, bool tab = true) + { + this.WriteSTAInternal('$'.ToString() + (addr & 16777215 /*0xFFFFFF*/).ToString("X6"), w, true, comment, tab); + } + + public void WriteSTZ(byte addr, int w = 0, string comment = null, bool tab = true) + { + this.WriteSTAInternal('$'.ToString() + addr.ToString("X2"), w, false, comment, tab); + } + + public void WriteSTZ(ushort addr, int w = 0, string comment = null, bool tab = true) + { + this.WriteSTAInternal('$'.ToString() + addr.ToString("X4"), w, false, comment, tab); + } + + public void SetTextBoxText(RichTextBox textBox) + { + textBox.Rtf = $"{{\\rtf1\\ansi\\deff0{{\\colortbl;\\red0\\green127\\blue0;\\red0\\green0\\blue255;\\red64\\green64\\blue64;\\red127\\green0\\blue127;}}{this.m_rtf.ToString()}\\line}}"; + } + + public string GetText() => this.m_plain.ToString(); + + public void WriteToFile(string filename, Encoding encoding = null) + { + if (encoding == null) + encoding = (Encoding) new UTF8Encoding(false); + File.WriteAllText(filename, this.m_plain.ToString(), encoding); + } + + ~CodeGen() => this.m_rtf = this.m_plain = (StringBuilder) null; +} diff --git a/ColourSelector.cs b/ColourSelector.cs new file mode 100644 index 0000000..f588dbc --- /dev/null +++ b/ColourSelector.cs @@ -0,0 +1,825 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.ColourSelector +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.Properties; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal class ColourSelector : Form +{ + private const int c_hueChange = 1; + private const int c_satChange = 2; + private const int c_lgtChange = 4; + private int m_scalar = 100; + private int m_deg = 360; + private Bitmap m_hues = Resources.hues; + private LinearGradientBrush m_lightnessPanelBrush = new LinearGradientBrush(Point.Empty, new Point(0, 1), Color.White, Color.Black); + private Vector m_hsl; + private static readonly Point[] s_rightMarker = new Point[5] + { + new Point(3, 0), + new Point(4, 1), + new Point(9, 2), + new Point(9, -2), + new Point(4, -1) + }; + private static readonly Point[] s_rightLightnessMarker = new Point[5] + { + new Point(3, 0), + new Point(4, 1), + new Point(9, 3), + new Point(9, -3), + new Point(4, -1) + }; + private bool m_isChanging; + private IContainer components; + private Button okButton; + private Button cancelButton; + private NumericUpDown hueUpDown; + private NumericUpDown redUpDown; + private NumericUpDown satUpDown; + private NumericUpDown greenUpDown; + private NumericUpDown lightUpDown; + private NumericUpDown blueUpDown; + private NumericUpDown posUpDown; + private ToolTip toolTip; + private Button eyedropperButton; + private DoubleBufferedPanel colourPanel; + private DoubleBufferedPanel hueSaturationPanel; + private DoubleBufferedPanel lightnessPanel; + private TableLayoutPanel tableLayoutPanel5; + private RadioButton radioButton1; + private RadioButton radioButton2; + private RadioButton radioButton3; + + public ColourSelector() + { + this.InitializeComponent(); + this.m_lightnessPanelBrush.InterpolationColors = new ColorBlend(3) + { + Colors = new Color[3] + { + Color.White, + Color.Gray, + Color.Black + }, + Positions = new float[3]{ 0.0f, 0.5f, 1f } + }; + } + + private int GetMarkerPosFromHue(double hue) + { + return (int) (1.5 + hue * (double) (this.hueSaturationPanel.ClientSize.Width - 3)); + } + + private int GetMarkerPosFromSat(double saturation) + { + return (int) (1.5 + (1.0 - saturation) * (double) (this.hueSaturationPanel.ClientSize.Height - 3)); + } + + private int HueMarkerPos => this.GetMarkerPosFromHue(this.m_hsl.X); + + private int SatMarkerPos => this.GetMarkerPosFromSat(this.m_hsl.Y); + + private void RefreshHueSatMarkerPos(int oldHuePos, int oldSatPos) + { + using (Region region = new Region(new Rectangle(this.HueMarkerPos - 9, this.SatMarkerPos - 9, 19, 19))) + { + region.Union(new Rectangle(oldHuePos - 9, oldSatPos - 9, 19, 19)); + this.hueSaturationPanel.Invalidate(region); + } + } + + private void PaintHueSaturationPanel(object sender, PaintEventArgs e) + { + e.Graphics.DrawImage((Image) this.m_hues, Rectangle.Inflate(this.hueSaturationPanel.ClientRectangle, -1, -1), new Rectangle(0, 0, 6, 1), GraphicsUnit.Pixel); + e.Graphics.TranslateTransform((float) this.HueMarkerPos, (float) this.SatMarkerPos); + e.Graphics.FillPolygon(Brushes.Black, ColourSelector.s_rightMarker); + e.Graphics.DrawPolygon(Pens.White, ColourSelector.s_rightMarker); + e.Graphics.RotateTransform(90f); + e.Graphics.FillPolygon(Brushes.Black, ColourSelector.s_rightMarker); + e.Graphics.DrawPolygon(Pens.White, ColourSelector.s_rightMarker); + e.Graphics.RotateTransform(90f); + e.Graphics.FillPolygon(Brushes.Black, ColourSelector.s_rightMarker); + e.Graphics.DrawPolygon(Pens.White, ColourSelector.s_rightMarker); + e.Graphics.RotateTransform(90f); + e.Graphics.FillPolygon(Brushes.Black, ColourSelector.s_rightMarker); + e.Graphics.DrawPolygon(Pens.White, ColourSelector.s_rightMarker); + e.Graphics.ResetTransform(); + } + + private void MoveHueSatMarker(MouseEventArgs e) + { + bool isChanging = this.m_isChanging; + this.m_isChanging = true; + double d = (double) (e.X - 1) / ((double) this.hueSaturationPanel.ClientSize.Width - 3.0); + double num = 1.0 - ((double) (e.Y - 1) / ((double) this.hueSaturationPanel.ClientSize.Height - 3.0)).Clamp(); + if (d < 0.0 || d > 1.0) + d -= Math.Floor(d); + int hueMarkerPos = this.HueMarkerPos; + int satMarkerPos = this.SatMarkerPos; + this.m_hsl.X = d; + this.m_hsl.Y = num; + this.RefreshHueSatMarkerPos(hueMarkerPos, satMarkerPos); + this.lightnessPanel.Invalidate(); + Vector hdr = this.m_hsl.ToHDR(GradientColourspace.HSL); + this.hueUpDown.Value = (Decimal) (this.m_hsl.X * (double) this.m_deg); + this.satUpDown.Value = ((Decimal) (this.m_hsl.Y * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.redUpDown.Value = ((Decimal) (hdr.X.Clamp() * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.greenUpDown.Value = ((Decimal) (hdr.Y.Clamp() * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.blueUpDown.Value = ((Decimal) (hdr.Z.Clamp() * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.UpdateColourPreview(); + this.m_isChanging = isChanging; + } + + private void HueSatPanelMouseDown(object sender, MouseEventArgs e) + { + if ((e.Button & MouseButtons.Left) == MouseButtons.None) + return; + this.hueSaturationPanel.Capture = true; + this.hueSaturationPanel.Cursor = Eyedropper.s_blank; + Cursor.Clip = this.hueSaturationPanel.RectangleToScreen(Rectangle.Inflate(this.hueSaturationPanel.ClientRectangle, -1, -1)); + this.MoveHueSatMarker(e); + } + + private void HueSatPanelMouseMove(object sender, MouseEventArgs e) + { + if ((e.Button & MouseButtons.Left) == MouseButtons.None) + return; + this.MoveHueSatMarker(e); + } + + private void HueSatPanelMouseUp(object sender, MouseEventArgs e) + { + if ((e.Button & MouseButtons.Left) == MouseButtons.None) + return; + Cursor.Clip = Rectangle.Empty; + this.hueSaturationPanel.Cursor = Cursors.Cross; + this.hueSaturationPanel.Capture = false; + } + + private int GetMarkerPosFromLightness(double lightness) + { + return (int) (1.5 + (1.0 - lightness) * (double) (this.lightnessPanel.ClientSize.Height - 3)); + } + + private int LightnessMarkerPos => this.GetMarkerPosFromLightness(this.m_hsl.Z); + + private void RefreshLightnessMarker(int oldPos) + { + using (Region region = new Region(new Rectangle(1, this.LightnessMarkerPos - 3, this.lightnessPanel.ClientSize.Width - 2, 7))) + { + region.Union(new Rectangle(1, oldPos - 3, this.lightnessPanel.ClientSize.Width - 2, 7)); + this.lightnessPanel.Invalidate(region); + } + } + + private void PaintLightnessPanel(object sender, PaintEventArgs e) + { + Vector hsl = this.m_hsl with { Z = 0.5 }; + ColorBlend interpolationColors = this.m_lightnessPanelBrush.InterpolationColors; + interpolationColors.Colors[1] = hsl.ToRGB(GradientColourspace.HSL); + this.m_lightnessPanelBrush.InterpolationColors = interpolationColors; + e.Graphics.TranslateTransform(1f, 1f); + e.Graphics.ScaleTransform((float) (this.lightnessPanel.ClientSize.Width - 2), (float) (this.lightnessPanel.ClientSize.Height - 2)); + e.Graphics.FillRectangle((Brush) this.m_lightnessPanelBrush, new Rectangle(0, 0, 1, 1)); + e.Graphics.ResetTransform(); + e.Graphics.TranslateTransform((float) (this.lightnessPanel.ClientSize.Width / 2), (float) this.LightnessMarkerPos); + e.Graphics.FillPolygon(Brushes.Black, ColourSelector.s_rightLightnessMarker); + e.Graphics.DrawPolygon(Pens.White, ColourSelector.s_rightLightnessMarker); + e.Graphics.ScaleTransform(-1f, 1f); + e.Graphics.FillPolygon(Brushes.Black, ColourSelector.s_rightLightnessMarker); + e.Graphics.DrawPolygon(Pens.White, ColourSelector.s_rightLightnessMarker); + e.Graphics.ResetTransform(); + } + + private void MoveLightnessMarker(MouseEventArgs e) + { + bool isChanging = this.m_isChanging; + this.m_isChanging = true; + double num = 1.0 - ((double) (e.Y - 1) / ((double) this.hueSaturationPanel.ClientSize.Height - 3.0)).Clamp(); + int lightnessMarkerPos = this.LightnessMarkerPos; + this.m_hsl.Z = num; + this.RefreshLightnessMarker(lightnessMarkerPos); + Vector hdr = this.m_hsl.ToHDR(GradientColourspace.HSL); + this.lightUpDown.Value = ((Decimal) (this.m_hsl.Z * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.redUpDown.Value = ((Decimal) (hdr.X * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.greenUpDown.Value = ((Decimal) (hdr.Y * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.blueUpDown.Value = ((Decimal) (hdr.Z * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.UpdateColourPreview(); + this.m_isChanging = isChanging; + } + + private void LghtPanelMouseDown(object sender, MouseEventArgs e) + { + if ((e.Button & MouseButtons.Left) == MouseButtons.None) + return; + this.lightnessPanel.Capture = true; + this.lightnessPanel.Cursor = Eyedropper.s_blank; + Cursor.Clip = this.lightnessPanel.RectangleToScreen(new Rectangle(this.lightnessPanel.ClientSize.Width / 2, 1, 1, this.lightnessPanel.ClientSize.Height - 2)); + this.MoveLightnessMarker(e); + } + + private void LghtPanelMouseMove(object sender, MouseEventArgs e) + { + if ((e.Button & MouseButtons.Left) == MouseButtons.None) + return; + this.MoveLightnessMarker(e); + } + + private void LghtPanelMouseUp(object sender, MouseEventArgs e) + { + if ((e.Button & MouseButtons.Left) == MouseButtons.None) + return; + Cursor.Clip = Rectangle.Empty; + this.lightnessPanel.Cursor = Cursors.Cross; + this.lightnessPanel.Capture = false; + } + + private void UpdateColourPreview() + { + this.colourPanel.BackColor = this.m_hsl.ToRGB(GradientColourspace.HSL); + } + + private void DoRGBChange() + { + if (this.m_isChanging) + return; + this.m_isChanging = true; + int hueMarkerPos = this.HueMarkerPos; + int satMarkerPos = this.SatMarkerPos; + Vector vector = new Vector() + { + X = (double) (this.redUpDown.Value / (Decimal) this.m_scalar), + Y = (double) (this.greenUpDown.Value / (Decimal) this.m_scalar), + Z = (double) (this.blueUpDown.Value / (Decimal) this.m_scalar) + }; + double x = this.m_hsl.X; + double y = this.m_hsl.Y; + this.m_hsl = vector.HDRToColourspace(GradientColourspace.HSL); + if (double.IsNaN(this.m_hsl.X)) + this.m_hsl.X = x; + if (double.IsNaN(this.m_hsl.Y)) + this.m_hsl.Y = y; + this.hueUpDown.Value = (Decimal) (this.m_hsl.X * (double) this.m_deg); + this.satUpDown.Value = ((Decimal) (this.m_hsl.Y * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.lightUpDown.Value = ((Decimal) (this.m_hsl.Z * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.RefreshHueSatMarkerPos(hueMarkerPos, satMarkerPos); + this.lightnessPanel.Invalidate(); + this.UpdateColourPreview(); + this.m_isChanging = false; + } + + private void DoHSLChange(object sender, bool all = false) + { + if (this.m_isChanging) + return; + this.m_isChanging = true; + int num1 = 0; + Decimal d = this.hueUpDown.Value / (Decimal) this.m_deg; + int hueMarkerPos = this.HueMarkerPos; + int num2 = this.SatMarkerPos; + if (all || object.ReferenceEquals(sender, (object) this.hueUpDown)) + { + num1 = 1; + if (d < 0M || d > 1M) + { + d -= Math.Floor(d); + this.hueUpDown.Value = d * (Decimal) this.m_deg; + } + } + if (all || object.ReferenceEquals(sender, (object) this.satUpDown)) + { + num1 = 2; + this.satUpDown.Value = this.satUpDown.Value.Clamp((Decimal) this.m_scalar); + } + if (all || object.ReferenceEquals(sender, (object) this.lightUpDown)) + { + num1 = 4; + this.lightUpDown.Value = this.lightUpDown.Value.Clamp((Decimal) this.m_scalar); + num2 = this.LightnessMarkerPos; + } + this.m_hsl = new Vector() + { + X = (double) d, + Y = ((double) (this.satUpDown.Value / (Decimal) this.m_scalar)).Clamp(), + Z = ((double) (this.lightUpDown.Value / (Decimal) this.m_scalar)).Clamp() + }; + switch (num1) + { + case 1: + case 2: + this.RefreshHueSatMarkerPos(hueMarkerPos, num2); + this.lightnessPanel.Invalidate(); + break; + case 4: + this.RefreshLightnessMarker(num2); + break; + } + Vector hdr = this.m_hsl.ToHDR(GradientColourspace.HSL); + this.redUpDown.Value = ((Decimal) (hdr.X * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.greenUpDown.Value = ((Decimal) (hdr.Y * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.blueUpDown.Value = ((Decimal) (hdr.Z * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.UpdateColourPreview(); + this.m_isChanging = false; + } + + private void posUpDown_ValueChanged(object sender, EventArgs e) + { + } + + private void RGBUpDownsChanged(object sender, EventArgs e) => this.DoRGBChange(); + + private void HSLUpDownsChanged(object sender, EventArgs e) => this.DoHSLChange(sender); + + public void SetColour(Vector hdr) + { + this.m_isChanging = true; + this.redUpDown.Value = ((Decimal) (hdr.X * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.greenUpDown.Value = ((Decimal) (hdr.Y * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.blueUpDown.Value = ((Decimal) (hdr.Z * (double) this.m_scalar)).Clamp((Decimal) this.m_scalar); + this.m_isChanging = false; + this.DoRGBChange(); + } + + public Vector GetColour() => this.m_hsl.ToHDR(GradientColourspace.HSL); + + public void SetOffset(double offset) + { + this.posUpDown.Value = ((Decimal) (offset * 100.0)).Clamp(); + } + + public double GetOffset() => (double) (this.posUpDown.Value / 100M); + + protected override void OnClosing(CancelEventArgs e) + { + base.OnClosing(e); + if (e.Cancel) + return; + Cursor.Clip = Rectangle.Empty; + } + + private void EyedropperClicked(object sender, EventArgs e) + { + Eyedropper.PickAColour((Form) this, (Action) (c => this.SetColour(c.ToColourspace(GradientColourspace.RGB)))); + } + + private void SetScalar(int scalar, int deg) + { + if (this.m_scalar == scalar && this.m_deg == deg) + return; + bool isChanging = this.m_isChanging; + this.m_isChanging = true; + this.m_scalar = scalar; + this.m_deg = deg; + this.satUpDown.Maximum = (Decimal) scalar; + this.lightUpDown.Maximum = (Decimal) scalar; + this.redUpDown.Maximum = (Decimal) scalar; + this.greenUpDown.Maximum = (Decimal) scalar; + this.blueUpDown.Maximum = (Decimal) scalar; + Vector hdr = this.m_hsl.ToHDR(GradientColourspace.HSL); + this.hueUpDown.Value = (Decimal) (this.m_hsl.X * (double) deg); + this.satUpDown.Value = ((Decimal) (this.m_hsl.Y * (double) scalar)).Clamp((Decimal) scalar); + this.lightUpDown.Value = ((Decimal) (this.m_hsl.Z * (double) scalar)).Clamp((Decimal) scalar); + this.redUpDown.Value = ((Decimal) (hdr.X * (double) scalar)).Clamp((Decimal) scalar); + this.greenUpDown.Value = ((Decimal) (hdr.Y * (double) scalar)).Clamp((Decimal) scalar); + this.blueUpDown.Value = ((Decimal) (hdr.Z * (double) scalar)).Clamp((Decimal) scalar); + this.m_isChanging = isChanging; + } + + private void radioButton1_CheckedChanged(object sender, EventArgs e) => this.SetScalar(100, 360); + + private void radioButton2_CheckedChanged(object sender, EventArgs e) + { + this.SetScalar((int) byte.MaxValue, (int) byte.MaxValue); + } + + private void radioButton3_CheckedChanged(object sender, EventArgs e) + { + this.SetScalar(240 /*0xF0*/, 240 /*0xF0*/); + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer) new System.ComponentModel.Container(); + this.redUpDown = new NumericUpDown(); + this.greenUpDown = new NumericUpDown(); + this.blueUpDown = new NumericUpDown(); + this.lightUpDown = new NumericUpDown(); + this.satUpDown = new NumericUpDown(); + this.hueUpDown = new NumericUpDown(); + this.okButton = new Button(); + this.cancelButton = new Button(); + this.posUpDown = new NumericUpDown(); + this.colourPanel = new DoubleBufferedPanel(); + this.eyedropperButton = new Button(); + this.hueSaturationPanel = new DoubleBufferedPanel(); + this.lightnessPanel = new DoubleBufferedPanel(); + this.tableLayoutPanel5 = new TableLayoutPanel(); + this.radioButton1 = new RadioButton(); + this.radioButton2 = new RadioButton(); + this.radioButton3 = new RadioButton(); + this.toolTip = new ToolTip(this.components); + TableLayoutPanel tableLayoutPanel1 = new TableLayoutPanel(); + Label label1 = new Label(); + Label label2 = new Label(); + Label label3 = new Label(); + Label label4 = new Label(); + Label label5 = new Label(); + Label label6 = new Label(); + TableLayoutPanel tableLayoutPanel2 = new TableLayoutPanel(); + TableLayoutPanel tableLayoutPanel3 = new TableLayoutPanel(); + Label label7 = new Label(); + Label label8 = new Label(); + TableLayoutPanel tableLayoutPanel4 = new TableLayoutPanel(); + tableLayoutPanel1.SuspendLayout(); + this.redUpDown.BeginInit(); + this.greenUpDown.BeginInit(); + this.blueUpDown.BeginInit(); + this.lightUpDown.BeginInit(); + this.satUpDown.BeginInit(); + this.hueUpDown.BeginInit(); + tableLayoutPanel2.SuspendLayout(); + this.posUpDown.BeginInit(); + tableLayoutPanel3.SuspendLayout(); + tableLayoutPanel4.SuspendLayout(); + this.tableLayoutPanel5.SuspendLayout(); + this.SuspendLayout(); + tableLayoutPanel1.ColumnCount = 5; + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel1.Controls.Add((Control) label1, 1, 5); + tableLayoutPanel1.Controls.Add((Control) label2, 1, 4); + tableLayoutPanel1.Controls.Add((Control) label3, 1, 3); + tableLayoutPanel1.Controls.Add((Control) label4, 3, 3); + tableLayoutPanel1.Controls.Add((Control) this.redUpDown, 4, 3); + tableLayoutPanel1.Controls.Add((Control) label5, 3, 4); + tableLayoutPanel1.Controls.Add((Control) this.greenUpDown, 4, 4); + tableLayoutPanel1.Controls.Add((Control) label6, 3, 5); + tableLayoutPanel1.Controls.Add((Control) this.blueUpDown, 4, 5); + tableLayoutPanel1.Controls.Add((Control) this.lightUpDown, 2, 5); + tableLayoutPanel1.Controls.Add((Control) this.satUpDown, 2, 4); + tableLayoutPanel1.Controls.Add((Control) this.hueUpDown, 2, 3); + tableLayoutPanel1.Controls.Add((Control) tableLayoutPanel2, 0, 7); + tableLayoutPanel1.Controls.Add((Control) this.posUpDown, 3, 6); + tableLayoutPanel1.Controls.Add((Control) tableLayoutPanel3, 0, 3); + tableLayoutPanel1.Controls.Add((Control) label8, 2, 6); + tableLayoutPanel1.Controls.Add((Control) this.eyedropperButton, 1, 6); + tableLayoutPanel1.Controls.Add((Control) tableLayoutPanel4, 0, 0); + tableLayoutPanel1.Controls.Add((Control) this.tableLayoutPanel5, 0, 1); + tableLayoutPanel1.Dock = DockStyle.Fill; + tableLayoutPanel1.Location = new Point(9, 9); + tableLayoutPanel1.Name = "tableLayoutPanel1"; + tableLayoutPanel1.RowCount = 8; + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.Size = new Size(282, 365); + tableLayoutPanel1.TabIndex = 0; + label1.Anchor = AnchorStyles.Right; + label1.AutoSize = true; + label1.Location = new Point(78, 279); + label1.Margin = new Padding(3, 2, 3, 2); + label1.Name = "label5"; + label1.Size = new Size(13, 13); + label1.TabIndex = 6; + label1.Text = "&L"; + this.toolTip.SetToolTip((Control) label1, "Lightness"); + label2.Anchor = AnchorStyles.Right; + label2.AutoSize = true; + label2.Location = new Point(77, 253); + label2.Margin = new Padding(3, 2, 3, 2); + label2.Name = "label3"; + label2.Size = new Size(14, 13); + label2.TabIndex = 4; + label2.Text = "&S"; + this.toolTip.SetToolTip((Control) label2, "Saturation"); + label3.Anchor = AnchorStyles.Right; + label3.AutoSize = true; + label3.Location = new Point(76, 227); + label3.Margin = new Padding(3, 2, 3, 2); + label3.Name = "label1"; + label3.Size = new Size(15, 13); + label3.TabIndex = 2; + label3.Text = "&H"; + this.toolTip.SetToolTip((Control) label3, "Hue"); + label4.Anchor = AnchorStyles.Left; + label4.AutoSize = true; + label4.Location = new Point(183, 227); + label4.Margin = new Padding(8, 2, 3, 2); + label4.Name = "label2"; + label4.Size = new Size(15, 13); + label4.TabIndex = 8; + label4.Text = "&R"; + this.toolTip.SetToolTip((Control) label4, "Red"); + this.redUpDown.DecimalPlaces = 3; + this.redUpDown.Location = new Point(204, 224 /*0xE0*/); + this.redUpDown.Name = "redUpDown"; + this.redUpDown.Size = new Size(75, 20); + this.redUpDown.TabIndex = 9; + this.toolTip.SetToolTip((Control) this.redUpDown, "Red"); + this.redUpDown.ValueChanged += new EventHandler(this.RGBUpDownsChanged); + label5.Anchor = AnchorStyles.Left; + label5.AutoSize = true; + label5.Location = new Point(183, 253); + label5.Margin = new Padding(8, 2, 3, 2); + label5.Name = "label4"; + label5.Size = new Size(15, 13); + label5.TabIndex = 10; + label5.Text = "&G"; + this.toolTip.SetToolTip((Control) label5, "Green"); + this.greenUpDown.DecimalPlaces = 3; + this.greenUpDown.Location = new Point(204, 250); + this.greenUpDown.Name = "greenUpDown"; + this.greenUpDown.Size = new Size(75, 20); + this.greenUpDown.TabIndex = 11; + this.toolTip.SetToolTip((Control) this.greenUpDown, "Green"); + this.greenUpDown.ValueChanged += new EventHandler(this.RGBUpDownsChanged); + label6.Anchor = AnchorStyles.Left; + label6.AutoSize = true; + label6.Location = new Point(183, 279); + label6.Margin = new Padding(8, 2, 3, 2); + label6.Name = "label6"; + label6.Size = new Size(14, 13); + label6.TabIndex = 12; + label6.Text = "&B"; + this.toolTip.SetToolTip((Control) label6, "Blue"); + this.blueUpDown.DecimalPlaces = 3; + this.blueUpDown.Location = new Point(204, 276); + this.blueUpDown.Name = "blueUpDown"; + this.blueUpDown.Size = new Size(75, 20); + this.blueUpDown.TabIndex = 13; + this.toolTip.SetToolTip((Control) this.blueUpDown, "Blue"); + this.blueUpDown.ValueChanged += new EventHandler(this.RGBUpDownsChanged); + this.lightUpDown.DecimalPlaces = 3; + this.lightUpDown.Location = new Point(97, 276); + this.lightUpDown.Name = "lightUpDown"; + this.lightUpDown.Size = new Size(75, 20); + this.lightUpDown.TabIndex = 7; + this.toolTip.SetToolTip((Control) this.lightUpDown, "Lightness"); + this.lightUpDown.ValueChanged += new EventHandler(this.HSLUpDownsChanged); + this.satUpDown.DecimalPlaces = 3; + this.satUpDown.Location = new Point(97, 250); + this.satUpDown.Name = "satUpDown"; + this.satUpDown.Size = new Size(75, 20); + this.satUpDown.TabIndex = 5; + this.toolTip.SetToolTip((Control) this.satUpDown, "Saturation"); + this.satUpDown.ValueChanged += new EventHandler(this.HSLUpDownsChanged); + this.hueUpDown.DecimalPlaces = 3; + this.hueUpDown.Location = new Point(97, 224 /*0xE0*/); + this.hueUpDown.Maximum = new Decimal(new int[4] + { + -1, + -1, + -1, + 0 + }); + this.hueUpDown.Minimum = new Decimal(new int[4] + { + -1, + -1, + -1, + int.MinValue + }); + this.hueUpDown.Name = "hueUpDown"; + this.hueUpDown.Size = new Size(75, 20); + this.hueUpDown.TabIndex = 3; + this.toolTip.SetToolTip((Control) this.hueUpDown, "Hue"); + this.hueUpDown.ValueChanged += new EventHandler(this.HSLUpDownsChanged); + tableLayoutPanel2.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right; + tableLayoutPanel2.AutoSize = true; + tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink; + tableLayoutPanel2.ColumnCount = 2; + tableLayoutPanel1.SetColumnSpan((Control) tableLayoutPanel2, 5); + tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f)); + tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50f)); + tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20f)); + tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20f)); + tableLayoutPanel2.Controls.Add((Control) this.okButton, 0, 0); + tableLayoutPanel2.Controls.Add((Control) this.cancelButton, 1, 0); + tableLayoutPanel2.Location = new Point(120, 336); + tableLayoutPanel2.Margin = new Padding(0, 6, 0, 0); + tableLayoutPanel2.Name = "tableLayoutPanel2"; + tableLayoutPanel2.RowCount = 1; + tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 50f)); + tableLayoutPanel2.Size = new Size(162, 29); + tableLayoutPanel2.TabIndex = 17; + this.okButton.DialogResult = DialogResult.OK; + this.okButton.Location = new Point(3, 3); + this.okButton.Name = "okButton"; + this.okButton.Size = new Size(75, 23); + this.okButton.TabIndex = 0; + this.okButton.Text = "&OK"; + this.okButton.UseVisualStyleBackColor = true; + this.cancelButton.DialogResult = DialogResult.Cancel; + this.cancelButton.Location = new Point(84, 3); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new Size(75, 23); + this.cancelButton.TabIndex = 1; + this.cancelButton.Text = "&Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + this.posUpDown.Anchor = AnchorStyles.Left | AnchorStyles.Right; + tableLayoutPanel1.SetColumnSpan((Control) this.posUpDown, 2); + this.posUpDown.DecimalPlaces = 6; + this.posUpDown.Location = new Point(183, 307); + this.posUpDown.Margin = new Padding(8, 8, 3, 3); + this.posUpDown.Name = "posUpDown"; + this.posUpDown.Size = new Size(96 /*0x60*/, 20); + this.posUpDown.TabIndex = 16 /*0x10*/; + this.toolTip.SetToolTip((Control) this.posUpDown, "Position of gradient stop"); + this.posUpDown.ValueChanged += new EventHandler(this.posUpDown_ValueChanged); + tableLayoutPanel3.Anchor = AnchorStyles.Right; + tableLayoutPanel3.ColumnCount = 1; + tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + tableLayoutPanel3.Controls.Add((Control) label7, 0, 1); + tableLayoutPanel3.Controls.Add((Control) this.colourPanel, 0, 0); + tableLayoutPanel3.Location = new Point(0, 221); + tableLayoutPanel3.Margin = new Padding(0); + tableLayoutPanel3.Name = "tableLayoutPanel3"; + tableLayoutPanel3.RowCount = 2; + tableLayoutPanel1.SetRowSpan((Control) tableLayoutPanel3, 3); + tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + tableLayoutPanel3.RowStyles.Add(new RowStyle()); + tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Absolute, 20f)); + tableLayoutPanel3.Size = new Size(66, 78); + tableLayoutPanel3.TabIndex = 1; + label7.Anchor = AnchorStyles.None; + label7.AutoSize = true; + label7.Location = new Point(14, 63 /*0x3F*/); + label7.Margin = new Padding(3, 2, 3, 2); + label7.Name = "label8"; + label7.Size = new Size(37, 13); + label7.TabIndex = 1; + label7.Text = "Colour"; + this.toolTip.SetToolTip((Control) label7, "Gradient stop colour"); + this.colourPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.colourPanel.BackColor = Color.Black; + this.colourPanel.Location = new Point(8, 8); + this.colourPanel.Margin = new Padding(8); + this.colourPanel.Name = "colourPanel"; + this.colourPanel.Size = new Size(50, 45); + this.colourPanel.TabIndex = 0; + this.toolTip.SetToolTip((Control) this.colourPanel, "Gradient stop colour"); + label8.Anchor = AnchorStyles.Right; + label8.AutoSize = true; + label8.Location = new Point(125, 310); + label8.Margin = new Padding(3, 6, 3, 2); + label8.Name = "label7"; + label8.Size = new Size(47, 13); + label8.TabIndex = 15; + label8.Text = "&Position:"; + this.toolTip.SetToolTip((Control) label8, "Position of gradient stop"); + this.eyedropperButton.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + this.eyedropperButton.Image = (Image) Resources.pipette; + this.eyedropperButton.Location = new Point(69, 305); + this.eyedropperButton.Name = "eyedropperButton"; + this.eyedropperButton.Size = new Size(22, 22); + this.eyedropperButton.TabIndex = 14; + this.toolTip.SetToolTip((Control) this.eyedropperButton, "Pick Colour from Screen"); + this.eyedropperButton.UseVisualStyleBackColor = true; + this.eyedropperButton.Click += new EventHandler(this.EyedropperClicked); + tableLayoutPanel4.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + tableLayoutPanel4.ColumnCount = 2; + tableLayoutPanel1.SetColumnSpan((Control) tableLayoutPanel4, 5); + tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + tableLayoutPanel4.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 32f)); + tableLayoutPanel4.Controls.Add((Control) this.hueSaturationPanel, 0, 0); + tableLayoutPanel4.Controls.Add((Control) this.lightnessPanel, 1, 0); + tableLayoutPanel4.Location = new Point(0, 0); + tableLayoutPanel4.Margin = new Padding(0); + tableLayoutPanel4.Name = "tableLayoutPanel4"; + tableLayoutPanel4.RowCount = 1; + tableLayoutPanel4.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + tableLayoutPanel4.Size = new Size(282, 198); + tableLayoutPanel4.TabIndex = 0; + this.hueSaturationPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.hueSaturationPanel.BackColor = Color.Gray; + this.hueSaturationPanel.Cursor = Cursors.Cross; + this.hueSaturationPanel.Location = new Point(3, 3); + this.hueSaturationPanel.Margin = new Padding(3, 3, 6, 3); + this.hueSaturationPanel.Name = "hueSaturationPanel"; + this.hueSaturationPanel.Size = new Size(241, 192 /*0xC0*/); + this.hueSaturationPanel.TabIndex = 0; + this.hueSaturationPanel.Paint += new PaintEventHandler(this.PaintHueSaturationPanel); + this.hueSaturationPanel.MouseDown += new MouseEventHandler(this.HueSatPanelMouseDown); + this.hueSaturationPanel.MouseMove += new MouseEventHandler(this.HueSatPanelMouseMove); + this.hueSaturationPanel.MouseUp += new MouseEventHandler(this.HueSatPanelMouseUp); + this.lightnessPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + this.lightnessPanel.Cursor = Cursors.Cross; + this.lightnessPanel.Location = new Point(256 /*0x0100*/, 3); + this.lightnessPanel.Margin = new Padding(6, 3, 3, 3); + this.lightnessPanel.Name = "lightnessPanel"; + this.lightnessPanel.Size = new Size(23, 192 /*0xC0*/); + this.lightnessPanel.TabIndex = 1; + this.lightnessPanel.Paint += new PaintEventHandler(this.PaintLightnessPanel); + this.lightnessPanel.MouseDown += new MouseEventHandler(this.LghtPanelMouseDown); + this.lightnessPanel.MouseMove += new MouseEventHandler(this.LghtPanelMouseMove); + this.lightnessPanel.MouseUp += new MouseEventHandler(this.LghtPanelMouseUp); + this.tableLayoutPanel5.Anchor = AnchorStyles.Left | AnchorStyles.Right; + this.tableLayoutPanel5.AutoSize = true; + this.tableLayoutPanel5.ColumnCount = 3; + tableLayoutPanel1.SetColumnSpan((Control) this.tableLayoutPanel5, 5); + this.tableLayoutPanel5.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33333f)); + this.tableLayoutPanel5.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33334f)); + this.tableLayoutPanel5.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 33.33334f)); + this.tableLayoutPanel5.Controls.Add((Control) this.radioButton1, 0, 0); + this.tableLayoutPanel5.Controls.Add((Control) this.radioButton2, 2, 0); + this.tableLayoutPanel5.Controls.Add((Control) this.radioButton3, 1, 0); + this.tableLayoutPanel5.Location = new Point(0, 198); + this.tableLayoutPanel5.Margin = new Padding(0); + this.tableLayoutPanel5.Name = "tableLayoutPanel5"; + this.tableLayoutPanel5.RowCount = 1; + this.tableLayoutPanel5.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel5.Size = new Size(282, 23); + this.tableLayoutPanel5.TabIndex = 18; + this.radioButton1.Anchor = AnchorStyles.None; + this.radioButton1.AutoSize = true; + this.radioButton1.Checked = true; + this.radioButton1.Location = new Point(25, 3); + this.radioButton1.Name = "radioButton1"; + this.radioButton1.Size = new Size(43, 17); + this.radioButton1.TabIndex = 0; + this.radioButton1.TabStop = true; + this.radioButton1.Text = "°, %"; + this.toolTip.SetToolTip((Control) this.radioButton1, "H will be degrees; RGB, S, and L values will be a percentage."); + this.radioButton1.UseVisualStyleBackColor = true; + this.radioButton1.CheckedChanged += new EventHandler(this.radioButton1_CheckedChanged); + this.radioButton2.Anchor = AnchorStyles.None; + this.radioButton2.AutoSize = true; + this.radioButton2.Location = new Point(204, 3); + this.radioButton2.Name = "radioButton2"; + this.radioButton2.Size = new Size(61, 17); + this.radioButton2.TabIndex = 1; + this.radioButton2.TabStop = true; + this.radioButton2.Text = "0 .. 255"; + this.toolTip.SetToolTip((Control) this.radioButton2, "HSL and RGB values will be in the range of 0 to 255."); + this.radioButton2.UseVisualStyleBackColor = true; + this.radioButton2.CheckedChanged += new EventHandler(this.radioButton2_CheckedChanged); + this.radioButton3.Anchor = AnchorStyles.None; + this.radioButton3.AutoSize = true; + this.radioButton3.Location = new Point(109, 3); + this.radioButton3.Name = "radioButton3"; + this.radioButton3.Size = new Size(61, 17); + this.radioButton3.TabIndex = 2; + this.radioButton3.TabStop = true; + this.radioButton3.Text = "0 .. 240"; + this.toolTip.SetToolTip((Control) this.radioButton3, "HSL and RGB values will be in the range of 0 to 240."); + this.radioButton3.UseVisualStyleBackColor = true; + this.radioButton3.CheckedChanged += new EventHandler(this.radioButton3_CheckedChanged); + this.AcceptButton = (IButtonControl) this.okButton; + this.AutoScaleDimensions = new SizeF(6f, 13f); + this.AutoScaleMode = AutoScaleMode.Font; + this.CancelButton = (IButtonControl) this.cancelButton; + this.ClientSize = new Size(300, 383); + this.Controls.Add((Control) tableLayoutPanel1); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof (ColourSelector); + this.Padding = new Padding(9); + this.ShowIcon = false; + this.ShowInTaskbar = false; + this.StartPosition = FormStartPosition.CenterScreen; + this.Text = "Edit Gradient Stop"; + tableLayoutPanel1.ResumeLayout(false); + tableLayoutPanel1.PerformLayout(); + this.redUpDown.EndInit(); + this.greenUpDown.EndInit(); + this.blueUpDown.EndInit(); + this.lightUpDown.EndInit(); + this.satUpDown.EndInit(); + this.hueUpDown.EndInit(); + tableLayoutPanel2.ResumeLayout(false); + this.posUpDown.EndInit(); + tableLayoutPanel3.ResumeLayout(false); + tableLayoutPanel3.PerformLayout(); + tableLayoutPanel4.ResumeLayout(false); + this.tableLayoutPanel5.ResumeLayout(false); + this.tableLayoutPanel5.PerformLayout(); + this.ResumeLayout(false); + } +} diff --git a/ColourSelector.resx b/ColourSelector.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/ColourSelector.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file diff --git a/Combiner.cs b/Combiner.cs new file mode 100644 index 0000000..261dacc --- /dev/null +++ b/Combiner.cs @@ -0,0 +1,16 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.Combiner +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +#nullable disable +namespace SFXProductions.GradientTool; + +internal enum Combiner +{ + Normal, + AverageWithX, + AverageWithY, + Drop, +} diff --git a/Config2.cs b/Config2.cs new file mode 100644 index 0000000..a2228bd --- /dev/null +++ b/Config2.cs @@ -0,0 +1,253 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.Config2 +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA; +using SFXProductions.GradientTool.HDMA.Configuration; +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal class Config2 : Form +{ + private Settings2 m_settings; + private IContainer components; + private Button okButton; + private Button cancelButton; + private TabControl optionsTabControl; + private CheckBox generateInitCheckBox; + private TextBox gradientNameTextBox; + private NumericUpDown nWritesNumericUpDown; + private CheckBox hexCheckBox; + + private Config2(Settings2 settings) + { + this.InitializeComponent(); + this.m_settings = settings; + this.generateInitCheckBox.Checked = settings.GenerateInitializationCode; + this.gradientNameTextBox.Text = settings.Name; + ColourChannelsRef channelsReference = (ColourChannelsRef) null; + this.optionsTabControl.TabPages.Add(this.m_settings.Channel1.CreatePropertiesPage(this.m_settings.Channel2 as Mode0Channel, ref channelsReference)); + if (this.m_settings.Channel2 != null) + this.optionsTabControl.TabPages.Add(this.m_settings.Channel2.CreatePropertiesPage((Mode0Channel) null, ref channelsReference)); + if (this.m_settings.Channel3 == null) + return; + this.optionsTabControl.TabPages.Add(this.m_settings.Channel3.CreatePropertiesPage((Mode0Channel) null, ref channelsReference)); + } + + private void ApplySettings() + { + this.m_settings.Channel1.ApplySettings(this.optionsTabControl.TabPages[0]); + if (this.m_settings.Channel2 != null) + this.m_settings.Channel2.ApplySettings(this.optionsTabControl.TabPages[1]); + if (this.m_settings.Channel3 == null) + return; + this.m_settings.Channel2.ApplySettings(this.optionsTabControl.TabPages[2]); + } + + public static bool ConfigureSettings(IWin32Window owner, ref Settings2 settings, ref int nWrites) + { + using (Config2 config2 = new Config2(settings)) + { + config2.nWritesNumericUpDown.Value = (Decimal) nWrites; + if (config2.ShowDialog(owner) == DialogResult.OK) + { + config2.ApplySettings(); + settings.GenerateInitializationCode = config2.generateInitCheckBox.Checked; + settings.Name = config2.gradientNameTextBox.Text; + nWrites = (int) config2.nWritesNumericUpDown.Value; + return true; + } + } + return false; + } + + private void hexCheckBox_CheckedChanged(object sender, EventArgs e) + { + this.nWritesNumericUpDown.Hexadecimal = this.hexCheckBox.Checked; + } + + private void gradientNameTextBox_TextChanged(object sender, EventArgs e) + { + this.okButton.Enabled = Settings2.ValidateName(this.gradientNameTextBox.Text = this.gradientNameTextBox.Text.Trim()); + } + + private void generateInitCheckBox_CheckedChanged(object sender, EventArgs e) + { + this.optionsTabControl.Enabled = this.generateInitCheckBox.Checked; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.nWritesNumericUpDown = new NumericUpDown(); + this.hexCheckBox = new CheckBox(); + this.okButton = new Button(); + this.cancelButton = new Button(); + this.optionsTabControl = new TabControl(); + this.generateInitCheckBox = new CheckBox(); + this.gradientNameTextBox = new TextBox(); + Label label1 = new Label(); + Label label2 = new Label(); + TableLayoutPanel tableLayoutPanel1 = new TableLayoutPanel(); + TableLayoutPanel tableLayoutPanel2 = new TableLayoutPanel(); + tableLayoutPanel1.SuspendLayout(); + tableLayoutPanel2.SuspendLayout(); + this.nWritesNumericUpDown.BeginInit(); + this.SuspendLayout(); + label1.Anchor = AnchorStyles.Right; + label1.AutoSize = true; + label1.Location = new Point(18, 6); + label1.Name = "label1"; + label1.Size = new Size(66, 13); + label1.TabIndex = 0; + label1.Text = "№ of Wri&tes:"; + label2.Anchor = AnchorStyles.Right; + label2.AutoSize = true; + label2.Location = new Point(3, 32 /*0x20*/); + label2.Name = "label2"; + label2.Size = new Size(81, 13); + label2.TabIndex = 2; + label2.Text = "Gradient N&ame:"; + tableLayoutPanel1.ColumnCount = 3; + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel1.Controls.Add((Control) tableLayoutPanel2, 1, 0); + tableLayoutPanel1.Controls.Add((Control) this.okButton, 0, 4); + tableLayoutPanel1.Controls.Add((Control) this.cancelButton, 2, 4); + tableLayoutPanel1.Controls.Add((Control) this.optionsTabControl, 0, 3); + tableLayoutPanel1.Controls.Add((Control) label1, 0, 0); + tableLayoutPanel1.Controls.Add((Control) this.generateInitCheckBox, 1, 2); + tableLayoutPanel1.Controls.Add((Control) label2, 0, 1); + tableLayoutPanel1.Controls.Add((Control) this.gradientNameTextBox, 1, 1); + tableLayoutPanel1.Dock = DockStyle.Fill; + tableLayoutPanel1.Location = new Point(9, 9); + tableLayoutPanel1.Name = "tableLayoutPanel1"; + tableLayoutPanel1.RowCount = 5; + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + tableLayoutPanel1.RowStyles.Add(new RowStyle()); + tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 20f)); + tableLayoutPanel1.Size = new Size(282, 322); + tableLayoutPanel1.TabIndex = 0; + tableLayoutPanel2.Anchor = AnchorStyles.Left; + tableLayoutPanel2.AutoSize = true; + tableLayoutPanel2.AutoSizeMode = AutoSizeMode.GrowAndShrink; + tableLayoutPanel2.ColumnCount = 2; + tableLayoutPanel1.SetColumnSpan((Control) tableLayoutPanel2, 2); + tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel2.Controls.Add((Control) this.nWritesNumericUpDown, 0, 0); + tableLayoutPanel2.Controls.Add((Control) this.hexCheckBox, 1, 0); + tableLayoutPanel2.Location = new Point(87, 0); + tableLayoutPanel2.Margin = new Padding(0); + tableLayoutPanel2.Name = "tableLayoutPanel2"; + tableLayoutPanel2.RowCount = 1; + tableLayoutPanel2.RowStyles.Add(new RowStyle()); + tableLayoutPanel2.Size = new Size(132, 26); + tableLayoutPanel2.TabIndex = 1; + this.nWritesNumericUpDown.Anchor = AnchorStyles.Left; + this.nWritesNumericUpDown.Location = new Point(3, 3); + this.nWritesNumericUpDown.Maximum = new Decimal(new int[4] + { + (int) short.MaxValue, + 0, + 0, + 0 + }); + this.nWritesNumericUpDown.Name = "nWritesNumericUpDown"; + this.nWritesNumericUpDown.Size = new Size(75, 20); + this.nWritesNumericUpDown.TabIndex = 0; + this.nWritesNumericUpDown.Value = new Decimal(new int[4] + { + 224 /*0xE0*/, + 0, + 0, + 0 + }); + this.hexCheckBox.AutoSize = true; + this.hexCheckBox.Location = new Point(84, 3); + this.hexCheckBox.Name = "hexCheckBox"; + this.hexCheckBox.Size = new Size(45, 17); + this.hexCheckBox.TabIndex = 1; + this.hexCheckBox.Text = "&Hex"; + this.hexCheckBox.UseVisualStyleBackColor = true; + this.hexCheckBox.CheckedChanged += new EventHandler(this.hexCheckBox_CheckedChanged); + this.okButton.Anchor = AnchorStyles.Right; + tableLayoutPanel1.SetColumnSpan((Control) this.okButton, 2); + this.okButton.DialogResult = DialogResult.OK; + this.okButton.Location = new Point(123, 296); + this.okButton.Name = "okButton"; + this.okButton.Size = new Size(75, 23); + this.okButton.TabIndex = 6; + this.okButton.Text = "&OK"; + this.okButton.UseVisualStyleBackColor = true; + this.cancelButton.Anchor = AnchorStyles.None; + this.cancelButton.DialogResult = DialogResult.Cancel; + this.cancelButton.Location = new Point(204, 296); + this.cancelButton.Name = "cancelButton"; + this.cancelButton.Size = new Size(75, 23); + this.cancelButton.TabIndex = 7; + this.cancelButton.Text = "&Cancel"; + this.cancelButton.UseVisualStyleBackColor = true; + tableLayoutPanel1.SetColumnSpan((Control) this.optionsTabControl, 3); + this.optionsTabControl.Dock = DockStyle.Fill; + this.optionsTabControl.Location = new Point(3, 83); + this.optionsTabControl.Margin = new Padding(3, 8, 3, 3); + this.optionsTabControl.Name = "optionsTabControl"; + this.optionsTabControl.SelectedIndex = 0; + this.optionsTabControl.Size = new Size(276, 207); + this.optionsTabControl.TabIndex = 5; + this.generateInitCheckBox.Anchor = AnchorStyles.Left; + this.generateInitCheckBox.AutoSize = true; + tableLayoutPanel1.SetColumnSpan((Control) this.generateInitCheckBox, 2); + this.generateInitCheckBox.Location = new Point(90, 55); + this.generateInitCheckBox.Name = "generateInitCheckBox"; + this.generateInitCheckBox.Size = new Size(155, 17); + this.generateInitCheckBox.TabIndex = 4; + this.generateInitCheckBox.Text = "&Generate Initialization Code"; + this.generateInitCheckBox.UseVisualStyleBackColor = true; + this.gradientNameTextBox.Anchor = AnchorStyles.Left | AnchorStyles.Right; + tableLayoutPanel1.SetColumnSpan((Control) this.gradientNameTextBox, 2); + this.gradientNameTextBox.Location = new Point(90, 29); + this.gradientNameTextBox.Name = "gradientNameTextBox"; + this.gradientNameTextBox.Size = new Size(189, 20); + this.gradientNameTextBox.TabIndex = 3; + this.gradientNameTextBox.Text = "Gradient1"; + this.gradientNameTextBox.TextChanged += new EventHandler(this.gradientNameTextBox_TextChanged); + this.AcceptButton = (IButtonControl) this.okButton; + this.AutoScaleDimensions = new SizeF(6f, 13f); + this.AutoScaleMode = AutoScaleMode.Font; + this.CancelButton = (IButtonControl) this.cancelButton; + this.ClientSize = new Size(300, 340); + this.Controls.Add((Control) tableLayoutPanel1); + this.MaximizeBox = false; + this.MaximumSize = new Size(432, 371); + this.MinimumSize = new Size(276, 326); + this.Name = nameof (Config2); + this.Padding = new Padding(9); + this.ShowIcon = false; + this.Text = "Configure HDMA"; + tableLayoutPanel1.ResumeLayout(false); + tableLayoutPanel1.PerformLayout(); + tableLayoutPanel2.ResumeLayout(false); + tableLayoutPanel2.PerformLayout(); + this.nWritesNumericUpDown.EndInit(); + this.ResumeLayout(false); + } +} diff --git a/Config2.resx b/Config2.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/Config2.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file diff --git a/DoubleBufferedPanel.cs b/DoubleBufferedPanel.cs new file mode 100644 index 0000000..110ca4a --- /dev/null +++ b/DoubleBufferedPanel.cs @@ -0,0 +1,26 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.DoubleBufferedPanel +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal sealed class DoubleBufferedPanel : Control +{ + public DoubleBufferedPanel() + { + this.DoubleBuffered = true; + this.ResizeRedraw = true; + } + + protected override void OnPaint(PaintEventArgs e) + { + base.OnPaint(e); + e.Graphics.ResetTransform(); + ControlPaint.DrawBorder3D(e.Graphics, this.ClientRectangle, Border3DStyle.SunkenOuter); + } +} diff --git a/Eyedropper.cs b/Eyedropper.cs new file mode 100644 index 0000000..0a1b166 --- /dev/null +++ b/Eyedropper.cs @@ -0,0 +1,433 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.Eyedropper +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal sealed class Eyedropper : Form +{ + private const int c_zoom = 9; + private const int c_reg = 9; + private const int c_offset = 4; + private const int INPUT_MOUSE = 0; + private const uint MOUSEEVENTF_MIDDLEDOWN = 32 /*0x20*/; + private const uint MOUSEEVENTF_MIDDLEUP = 64 /*0x40*/; + private const int c_sleepTime = 20; + private const double c_step = 0.2; + private const int WM_WINDOWPOSCHANGING = 70; + private const int WM_GETMINMAXINFO = 36; + private Bitmap m_buffer = new Bitmap(9, 9); + private System.Windows.Forms.Timer m_timer = new System.Windows.Forms.Timer() + { + Interval = 1 + }; + internal static readonly Cursor s_blank = Eyedropper.LoadCursor("SFXProductions.GradientTool.Resources.blank.cur"); + private static readonly Cursor s_crosshair = Eyedropper.LoadCursor("SFXProductions.GradientTool.Resources.InvertedCrosshair.cur"); + private Color m_selectedColour; + private static readonly Size s_minSize = new Size(5, 5); + + private static Cursor LoadCursor(string name) + { + using (Stream manifestResourceStream = typeof (Eyedropper).Assembly.GetManifestResourceStream(name)) + return new Cursor(manifestResourceStream); + } + + [DllImport("user32.dll", SetLastError = true)] + private static extern uint SendInput(uint nInputs, Eyedropper.INPUT[] pInputs, int cbSize); + + private static void MiddleClick() + { + int size = 0; + unsafe + { + size = sizeof(Eyedropper.INPUT); + } + int num = (int) Eyedropper.SendInput(2U, new Eyedropper.INPUT[2] + { + new Eyedropper.INPUT() + { + type = 0, + mi = new Eyedropper.MOUSEINPUT() + { + dwFlags = 32U /*0x20*/ + } + }, + new Eyedropper.INPUT() + { + type = 0, + mi = new Eyedropper.MOUSEINPUT() + { + dwFlags = 64U /*0x40*/ + } + } + }, size); + } + + private Eyedropper(string text) + { + this.DoubleBuffered = true; + this.AutoScaleMode = AutoScaleMode.None; + this.FormBorderStyle = FormBorderStyle.None; + this.ClientSize = new Size(81, 81); + this.ShowInTaskbar = false; + this.TopMost = true; + this.Capture = true; + this.Opacity = 0.0; + this.Text = text; + this.m_timer.Tick += (EventHandler) ((s, e2) => + { + this.CenterOnMouse(); + if (this.Focused) + return; + Eyedropper.MiddleClick(); + }); + } + + protected override void Dispose(bool disposing) + { + try + { + if (disposing) + { + if (this.m_buffer != null) + this.m_buffer.Dispose(); + if (this.m_timer != null) + this.m_timer.Dispose(); + } + this.m_buffer = (Bitmap) null; + this.m_timer = (System.Windows.Forms.Timer) null; + } + finally + { + base.Dispose(disposing); + } + } + + private void CenterOnMouse() + { + int num1 = Control.MousePosition.X - this.ClientSize.Width / 2; + int num2 = Control.MousePosition.Y - this.ClientSize.Height / 2; + if (num1 < 0) + num1 = 0; + else if (num1 + this.ClientSize.Width >= SystemInformation.PrimaryMonitorSize.Width) + num1 = SystemInformation.PrimaryMonitorSize.Width - this.ClientSize.Width; + if (num2 < 0) + num2 = 0; + else if (num2 + this.ClientSize.Height >= SystemInformation.PrimaryMonitorSize.Height) + num2 = SystemInformation.PrimaryMonitorSize.Height - this.ClientSize.Height; + this.Left = num1; + this.Top = num2; + this.UpdateBuffer(); + this.Invalidate(); + } + + private void UpdateBuffer() + { + Rectangle rectangle = new Rectangle(Control.MousePosition.X - 4, Control.MousePosition.Y - 4, 9, 9); + if (rectangle.Left < 0) + rectangle.X = 0; + else if (rectangle.Right > SystemInformation.PrimaryMonitorSize.Width) + rectangle.X = SystemInformation.PrimaryMonitorSize.Width - rectangle.Width; + if (rectangle.Top < 0) + rectangle.Y = 0; + else if (rectangle.Bottom > SystemInformation.PrimaryMonitorSize.Height) + rectangle.Y = SystemInformation.PrimaryMonitorSize.Height - rectangle.Height; + using (Graphics graphics = Graphics.FromImage((Image) this.m_buffer)) + graphics.CopyFromScreen(rectangle.Location, Point.Empty, new Size(9, 9), CopyPixelOperation.SourceCopy); + Point mousePosition = Control.MousePosition; + mousePosition.Offset(-rectangle.X, -rectangle.Y); + if (mousePosition.X < 0) + mousePosition.X = 0; + else if (mousePosition.X >= 9) + mousePosition.X = 8; + if (mousePosition.Y < 0) + mousePosition.Y = 0; + else if (mousePosition.Y >= 9) + mousePosition.Y = 8; + this.m_selectedColour = this.m_buffer.GetPixel(mousePosition.X, mousePosition.Y); + } + + protected override void OnShown(EventArgs e) + { + for (double num = this.Opacity + 0.2; num <= 0.999; num += 0.2) + { + this.CenterOnMouse(); + if ((Control.ModifierKeys & Keys.Control) != Keys.None) + { + if (!object.ReferenceEquals((object) this.Cursor, (object) Eyedropper.s_crosshair)) + this.Cursor = Eyedropper.s_crosshair; + if (num >= 0.3) + { + this.Opacity = 0.3; + goto label_9; + } + } + this.Opacity = num; + Application.DoEvents(); + Thread.Sleep(20); + } + this.Opacity = 0.999; +label_9: + this.m_timer.Start(); + base.OnShown(e); + } + + protected override void OnClosing(CancelEventArgs e) + { + base.OnClosing(e); + if (e.Cancel) + return; + this.m_timer.Stop(); + for (double num = this.Opacity - 0.2; num >= 0.0; num -= 0.2) + { + this.Opacity = num; + this.Update(); + Thread.Sleep(20); + } + this.Opacity = 0.0; + } + + protected override Cursor DefaultCursor => Eyedropper.s_blank; + + protected override void OnMouseMove(MouseEventArgs e) + { + this.CenterOnMouse(); + base.OnMouseMove(e); + } + + protected override void OnMouseLeave(EventArgs e) + { + this.CenterOnMouse(); + base.OnMouseLeave(e); + } + + protected override void OnMouseClick(MouseEventArgs e) + { + bool flag; + if (flag = (e.Button & MouseButtons.Left) != MouseButtons.None) + this.CenterOnMouse(); + base.OnMouseClick(e); + if (!flag) + return; + this.DialogResult = DialogResult.OK; + } + + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + if ((e.Modifiers & Keys.Control) == Keys.None) + return; + this.Opacity = 0.3; + this.Cursor = Eyedropper.s_crosshair; + } + + protected override void OnKeyUp(KeyEventArgs e) + { + base.OnKeyUp(e); + if ((e.Modifiers & Keys.Control) != Keys.None) + return; + this.Cursor = Eyedropper.s_blank; + this.Opacity = 0.999; + } + + protected override void OnKeyPress(KeyPressEventArgs e) + { + base.OnKeyPress(e); + if (e.KeyChar != '\u001B') + return; + this.DialogResult = DialogResult.Cancel; + } + + protected override void OnPaint(PaintEventArgs e) + { + e.Graphics.PixelOffsetMode = PixelOffsetMode.Half; + e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor; + e.Graphics.DrawImage((Image) this.m_buffer, this.ClientRectangle); + e.Graphics.PixelOffsetMode = PixelOffsetMode.Default; + e.Graphics.InterpolationMode = InterpolationMode.Default; + IntPtr hdc = e.Graphics.GetHdc(); + try + { + Rectangle rect = Rectangle.Inflate(new Rectangle(Control.MousePosition.X, Control.MousePosition.Y, 1, 1), 4, 4); + if (rect.Left < 0) + rect.X = 0; + else if (rect.Right > SystemInformation.PrimaryMonitorSize.Width) + rect.X = SystemInformation.PrimaryMonitorSize.Width - rect.Width; + if (rect.Top < 0) + rect.Y = 0; + else if (rect.Bottom > SystemInformation.PrimaryMonitorSize.Height) + rect.Y = SystemInformation.PrimaryMonitorSize.Height - rect.Height; + Point mousePosition = Control.MousePosition; + mousePosition.Offset(-rect.X, -rect.Y); + if (mousePosition.X < 0) + mousePosition.X = 0; + else if (mousePosition.X >= 9) + mousePosition.X = 8; + if (mousePosition.Y < 0) + mousePosition.Y = 0; + else if (mousePosition.Y >= 9) + mousePosition.Y = 8; + rect = this.ClientRectangle; + Eyedropper.RECT lprc = (Eyedropper.RECT) rect; + Eyedropper.InvertRect(hdc, ref lprc); + lprc = (Eyedropper.RECT) (rect = Rectangle.Inflate(rect, -1, -1)); + Eyedropper.InvertRect(hdc, ref lprc); + rect = new Rectangle(mousePosition.X * 9 + 1, mousePosition.Y * 9 + 1, 7, 7); + lprc = (Eyedropper.RECT) rect; + Eyedropper.InvertRect(hdc, ref lprc); + rect.Inflate(-1, -1); + lprc = (Eyedropper.RECT) rect; + Eyedropper.InvertRect(hdc, ref lprc); + } + finally + { + e.Graphics.ReleaseHdc(hdc); + } + base.OnPaint(e); + } + + protected override Size DefaultMinimumSize => Eyedropper.s_minSize; + + protected override unsafe void WndProc(ref Message m) + { + if (m.Msg == 70) + { + Eyedropper.WindowPos windowPos = *(Eyedropper.WindowPos*) (void*) m.LParam; + } + base.WndProc(ref m); + if (m.Msg != 36) + return; + Eyedropper.MinMaxInfo* lparam = (Eyedropper.MinMaxInfo*) (void*) m.LParam; + lparam->ptMinTrackSize.x = this.MinimumSize.Width; + lparam->ptMinTrackSize.y = this.MinimumSize.Height; + } + + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool InvertRect(IntPtr hDC, ref Eyedropper.RECT lprc); + + public static void PickAColour(Form owner, Action acceptCallback) + { + for (double num = 1.0; num >= 0.0; num -= 0.2) + { + Thread.Sleep(20); + owner.Opacity = num; + owner.Update(); + if (owner.Owner != null) + { + owner.Owner.Opacity = num; + owner.Owner.Update(); + } + } + owner.Opacity = 0.0; + if (owner.Owner != null) + owner.Owner.Opacity = 0.0; + Eyedropper eyedropper = new Eyedropper("GradientTool Eyedropper"); + if (eyedropper.ShowDialog((IWin32Window) owner) != DialogResult.Cancel) + acceptCallback(eyedropper.m_selectedColour); + try + { + for (double num = 0.0; num <= 1.0; num += 0.2) + { + owner.Opacity = num; + if (owner.Owner != null) + owner.Owner.Opacity = num; + Application.DoEvents(); + Thread.Sleep(20); + } + owner.Opacity = 1.0; + if (owner.Owner != null) + { + owner.Owner.Opacity = 1.0; + owner.Owner.Refresh(); + } + if (owner.Focused) + return; + owner.Activate(); + } + catch (ObjectDisposedException ex) + { + } + } + + private struct MOUSEINPUT + { + public int dx; + public int dy; + public uint mouseData; + public uint dwFlags; + public uint time; + public IntPtr dwExtraInfo; + } + + [StructLayout(LayoutKind.Explicit)] + private struct INPUT + { + [FieldOffset(0)] + public int type; + [FieldOffset(4)] + public Eyedropper.MOUSEINPUT mi; + } + + private struct WindowPos + { + public IntPtr hwnd; + public IntPtr hwndInsertAfter; + public int x; + public int y; + public int width; + public int height; + public uint flags; + } + + private struct POINT + { + public int x; + public int y; + } + + private struct MinMaxInfo + { + public Eyedropper.POINT ptReserved; + public Eyedropper.POINT ptMaxSize; + public Eyedropper.POINT ptMaxPosition; + public Eyedropper.POINT ptMinTrackSize; + public Eyedropper.POINT ptMaxTrackSize; + } + + private struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + + public static implicit operator Eyedropper.RECT(Rectangle rectangle) + { + return new Eyedropper.RECT() + { + left = rectangle.Left, + top = rectangle.Top, + right = rectangle.Right, + bottom = rectangle.Bottom + }; + } + + public static implicit operator Rectangle(Eyedropper.RECT rect) + { + return Rectangle.FromLTRB(rect.left, rect.top, rect.right, rect.bottom); + } + } +} diff --git a/Gradient.cs b/Gradient.cs new file mode 100644 index 0000000..0ff7214 --- /dev/null +++ b/Gradient.cs @@ -0,0 +1,165 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.Gradient +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.Collections.Generic; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal sealed class Gradient +{ + private List m_stops; + + public Gradient() + { + this.m_stops = new List(2); + this.m_stops.Add(new GradientStop(0.0, new Vector() + { + X = 1.0 + })); + this.m_stops.Add(new GradientStop(1.0, new Vector() + { + Y = 1.0, + Z = 1.0 + })); + } + + public GradientColourspace Colourspace { get; set; } + + public GradientType Type { get; set; } + + public List Stops => this.m_stops; + + private void FillBuffers( + int count, + double[] rBuffer, + double[] gBuffer, + double[] bBuffer, + double rValue, + double gValue, + double bValue) + { + for (int index = 0; index < count; ++index) + { + rBuffer[index] = rValue; + gBuffer[index] = gValue; + bBuffer[index] = bValue; + } + } + + private void FillBuffers( + int start, + int end, + double[] rBuffer, + double[] gBuffer, + double[] bBuffer, + double rValue, + double gValue, + double bValue) + { + for (int index = start; index < end; ++index) + { + rBuffer[index] = rValue; + gBuffer[index] = gValue; + bBuffer[index] = bValue; + } + } + + public void Calculate(int count, double[] r, double[] g, double[] b) + { + if (count <= 0 || count > r.Length || count > g.Length || count > b.Length) + throw new ArgumentOutOfRangeException(nameof (count), "Count must be greater than zero but less than the length of r, g, and b."); + if (r == null) + throw new ArgumentNullException(nameof (r)); + if (g == null) + throw new ArgumentNullException(nameof (g)); + if (b == null) + throw new ArgumentNullException(nameof (b)); + if (this.m_stops.Count == 0) + this.FillBuffers(count, r, g, b, 0.0, 0.0, 0.0); + else if (this.m_stops.Count == 1) + { + Vector colour = this.m_stops[0].Colour; + this.FillBuffers(count, r, g, b, colour.X, colour.Y, colour.Z); + } + else + { + this.m_stops.Sort(); + this.m_stops.Sort(); + GradientStop gradientStop = new GradientStop(); + Vector a = new Vector(); + Vector pre = a; + for (int index1 = 0; index1 < this.m_stops.Count; ++index1) + { + GradientStop stop = this.m_stops[index1]; + Vector colourspace1 = stop.Colour.HDRToColourspace(this.Colourspace); + if (index1 == 0) + { + if (stop.Position > 0.0) + { + int count1 = (int) (stop.Position * (double) (count - 1) + 0.5); + Vector colour = stop.Colour; + this.FillBuffers(count1, r, g, b, colour.X, colour.Y, colour.Z); + } + gradientStop = stop; + a = pre = colourspace1; + } + else + { + Vector colourspace2 = (index1 + 1 < this.m_stops.Count ? this.m_stops[index1 + 1] : stop).Colour.HDRToColourspace(this.Colourspace); + int num1 = (int) (gradientStop.Position * (double) (count - 1) + 0.5); + int num2 = (int) (stop.Position * (double) (count - 1) + 0.5); + double num3 = (double) (num2 - num1); + for (int index2 = num1; index2 <= num2; ++index2) + { + Vector hdr = this.Interpolate(pre, a, colourspace1, colourspace2, (double) (index2 - num1) / num3).ToHDR(this.Colourspace); + r[index2] = hdr.X; + g[index2] = hdr.Y; + b[index2] = hdr.Z; + } + pre = a; + gradientStop = stop; + a = colourspace1; + } + } + if (gradientStop.Position < 1.0) + { + int start = (int) (gradientStop.Position * (double) (count - 1) + 0.5); + Vector colour = gradientStop.Colour; + this.FillBuffers(start, count, r, g, b, colour.X, colour.Y, colour.Z); + } + else + { + if (gradientStop.Position != 1.0 || !gradientStop.Colour.IsValid() || !double.IsNaN(r[count - 1]) || !double.IsNaN(g[count - 1]) || !double.IsNaN(b[count - 1])) + return; + r[count - 1] = gradientStop.Colour.X; + g[count - 1] = gradientStop.Colour.Y; + b[count - 1] = gradientStop.Colour.Z; + } + } + } + + private Vector Interpolate(Vector pre, Vector a, Vector b, Vector post, double x) + { + bool flag = this.Colourspace >= GradientColourspace.RGB && this.Colourspace <= GradientColourspace.RGBL; + switch (this.Type) + { + case GradientType.Linear: + return !flag ? Vector.LerpH(a, b, x) : Vector.LerpRGB(a, b, x, this.Colourspace); + case GradientType.Circular: + return !flag ? Vector.CerpH(a, b, x) : Vector.CerpRGB(a, b, x, this.Colourspace); + case GradientType.Cubic: + case GradientType.CatmullRom: + bool catmullRom = this.Type == GradientType.CatmullRom; + return !flag ? Vector.CubicH(pre, a, b, post, x, catmullRom) : Vector.CubicRGB(pre, a, b, post, x, catmullRom, this.Colourspace); + case GradientType.Hermite: + return !flag ? Vector.HermiteH(pre, a, b, post, x) : Vector.HermiteRGB(pre, a, b, post, x, this.Colourspace); + default: + throw new ArgumentException("Invalid gradient type."); + } + } +} diff --git a/GradientColourspace.cs b/GradientColourspace.cs new file mode 100644 index 0000000..f32e068 --- /dev/null +++ b/GradientColourspace.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.GradientColourspace +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +#nullable disable +namespace SFXProductions.GradientTool; + +internal enum GradientColourspace +{ + RGB, + RGBV, + RGBB, + RGBL, + HSV, + HSL, + HSY, +} diff --git a/GradientControl.cs b/GradientControl.cs new file mode 100644 index 0000000..98088f9 --- /dev/null +++ b/GradientControl.cs @@ -0,0 +1,511 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.GradientControl +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA; +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.IO; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal sealed class GradientControl : Control +{ + private int m_sizeOfGradient = 224 /*0xE0*/; + private Gradient m_gradient; + private Bitmap m_realGradient; + private Bitmap m_emuGradient; + private Bitmap m_briGradient; + private double[] m_rPrebuffer; + private double[] m_gPrebuffer; + private double[] m_bPrebuffer; + private bool m_enableGrid = true; + private static readonly Size s_minSize = new Size(10, 0); + private ulong m_movingId; + private Settings2 m_settings = Settings2.CreateMode2Mode0(GradientChannels.RedGreenBlue, "Gradient1"); + + public GradientControl() + { + this.m_gradient = new Gradient(); + this.InitBuffers(); + this.Recalculate(); + this.SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); + } + + private static Bitmap CreateB4Bitmap(int height, int width = 1) + { + Bitmap b4Bitmap = new Bitmap(width, height, PixelFormat.Format4bppIndexed); + ColorPalette palette = b4Bitmap.Palette; + for (int index = 0; index < 16 /*0x10*/; ++index) + palette.Entries[index] = Color.FromArgb(index * 17, index * 17, index * 17); + b4Bitmap.Palette = palette; + return b4Bitmap; + } + + private void InitBuffers(int resize = -1) + { + if (resize < 0) + resize = this.m_sizeOfGradient; + Bitmap bitmap1 = (Bitmap) null; + Bitmap bitmap2 = (Bitmap) null; + Bitmap bitmap3 = (Bitmap) null; + double[] numArray1; + double[] numArray2; + double[] numArray3; + try + { + bitmap1 = new Bitmap(2, resize + 2, PixelFormat.Format24bppRgb); + bitmap2 = new Bitmap(1, resize, PixelFormat.Format16bppRgb555); + bitmap3 = GradientControl.CreateB4Bitmap(resize); + numArray1 = new double[resize]; + numArray2 = new double[resize]; + numArray3 = new double[resize]; + } + catch (Exception ex) + { + bitmap1?.Dispose(); + bitmap2?.Dispose(); + bitmap3?.Dispose(); + if (ex is ArgumentException) + throw new InsufficientMemoryException(); + throw; + } + if (this.m_realGradient != null) + this.m_realGradient.Dispose(); + if (this.m_emuGradient != null) + this.m_emuGradient.Dispose(); + if (this.m_briGradient != null) + this.m_briGradient.Dispose(); + this.m_realGradient = bitmap1; + this.m_emuGradient = bitmap2; + this.m_briGradient = bitmap3; + this.m_rPrebuffer = numArray1; + this.m_gPrebuffer = numArray2; + this.m_bPrebuffer = numArray3; + } + + protected override Size DefaultMinimumSize => GradientControl.s_minSize; + + public GradientColourspace Colourspace + { + get => this.m_gradient.Colourspace; + set + { + if (this.m_gradient.Colourspace == value) + return; + this.m_gradient.Colourspace = value; + this.Recalculate(); + this.RedrawGradientRegion(); + this.OnGradientChanged(EventArgs.Empty); + } + } + + public GradientType Type + { + get => this.m_gradient.Type; + set + { + if (this.m_gradient.Type == value) + return; + this.m_gradient.Type = value; + this.Recalculate(); + this.RedrawGradientRegion(); + this.OnGradientChanged(EventArgs.Empty); + } + } + + public GradientChannels Channels + { + get => this.m_settings.Channels; + set + { + if (this.m_settings.Channels == value) + return; + this.m_settings.Channels = value; + this.Recalculate(); + int num1 = (this.ClientSize.Width - 38) / 2; + int num2 = this.ClientSize.Height - 16 /*0x10*/; + this.Invalidate(new Rectangle(this.ClientSize.Width - num1 - 8, 9, num1 - 2, num2 - 2)); + this.OnGradientChanged(EventArgs.Empty); + } + } + + public bool ShowGrid + { + get => this.m_enableGrid; + set + { + if (this.m_enableGrid == value) + return; + this.m_enableGrid = value; + this.RedrawGradientRegion(); + } + } + + public int SizeOfGradient => this.m_sizeOfGradient; + + public void SetSizeOfGradient(int nSize) + { + if (nSize < 4 || nSize > (int) short.MaxValue) + throw new ArgumentOutOfRangeException(nameof (nSize), "Size of gradient must be a number between 4 and 32,767."); + if (this.m_sizeOfGradient == nSize) + return; + this.InitBuffers(nSize); + this.m_sizeOfGradient = nSize; + this.Recalculate(); + this.RedrawGradientRegion(); + this.OnGradientChanged(EventArgs.Empty); + } + + public bool GenerateHDMAInitializationCode + { + get => this.m_settings.GenerateInitializationCode; + set + { + if (this.m_settings.GenerateInitializationCode == value) + return; + this.m_settings.GenerateInitializationCode = value; + this.OnGradientChanged(EventArgs.Empty); + } + } + + public void UpdateGradient() + { + this.Recalculate(); + this.RedrawGradientRegion(); + } + + private void Recalculate() + { + this.m_gradient.Calculate(this.m_sizeOfGradient, this.m_rPrebuffer, this.m_gPrebuffer, this.m_bPrebuffer); + this.m_realGradient.Fill24BppBitmap(this.m_rPrebuffer, this.m_gPrebuffer, this.m_bPrebuffer); + this.m_emuGradient.Fill15BppBitmap(this.m_rPrebuffer, this.m_gPrebuffer, this.m_bPrebuffer, this.m_settings.Channels); + if (this.m_settings.Channels != GradientChannels.Brightness) + return; + this.m_briGradient.Fill4BppBitmap(this.m_rPrebuffer, this.m_gPrebuffer, this.m_bPrebuffer); + } + + private Region GetGradientRedrawRegion() + { + int num1 = (this.ClientSize.Width - 38) / 2; + int num2 = this.ClientSize.Height - 16 /*0x10*/; + Region gradientRedrawRegion = new Region(new Rectangle(9, 9, num1 - 2, num2 - 2)); + gradientRedrawRegion.Union(new Rectangle(this.ClientSize.Width - num1 - 8, 9, num1 - 2, num2 - 2)); + return gradientRedrawRegion; + } + + private void RedrawGradientRegion() + { + using (Region gradientRedrawRegion = this.GetGradientRedrawRegion()) + this.Invalidate(gradientRedrawRegion); + } + + protected override void OnPaint(PaintEventArgs e) + { + int width = (this.ClientSize.Width - 38) / 2; + int height1 = this.ClientSize.Height - 16 /*0x10*/; + int height2 = this.ClientSize.Height - 24; + e.Graphics.PixelOffsetMode = PixelOffsetMode.Half; + e.Graphics.InterpolationMode = InterpolationMode.Bilinear; + e.Graphics.DrawImage((Image) this.m_realGradient, new Rectangle(9, 9, width - 2, height1 - 2), 0.5f, 1f, 1f, (float) this.m_sizeOfGradient, GraphicsUnit.Pixel); + e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor; + e.Graphics.DrawImage(this.m_settings.Channels != GradientChannels.Brightness ? (Image) this.m_emuGradient : (Image) this.m_briGradient, this.ClientSize.Width - width - 8, 9, width - 2, height1 - 2); + if (this.m_enableGrid && this.Height >= this.m_sizeOfGradient * 6) + { + double num1 = (double) height1 / (double) this.m_sizeOfGradient; + double num2 = (double) Math.Max(e.ClipRectangle.Top - 9, 0); + double num3 = num2 - num2 % num1 + 9.0; + int num4 = this.ClientSize.Height - 9; + using (Pen pen1 = new Pen(Color.Black)) + { + using (Pen pen2 = new Pen(Color.White)) + { + pen1.DashStyle = DashStyle.Dot; + for (double num5 = num3; num5 <= (double) num4; num5 += num1) + { + int num6 = (int) num5; + e.Graphics.DrawLine(pen2, 9, num6, width + 7, num6); + e.Graphics.DrawLine(pen1, 9, num6, width + 7, num6); + e.Graphics.DrawLine(pen2, this.ClientSize.Width - width - 8, num6, this.ClientSize.Width - 9, num6); + e.Graphics.DrawLine(pen1, this.ClientSize.Width - width - 8, num6, this.ClientSize.Width - 9, num6); + } + } + } + } + ControlPaint.DrawBorder3D(e.Graphics, 8, 8, width, height1, Border3DStyle.SunkenOuter); + ControlPaint.DrawBorder3D(e.Graphics, this.ClientSize.Width - width - 9, 8, width, height1, Border3DStyle.SunkenOuter); + ControlPaint.DrawBorder3D(e.Graphics, this.ClientSize.Width / 2 - 1, 12, 2, height2, Border3DStyle.SunkenOuter); + Rectangle rectangle = new Rectangle(this.ClientSize.Width / 2 - 8, 0, 16 /*0x10*/, 8); + using (SolidBrush solidBrush = new SolidBrush(Color.Black)) + { + for (int index = 0; index < this.m_gradient.Stops.Count; ++index) + { + solidBrush.Color = this.m_gradient.Stops[index].Colour.ToRGB(GradientColourspace.RGB); + rectangle.Y = 8 + (int) (this.m_gradient.Stops[index].Position * (double) height2 + 0.5); + e.Graphics.FillRectangle((Brush) solidBrush, rectangle); + ControlPaint.DrawBorder3D(e.Graphics, rectangle, Border3DStyle.RaisedInner); + } + } + base.OnPaint(e); + } + + public event EventHandler GradientChanged; + + private void OnGradientChanged(EventArgs e) + { + if (this.GradientChanged == null) + return; + this.GradientChanged((object) this, e); + } + + private static bool IsPointInRect(Rectangle rect, Point point) + { + return point.X >= rect.Left && point.X <= rect.Right && point.Y >= rect.Top && point.Y <= rect.Bottom; + } + + private Rectangle GetSliderHitArea() + { + return new Rectangle(this.ClientSize.Width / 2 - 8, 8, 16 /*0x10*/, this.ClientSize.Height - 16 /*0x10*/); + } + + protected override void OnMouseDoubleClick(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left && GradientControl.IsPointInRect(this.GetSliderHitArea(), e.Location)) + { + int num1 = this.ClientSize.Height - 24; + Rectangle rect = new Rectangle(this.ClientSize.Width / 2 - 8, 0, 16 /*0x10*/, 8); + bool flag = false; + for (int index = 0; index < this.m_gradient.Stops.Count; ++index) + { + GradientStop stop = this.m_gradient.Stops[index]; + rect.Y = 8 + (int) (stop.Position * (double) num1 + 0.5); + if (GradientControl.IsPointInRect(rect, e.Location)) + { + flag = true; + if (Utils.EditGradientStop((IWin32Window) this, ref stop)) + { + this.m_gradient.Stops[index] = stop; + this.Recalculate(); + using (Region gradientRedrawRegion = this.GetGradientRedrawRegion()) + { + gradientRedrawRegion.Union(rect); + rect.Y = 8 + (int) (stop.Position * (double) num1 + 0.5); + gradientRedrawRegion.Union(rect); + this.Invalidate(gradientRedrawRegion); + } + this.OnGradientChanged(EventArgs.Empty); + break; + } + break; + } + } + if (!flag) + { + double num2 = (double) (e.Y - 12) / (double) num1; + if (num2 < 0.0) + num2 = 0.0; + else if (num2 > 1.0) + num2 = 1.0; + int index = ((int) (num2 * (double) (this.m_sizeOfGradient - 1) + 0.5)).Clamp(this.m_sizeOfGradient - 1); + double num3 = (double) index / (double) (this.m_sizeOfGradient - 1); + GradientStop gradientStop = new GradientStop() + { + Colour = new Vector() + { + X = this.m_rPrebuffer[index], + Y = this.m_gPrebuffer[index], + Z = this.m_bPrebuffer[index] + }, + Position = num3 + }; + if (Utils.EditGradientStop((IWin32Window) this, ref gradientStop, "Add Gradient Stop")) + { + this.m_gradient.Stops.Add(new GradientStop(gradientStop.Position, gradientStop.Colour)); + this.Recalculate(); + using (Region gradientRedrawRegion = this.GetGradientRedrawRegion()) + { + rect.Y = 8 + (int) (gradientStop.Position * (double) num1 + 0.5); + gradientRedrawRegion.Union(rect); + this.Invalidate(gradientRedrawRegion); + } + this.OnGradientChanged(EventArgs.Empty); + } + } + } + base.OnMouseDoubleClick(e); + } + + protected override void OnMouseClick(MouseEventArgs e) + { + if (GradientControl.IsPointInRect(this.GetSliderHitArea(), e.Location)) + { + int num = this.ClientSize.Height - 24; + Rectangle rect = new Rectangle(this.ClientSize.Width / 2 - 8, 0, 16 /*0x10*/, 8); + for (int index = 0; index < this.m_gradient.Stops.Count; ++index) + { + GradientStop stop = this.m_gradient.Stops[index]; + rect.Y = 8 + (int) (stop.Position * (double) num + 0.5); + if (GradientControl.IsPointInRect(rect, e.Location)) + { + if (e.Button == MouseButtons.Right && MessageBox.Show((IWin32Window) this, $"Remove the gradient stop at {this.m_gradient.Stops[index].Position:P1}?", "GradientTool", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) + { + this.m_gradient.Stops.RemoveAt(index); + this.Recalculate(); + using (Region gradientRedrawRegion = this.GetGradientRedrawRegion()) + { + gradientRedrawRegion.Union(rect); + this.Invalidate(gradientRedrawRegion); + } + this.OnGradientChanged(EventArgs.Empty); + break; + } + break; + } + } + } + base.OnMouseClick(e); + } + + protected override void OnMouseDown(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left && GradientControl.IsPointInRect(this.GetSliderHitArea(), e.Location)) + { + int num = this.ClientSize.Height - 24; + Rectangle rect = new Rectangle(this.ClientSize.Width / 2 - 8, 0, 16 /*0x10*/, 8); + for (int index = 0; index < this.m_gradient.Stops.Count; ++index) + { + GradientStop stop = this.m_gradient.Stops[index]; + rect.Y = 8 + (int) (stop.Position * (double) num + 0.5); + if (GradientControl.IsPointInRect(rect, e.Location)) + { + this.m_movingId = stop.Id; + break; + } + } + } + base.OnMouseDown(e); + } + + protected override void OnMouseUp(MouseEventArgs e) + { + if (e.Button == MouseButtons.Left) + this.m_movingId = 0UL; + base.OnMouseUp(e); + } + + protected override void OnMouseMove(MouseEventArgs e) + { + if (this.m_movingId != 0UL && (e.Button & MouseButtons.Left) != MouseButtons.None) + { + int num1 = this.ClientSize.Height - 24; + int index = this.m_gradient.Stops.IndexOfGradientStop(this.m_movingId); + GradientStop stop = this.m_gradient.Stops[index]; + Rectangle rect = new Rectangle(this.ClientSize.Width / 2 - 8, 8 + (int) (stop.Position * (double) num1 + 0.5), 16 /*0x10*/, 8); + double num2 = (double) (e.Y - 12) / (double) num1; + if (num2 < 0.0) + num2 = 0.0; + else if (num2 > 1.0) + num2 = 1.0; + stop.Position = num2; + this.m_gradient.Stops[index] = stop; + this.Recalculate(); + using (Region gradientRedrawRegion = this.GetGradientRedrawRegion()) + { + gradientRedrawRegion.Union(rect); + rect.Y = 8 + (int) (num2 * (double) num1 + 0.5); + gradientRedrawRegion.Union(rect); + this.Invalidate(gradientRedrawRegion); + } + this.OnGradientChanged(EventArgs.Empty); + } + base.OnMouseMove(e); + } + + public Settings2 Settings + { + get => this.m_settings; + set + { + this.m_settings = value; + this.Recalculate(); + this.RedrawGradientRegion(); + this.OnGradientChanged(EventArgs.Empty); + } + } + + public string GradientName + { + get => this.m_settings.Name; + set + { + if (!(this.m_settings.Name != value)) + return; + this.m_settings.Name = value; + this.OnGradientChanged(EventArgs.Empty); + } + } + + public void GenerateASM(CodeGen code) + { + Generator2.GenerateCode(this.m_rPrebuffer, this.m_gPrebuffer, this.m_bPrebuffer, this.m_settings, code); + } + + public bool SaveGradient(string filename, bool is24Bit) + { + bool flag = false; + ImageFormat format; + switch (Path.GetExtension(filename).ToLowerInvariant()) + { + case ".bmp": + case ".dib": + format = ImageFormat.Bmp; + break; + case ".jpeg": + case ".jpg": + case ".jpe": + flag = true; + format = ImageFormat.Jpeg; + break; + case ".gif": + flag = true; + format = ImageFormat.Gif; + break; + default: + format = ImageFormat.Png; + break; + } + if (flag && MessageBox.Show((IWin32Window) this, "Saving in this format may cause quality loss.\r\nDo you want to continue?", "GradientTool", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.No) + return false; + if (is24Bit) + { + using (Bitmap bmp = new Bitmap(24, this.m_sizeOfGradient, PixelFormat.Format24bppRgb)) + { + bmp.Fill24BppBitmap(this.m_rPrebuffer, this.m_gPrebuffer, this.m_bPrebuffer, false); + bmp.Save(filename, format); + } + } + else if (this.m_settings.Channels != GradientChannels.Brightness) + { + using (Bitmap bmp = new Bitmap(24, this.m_sizeOfGradient, PixelFormat.Format16bppRgb555)) + { + bmp.Fill15BppBitmap(this.m_rPrebuffer, this.m_gPrebuffer, this.m_bPrebuffer, this.m_settings.Channels); + bmp.Save(filename, format); + } + } + else + { + using (Bitmap b4Bitmap = GradientControl.CreateB4Bitmap(this.m_sizeOfGradient, 24)) + { + b4Bitmap.Fill4BppBitmap(this.m_rPrebuffer, this.m_gPrebuffer, this.m_bPrebuffer); + b4Bitmap.Save(filename, format); + } + } + return true; + } +} diff --git a/GradientStop.cs b/GradientStop.cs new file mode 100644 index 0000000..e2b9b69 --- /dev/null +++ b/GradientStop.cs @@ -0,0 +1,45 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.GradientStop +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.Drawing; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal struct GradientStop : IComparable, IComparable +{ + private static ulong s_lastId; + private ulong m_id; + + public GradientStop(double position, Vector colour) + : this() + { + this.m_id = ++GradientStop.s_lastId; + this.Position = position; + this.Colour = colour; + } + + public GradientStop(double position, Color colour) + : this(position, colour.ToColourspace(GradientColourspace.RGB)) + { + } + + public double Position { get; set; } + + public Vector Colour { get; set; } + + public ulong Id => this.m_id; + + public int CompareTo(GradientStop other) => this.Position.CompareTo(other.Position); + + int IComparable.CompareTo(object obj) + { + if (obj is GradientStop other) + return this.CompareTo(other); + throw new ArgumentException(); + } +} diff --git a/GradientTool.csproj b/GradientTool.csproj new file mode 100644 index 0000000..9f44167 --- /dev/null +++ b/GradientTool.csproj @@ -0,0 +1,80 @@ + + + net9.0-windows + WinExe + 0.8.2.1 + SFXProductions.GradientTool + false + true + true + true + en-CA + HDMA Gradient Generator + ExoticMatter Productions + GradientTool + Copyright © 2015 ExoticMatter + 0.8.2.1 + + + Release + + + Release + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/GradientTool.csproj.user b/GradientTool.csproj.user new file mode 100644 index 0000000..7cbf6e6 --- /dev/null +++ b/GradientTool.csproj.user @@ -0,0 +1,42 @@ + + + + + + Form + + + Form + + + Form + + + Component + + + Form + + + Component + + + Component + + + Component + + + Component + + + Component + + + Form + + + Form + + + \ No newline at end of file diff --git a/GradientTool.sln b/GradientTool.sln new file mode 100644 index 0000000..a974248 --- /dev/null +++ b/GradientTool.sln @@ -0,0 +1,24 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 18 +VisualStudioVersion = 18.5.11709.299 stable +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GradientTool", "GradientTool.csproj", "{ABF09A9A-444F-412F-9993-5BD116A38AE6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ABF09A9A-444F-412F-9993-5BD116A38AE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ABF09A9A-444F-412F-9993-5BD116A38AE6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ABF09A9A-444F-412F-9993-5BD116A38AE6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ABF09A9A-444F-412F-9993-5BD116A38AE6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {43734D35-1886-479E-AF82-53F85654AA4D} + EndGlobalSection +EndGlobal diff --git a/GradientType.cs b/GradientType.cs new file mode 100644 index 0000000..0220e4d --- /dev/null +++ b/GradientType.cs @@ -0,0 +1,17 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.GradientType +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +#nullable disable +namespace SFXProductions.GradientTool; + +internal enum GradientType +{ + Linear, + Circular, + Cubic, + CatmullRom, + Hermite, +} diff --git a/HDMA/Channel.cs b/HDMA/Channel.cs new file mode 100644 index 0000000..f41f7f7 --- /dev/null +++ b/HDMA/Channel.cs @@ -0,0 +1,80 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Channel +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA.Configuration; +using System; +using System.Collections.Generic; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal abstract class Channel +{ + private int m_channel; + + internal Channel() + { + } + + internal Channel(int channelNum) => this.m_channel = channelNum; + + public string GetChannelLabel(string gradientName) + { + return gradientName + (object) '_' + this.ChannelSuffix; + } + + public int HDMAChannel + { + get => this.m_channel; + set + { + if (this.m_channel == value) + return; + this.m_channel = value >= 0 && value <= 7 ? value : throw new ArgumentOutOfRangeException(nameof (value), "HDMA Channel number must be between 0 and 7."); + } + } + + public ChannelType FirstWriteType { get; set; } + + public ChannelType SecondWriteType { get; set; } + + public virtual bool CanUseContinuousMode => true; + + public abstract bool IsBackgroundOrBrightnessHDMA { get; } + + public abstract bool HasSecondWrite { get; } + + public abstract string ChannelSuffix { get; } + + public abstract uint CalculateTableSize(IList data); + + public abstract TabPage CreatePropertiesPage( + Mode0Channel sib, + ref ColourChannelsRef channelsReference); + + public abstract void ApplySettings(TabPage propertiesPage); + + public abstract void GetRawData( + double[] rBuffer, + double[] gBuffer, + double[] bBuffer, + DataPoint[] dataBuffer); + + protected abstract void DoWriteData(IList hdmaTable, CodeGen cGen); + + public void WriteData(IList hdmaTable, CodeGen cGen, string gradientName) + { + cGen.AppendLabel(this.GetChannelLabel(gradientName)); + cGen.AppendPlainText(':'); + cGen.AppendLine(); + this.DoWriteData(hdmaTable, cGen); + cGen.AppendKeyword("db"); + cGen.AppendSpace(); + cGen.AppendNumeric("$00"); + cGen.AppendLine(); + } +} diff --git a/HDMA/ChannelType.cs b/HDMA/ChannelType.cs new file mode 100644 index 0000000..9614237 --- /dev/null +++ b/HDMA/ChannelType.cs @@ -0,0 +1,23 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.ChannelType +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +[Flags] +internal enum ChannelType : byte +{ + Brightness = 0, + Red = 32, // 0x20 + Green = 64, // 0x40 + Blue = 128, // 0x80 + Yellow = Green | Red, // 0x60 + Cyan = Blue | Green, // 0xC0 + Magenta = Blue | Red, // 0xA0 + Grey = Magenta | Green, // 0xE0 +} diff --git a/HDMA/CombinedChannel.cs b/HDMA/CombinedChannel.cs new file mode 100644 index 0000000..ef2e04c --- /dev/null +++ b/HDMA/CombinedChannel.cs @@ -0,0 +1,73 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.CombinedChannel +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA.Configuration; +using System.Collections.Generic; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal sealed class CombinedChannel : Channel +{ + public override bool CanUseContinuousMode => false; + + public override bool HasSecondWrite => false; + + public override bool IsBackgroundOrBrightnessHDMA => false; + + public override string ChannelSuffix => "Table"; + + public override uint CalculateTableSize(IList data) + { + uint count = (uint) data.Count; + return count + count * 3U; + } + + public override TabPage CreatePropertiesPage( + Mode0Channel sib, + ref ColourChannelsRef channelsReference) + { + UnconfigurablePropertyTab propertiesPage = new UnconfigurablePropertyTab(); + propertiesPage.Message = "GradientTool doesn’t generate initialization code for scrolling gradients."; + propertiesPage.Text = "Channel"; + return (TabPage) propertiesPage; + } + + public override void ApplySettings(TabPage propertiesPage) + { + } + + public override void GetRawData( + double[] rBuffer, + double[] gBuffer, + double[] bBuffer, + DataPoint[] dataBuffer) + { + Generator2.CreateScrollingTable(rBuffer, gBuffer, bBuffer, dataBuffer); + } + + protected override void DoWriteData(IList hdmaTable, CodeGen code) + { + for (int index = 0; index < hdmaTable.Count; ++index) + { + CompressedDataPoint compressedDataPoint = hdmaTable[index]; + if (compressedDataPoint.Data.Count > 0) + { + code.AppendKeyword("db"); + code.AppendSpace(); + code.WriteHexAddress((byte) compressedDataPoint.Count); + code.AppendPlainText(','); + code.WriteHexAddress((byte) compressedDataPoint.Data[0].Data1); + code.AppendPlainText(','); + code.WriteHexAddress((byte) compressedDataPoint.Data[0].Data2); + code.AppendPlainText(','); + code.WriteHexAddress((byte) compressedDataPoint.Data[0].Data3); + code.AppendLine(); + } + } + } +} diff --git a/HDMA/CompressedDataPoint.cs b/HDMA/CompressedDataPoint.cs new file mode 100644 index 0000000..7ec0778 --- /dev/null +++ b/HDMA/CompressedDataPoint.cs @@ -0,0 +1,19 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.CompressedDataPoint +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System.Collections.Generic; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal struct CompressedDataPoint(DataPoint dataPoint) +{ + public int Count = 1; + public List Data = new List() + { + dataPoint + }; +} diff --git a/HDMA/Configuration/ColourChannelsRef.cs b/HDMA/Configuration/ColourChannelsRef.cs new file mode 100644 index 0000000..3422772 --- /dev/null +++ b/HDMA/Configuration/ColourChannelsRef.cs @@ -0,0 +1,43 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Configuration.ColourChannelsRef +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA.Configuration; + +internal sealed class ColourChannelsRef +{ + private ChannelType m_channel; + private Label m_label; + private TabPage m_tabPage; + + public ChannelType Value + { + get => this.m_channel; + set + { + if (value == this.m_channel) + return; + this.m_channel = value; + if (this.m_label != null) + this.m_label.Text = this.m_channel.ToString(); + if (this.m_tabPage == null) + return; + this.m_tabPage.Text = this.m_channel.ToString(); + } + } + + public void Bind(Label label, TabPage tabPage, ChannelType initialValue) + { + this.m_channel = initialValue; + if ((this.m_label = label) != null) + this.m_label.Text = initialValue.ToString(); + if ((this.m_tabPage = tabPage) == null) + return; + this.m_tabPage.Text = initialValue.ToString(); + } +} diff --git a/HDMA/Configuration/Mode0ChannelPropertyTab.cs b/HDMA/Configuration/Mode0ChannelPropertyTab.cs new file mode 100644 index 0000000..e550fc0 --- /dev/null +++ b/HDMA/Configuration/Mode0ChannelPropertyTab.cs @@ -0,0 +1,159 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Configuration.Mode0ChannelPropertyTab +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA.Configuration; + +internal class Mode0ChannelPropertyTab : TabPage +{ + private IContainer components; + private Label chtypeLabel; + private Label destRegLabel; + private Label coloursLabel; + private NumericUpDown hdmaChannelNumericUpDown; + + public Mode0ChannelPropertyTab(Mode0Channel channel, ColourChannelsRef colourChannelsReference) + { + this.InitializeComponent(); + this.destRegLabel.Text = channel.FirstWriteType != ChannelType.Brightness ? "COLDATA ($2132)" : "INIDISP ($2100)"; + colourChannelsReference.Bind(this.coloursLabel, (TabPage) this, channel.FirstWriteType); + this.hdmaChannelNumericUpDown.Value = (Decimal) channel.HDMAChannel; + } + + public void ApplyChanges(Mode0Channel channel) + { + channel.HDMAChannel = (int) this.hdmaChannelNumericUpDown.Value; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.chtypeLabel = new Label(); + this.destRegLabel = new Label(); + this.coloursLabel = new Label(); + this.hdmaChannelNumericUpDown = new NumericUpDown(); + Label label1 = new Label(); + Label label2 = new Label(); + Label label3 = new Label(); + Label label4 = new Label(); + TableLayoutPanel tableLayoutPanel = new TableLayoutPanel(); + tableLayoutPanel.SuspendLayout(); + this.hdmaChannelNumericUpDown.BeginInit(); + this.SuspendLayout(); + label1.Anchor = AnchorStyles.Right; + label1.AutoSize = true; + label1.Location = new Point(20, 5); + label1.Name = "label1"; + label1.Size = new Size(76, 13); + label1.TabIndex = 0; + label1.Text = "Channel &Type:"; + label2.Anchor = AnchorStyles.Right; + label2.AutoSize = true; + label2.Location = new Point(40, 29); + label2.Name = "label2"; + label2.Size = new Size(56, 13); + label2.TabIndex = 2; + label2.Text = "&Writes To:"; + label3.Anchor = AnchorStyles.Right; + label3.AutoSize = true; + label3.Location = new Point(3, 53); + label3.Name = "label3"; + label3.Size = new Size(93, 13); + label3.TabIndex = 4; + label3.Text = "&Colour Channel(s):"; + label4.Anchor = AnchorStyles.Right; + label4.AutoSize = true; + label4.Location = new Point(12, 78); + label4.Name = "label4"; + label4.Size = new Size(84, 13); + label4.TabIndex = 6; + label4.Text = "HDMA Cha&nnel:"; + tableLayoutPanel.ColumnCount = 2; + tableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + tableLayoutPanel.Controls.Add((Control) label1, 0, 0); + tableLayoutPanel.Controls.Add((Control) label2, 0, 1); + tableLayoutPanel.Controls.Add((Control) label3, 0, 2); + tableLayoutPanel.Controls.Add((Control) label4, 0, 4); + tableLayoutPanel.Controls.Add((Control) this.chtypeLabel, 1, 0); + tableLayoutPanel.Controls.Add((Control) this.destRegLabel, 1, 1); + tableLayoutPanel.Controls.Add((Control) this.coloursLabel, 1, 2); + tableLayoutPanel.Controls.Add((Control) this.hdmaChannelNumericUpDown, 1, 4); + tableLayoutPanel.Dock = DockStyle.Fill; + tableLayoutPanel.Location = new Point(0, 0); + tableLayoutPanel.Name = "tableLayoutPanel1"; + tableLayoutPanel.RowCount = 5; + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.Size = new Size(250, 98); + tableLayoutPanel.TabIndex = 0; + this.chtypeLabel.AutoEllipsis = true; + this.chtypeLabel.BackColor = SystemColors.Control; + this.chtypeLabel.BorderStyle = BorderStyle.Fixed3D; + this.chtypeLabel.Dock = DockStyle.Fill; + this.chtypeLabel.Location = new Point(102, 3); + this.chtypeLabel.Margin = new Padding(3); + this.chtypeLabel.Name = "chtypeLabel"; + this.chtypeLabel.Size = new Size(145, 18); + this.chtypeLabel.TabIndex = 1; + this.chtypeLabel.Text = "Transfer Mode 0 HDMA"; + this.chtypeLabel.TextAlign = ContentAlignment.MiddleLeft; + this.destRegLabel.AutoEllipsis = true; + this.destRegLabel.BackColor = SystemColors.Control; + this.destRegLabel.BorderStyle = BorderStyle.Fixed3D; + this.destRegLabel.Dock = DockStyle.Fill; + this.destRegLabel.Location = new Point(102, 27); + this.destRegLabel.Margin = new Padding(3); + this.destRegLabel.Name = "destRegLabel"; + this.destRegLabel.Size = new Size(145, 18); + this.destRegLabel.TabIndex = 3; + this.destRegLabel.Text = "[Destination Register]"; + this.destRegLabel.TextAlign = ContentAlignment.MiddleLeft; + this.coloursLabel.AutoEllipsis = true; + this.coloursLabel.BackColor = SystemColors.Control; + this.coloursLabel.BorderStyle = BorderStyle.Fixed3D; + this.coloursLabel.Dock = DockStyle.Fill; + this.coloursLabel.Location = new Point(102, 51); + this.coloursLabel.Margin = new Padding(3); + this.coloursLabel.Name = "coloursLabel"; + this.coloursLabel.Size = new Size(145, 18); + this.coloursLabel.TabIndex = 5; + this.coloursLabel.Text = "[Channels]"; + this.coloursLabel.TextAlign = ContentAlignment.MiddleLeft; + this.hdmaChannelNumericUpDown.Location = new Point(102, 75); + this.hdmaChannelNumericUpDown.Maximum = new Decimal(new int[4] + { + 7, + 0, + 0, + 0 + }); + this.hdmaChannelNumericUpDown.Name = "hdmaChannelNumericUpDown"; + this.hdmaChannelNumericUpDown.Size = new Size(50, 20); + this.hdmaChannelNumericUpDown.TabIndex = 7; + this.Controls.Add((Control) tableLayoutPanel); + this.Size = new Size(250, 98); + this.UseVisualStyleBackColor = true; + tableLayoutPanel.ResumeLayout(false); + tableLayoutPanel.PerformLayout(); + this.hdmaChannelNumericUpDown.EndInit(); + this.ResumeLayout(false); + } +} diff --git a/HDMA/Configuration/Mode0ChannelPropertyTab.resx b/HDMA/Configuration/Mode0ChannelPropertyTab.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/HDMA/Configuration/Mode0ChannelPropertyTab.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file diff --git a/HDMA/Configuration/Mode2ChannelPropertyTab.cs b/HDMA/Configuration/Mode2ChannelPropertyTab.cs new file mode 100644 index 0000000..35367a9 --- /dev/null +++ b/HDMA/Configuration/Mode2ChannelPropertyTab.cs @@ -0,0 +1,208 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Configuration.Mode2ChannelPropertyTab +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Media; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA.Configuration; + +internal class Mode2ChannelPropertyTab : TabPage +{ + private IContainer components; + private Label chtypeLabel; + private Label destRegLabel; + private NumericUpDown hdmaChannelNumericUpDown; + private Button swapButton; + private ToolTip toolTip; + private ListBox coloursListBox; + private Mode0Channel m_sib; + private ColourChannelsRef m_sibChtype; + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer) new System.ComponentModel.Container(); + this.chtypeLabel = new Label(); + this.destRegLabel = new Label(); + this.hdmaChannelNumericUpDown = new NumericUpDown(); + this.swapButton = new Button(); + this.coloursListBox = new ListBox(); + this.toolTip = new ToolTip(this.components); + Label label1 = new Label(); + Label label2 = new Label(); + Label label3 = new Label(); + Label label4 = new Label(); + TableLayoutPanel tableLayoutPanel = new TableLayoutPanel(); + tableLayoutPanel.SuspendLayout(); + this.hdmaChannelNumericUpDown.BeginInit(); + this.SuspendLayout(); + label1.Anchor = AnchorStyles.Right; + label1.AutoSize = true; + label1.Location = new Point(20, 5); + label1.Name = "label1"; + label1.Size = new Size(76, 13); + label1.TabIndex = 0; + label1.Text = "Channel &Type:"; + label2.Anchor = AnchorStyles.Right; + label2.AutoSize = true; + label2.Location = new Point(40, 29); + label2.Name = "label2"; + label2.Size = new Size(56, 13); + label2.TabIndex = 1; + label2.Text = "&Writes To:"; + label3.Anchor = AnchorStyles.Right; + label3.AutoSize = true; + label3.Location = new Point(3, 53); + label3.Name = "label3"; + label3.Size = new Size(93, 13); + label3.TabIndex = 2; + label3.Text = "&Colour Channel(s):"; + label4.Anchor = AnchorStyles.Right; + label4.AutoSize = true; + label4.Location = new Point(12, 119); + label4.Name = "label4"; + label4.Size = new Size(84, 13); + label4.TabIndex = 3; + label4.Text = "HDMA Cha&nnel:"; + tableLayoutPanel.ColumnCount = 2; + tableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + tableLayoutPanel.Controls.Add((Control) label1, 0, 0); + tableLayoutPanel.Controls.Add((Control) label2, 0, 1); + tableLayoutPanel.Controls.Add((Control) label3, 0, 2); + tableLayoutPanel.Controls.Add((Control) label4, 0, 6); + tableLayoutPanel.Controls.Add((Control) this.chtypeLabel, 1, 0); + tableLayoutPanel.Controls.Add((Control) this.destRegLabel, 1, 1); + tableLayoutPanel.Controls.Add((Control) this.hdmaChannelNumericUpDown, 1, 6); + tableLayoutPanel.Controls.Add((Control) this.swapButton, 1, 4); + tableLayoutPanel.Controls.Add((Control) this.coloursListBox, 1, 2); + tableLayoutPanel.Dock = DockStyle.Fill; + tableLayoutPanel.Location = new Point(0, 0); + tableLayoutPanel.Name = "tableLayoutPanel1"; + tableLayoutPanel.RowCount = 7; + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 24f)); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.Size = new Size(238, 139); + tableLayoutPanel.TabIndex = 0; + this.chtypeLabel.Anchor = AnchorStyles.Left | AnchorStyles.Right; + this.chtypeLabel.BackColor = SystemColors.Control; + this.chtypeLabel.BorderStyle = BorderStyle.Fixed3D; + this.chtypeLabel.Location = new Point(102, 3); + this.chtypeLabel.Margin = new Padding(3); + this.chtypeLabel.Name = "chtypeLabel"; + this.chtypeLabel.Size = new Size(133, 18); + this.chtypeLabel.TabIndex = 4; + this.chtypeLabel.Text = "Transfer Mode 2 HDMA"; + this.chtypeLabel.TextAlign = ContentAlignment.MiddleLeft; + this.destRegLabel.Anchor = AnchorStyles.Left | AnchorStyles.Right; + this.destRegLabel.BackColor = SystemColors.Control; + this.destRegLabel.BorderStyle = BorderStyle.Fixed3D; + this.destRegLabel.Location = new Point(102, 27); + this.destRegLabel.Margin = new Padding(3); + this.destRegLabel.Name = "destRegLabel"; + this.destRegLabel.Size = new Size(133, 18); + this.destRegLabel.TabIndex = 5; + this.destRegLabel.Text = "COLDATA ($2132)"; + this.destRegLabel.TextAlign = ContentAlignment.MiddleLeft; + this.hdmaChannelNumericUpDown.Anchor = AnchorStyles.Left; + this.hdmaChannelNumericUpDown.Location = new Point(102, 116); + this.hdmaChannelNumericUpDown.Maximum = new Decimal(new int[4] + { + 7, + 0, + 0, + 0 + }); + this.hdmaChannelNumericUpDown.Name = "hdmaChannelNumericUpDown"; + this.hdmaChannelNumericUpDown.Size = new Size(50, 20); + this.hdmaChannelNumericUpDown.TabIndex = 6; + this.swapButton.Anchor = AnchorStyles.Left; + this.swapButton.Enabled = false; + this.swapButton.Location = new Point(102, 87); + this.swapButton.Name = "swapButton"; + this.swapButton.Size = new Size(75, 23); + this.swapButton.TabIndex = 7; + this.swapButton.Text = "Swap"; + this.toolTip.SetToolTip((Control) this.swapButton, "Swap the selected colour channel with the independent colour channel."); + this.swapButton.UseVisualStyleBackColor = true; + this.swapButton.Click += new EventHandler(this.swapButton_Click); + this.coloursListBox.Anchor = AnchorStyles.Left | AnchorStyles.Right; + this.coloursListBox.FormattingEnabled = true; + this.coloursListBox.Location = new Point(102, 51); + this.coloursListBox.Name = "coloursListBox"; + tableLayoutPanel.SetRowSpan((Control) this.coloursListBox, 2); + this.coloursListBox.Size = new Size(133, 30); + this.coloursListBox.TabIndex = 8; + this.BackColor = Color.Transparent; + this.Controls.Add((Control) tableLayoutPanel); + this.Size = new Size(238, 139); + this.UseVisualStyleBackColor = true; + tableLayoutPanel.ResumeLayout(false); + tableLayoutPanel.PerformLayout(); + this.hdmaChannelNumericUpDown.EndInit(); + this.ResumeLayout(false); + } + + public Mode2ChannelPropertyTab( + Mode2Channel channel, + Mode0Channel siblingChannel, + ColourChannelsRef siblingChtypeRef) + { + this.InitializeComponent(); + this.coloursListBox.Items.AddRange(new object[2] + { + (object) channel.FirstWriteType, + (object) channel.SecondWriteType + }); + if (siblingChannel != null && siblingChtypeRef != null) + { + this.swapButton.Enabled = true; + this.m_sib = siblingChannel; + this.m_sibChtype = siblingChtypeRef; + } + this.Text = $"{channel.FirstWriteType}, {channel.SecondWriteType}"; + this.hdmaChannelNumericUpDown.Value = (Decimal) channel.HDMAChannel; + } + + private void swapButton_Click(object sender, EventArgs e) + { + if (this.coloursListBox.SelectedIndex < 0) + { + SystemSounds.Beep.Play(); + } + else + { + ChannelType selectedItem = (ChannelType) this.coloursListBox.SelectedItem; + this.coloursListBox.Items[this.coloursListBox.SelectedIndex] = (object) this.m_sibChtype.Value; + this.m_sibChtype.Value = selectedItem; + this.Text = $"{this.coloursListBox.Items[0]}, {this.coloursListBox.Items[1]}"; + } + } + + public void ApplyChanges(Mode2Channel channel) + { + if (this.m_sib != null) + this.m_sib.FirstWriteType = this.m_sibChtype.Value; + channel.FirstWriteType = (ChannelType) this.coloursListBox.Items[0]; + channel.SecondWriteType = (ChannelType) this.coloursListBox.Items[1]; + channel.HDMAChannel = (int) this.hdmaChannelNumericUpDown.Value; + } +} diff --git a/HDMA/Configuration/Mode2ChannelPropertyTab.resx b/HDMA/Configuration/Mode2ChannelPropertyTab.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/HDMA/Configuration/Mode2ChannelPropertyTab.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file diff --git a/HDMA/Configuration/Mode3ChannelPropertyTab.cs b/HDMA/Configuration/Mode3ChannelPropertyTab.cs new file mode 100644 index 0000000..504d387 --- /dev/null +++ b/HDMA/Configuration/Mode3ChannelPropertyTab.cs @@ -0,0 +1,188 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Configuration.Mode3ChannelPropertyTab +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA.Configuration; + +internal class Mode3ChannelPropertyTab : TabPage +{ + private IContainer components; + private Label chtypeLabel; + private Label destRegLabel; + private Label coloursLabel; + private NumericUpDown palIndexNumericUpDown; + private NumericUpDown hdmaChannelNumericUpDown; + + public Mode3ChannelPropertyTab(Mode3Channel channel) + { + this.InitializeComponent(); + this.palIndexNumericUpDown.Value = (Decimal) channel.PaletteIndex; + this.hdmaChannelNumericUpDown.Value = (Decimal) channel.HDMAChannel; + } + + public void ApplyChanges(Mode3Channel channel) + { + channel.PaletteIndex = (byte) this.palIndexNumericUpDown.Value; + channel.HDMAChannel = (int) this.hdmaChannelNumericUpDown.Value; + } + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.chtypeLabel = new Label(); + this.destRegLabel = new Label(); + this.coloursLabel = new Label(); + this.palIndexNumericUpDown = new NumericUpDown(); + this.hdmaChannelNumericUpDown = new NumericUpDown(); + TableLayoutPanel tableLayoutPanel = new TableLayoutPanel(); + Label label1 = new Label(); + Label label2 = new Label(); + Label label3 = new Label(); + Label label4 = new Label(); + Label label5 = new Label(); + tableLayoutPanel.SuspendLayout(); + this.palIndexNumericUpDown.BeginInit(); + this.hdmaChannelNumericUpDown.BeginInit(); + this.SuspendLayout(); + tableLayoutPanel.ColumnCount = 2; + tableLayoutPanel.ColumnStyles.Add(new ColumnStyle()); + tableLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + tableLayoutPanel.Controls.Add((Control) label1, 0, 0); + tableLayoutPanel.Controls.Add((Control) label2, 0, 1); + tableLayoutPanel.Controls.Add((Control) label3, 0, 2); + tableLayoutPanel.Controls.Add((Control) label4, 0, 4); + tableLayoutPanel.Controls.Add((Control) label5, 0, 5); + tableLayoutPanel.Controls.Add((Control) this.chtypeLabel, 1, 0); + tableLayoutPanel.Controls.Add((Control) this.destRegLabel, 1, 1); + tableLayoutPanel.Controls.Add((Control) this.coloursLabel, 1, 2); + tableLayoutPanel.Controls.Add((Control) this.palIndexNumericUpDown, 1, 4); + tableLayoutPanel.Controls.Add((Control) this.hdmaChannelNumericUpDown, 1, 5); + tableLayoutPanel.Dock = DockStyle.Fill; + tableLayoutPanel.Location = new Point(0, 0); + tableLayoutPanel.Name = "tableLayoutPanel1"; + tableLayoutPanel.RowCount = 6; + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.RowStyles.Add(new RowStyle()); + tableLayoutPanel.Size = new Size(286, 124); + tableLayoutPanel.TabIndex = 0; + label1.Anchor = AnchorStyles.Right; + label1.AutoSize = true; + label1.Location = new Point(20, 5); + label1.Name = "label1"; + label1.Size = new Size(76, 13); + label1.TabIndex = 0; + label1.Text = "Channel &Type:"; + label2.Anchor = AnchorStyles.Right; + label2.AutoSize = true; + label2.Location = new Point(40, 29); + label2.Name = "label2"; + label2.Size = new Size(56, 13); + label2.TabIndex = 2; + label2.Text = "&Writes To:"; + label3.Anchor = AnchorStyles.Right; + label3.AutoSize = true; + label3.Location = new Point(3, 53); + label3.Name = "label3"; + label3.Size = new Size(93, 13); + label3.TabIndex = 4; + label3.Text = "&Colour Channel(s):"; + label4.Anchor = AnchorStyles.Right; + label4.AutoSize = true; + label4.Location = new Point(24, 78); + label4.Name = "label4"; + label4.Size = new Size(72, 13); + label4.TabIndex = 6; + label4.Text = "Palette &Index:"; + label5.Anchor = AnchorStyles.Right; + label5.AutoSize = true; + label5.Location = new Point(12, 104); + label5.Name = "label5"; + label5.Size = new Size(84, 13); + label5.TabIndex = 8; + label5.Text = "HDMA Cha&nnel:"; + this.chtypeLabel.AutoEllipsis = true; + this.chtypeLabel.BackColor = SystemColors.Control; + this.chtypeLabel.BorderStyle = BorderStyle.Fixed3D; + this.chtypeLabel.Dock = DockStyle.Fill; + this.chtypeLabel.Location = new Point(102, 3); + this.chtypeLabel.Margin = new Padding(3); + this.chtypeLabel.Name = "chtypeLabel"; + this.chtypeLabel.Size = new Size(181, 18); + this.chtypeLabel.TabIndex = 1; + this.chtypeLabel.Text = "Transfer Mode 3 HDMA"; + this.chtypeLabel.TextAlign = ContentAlignment.MiddleLeft; + this.destRegLabel.AutoEllipsis = true; + this.destRegLabel.BackColor = SystemColors.Control; + this.destRegLabel.BorderStyle = BorderStyle.Fixed3D; + this.destRegLabel.Dock = DockStyle.Fill; + this.destRegLabel.Location = new Point(102, 27); + this.destRegLabel.Margin = new Padding(3); + this.destRegLabel.Name = "destRegLabel"; + this.destRegLabel.Size = new Size(181, 18); + this.destRegLabel.TabIndex = 3; + this.destRegLabel.Text = "CGADD, CGDATA ($2121, $2122)"; + this.destRegLabel.TextAlign = ContentAlignment.MiddleLeft; + this.coloursLabel.AutoEllipsis = true; + this.coloursLabel.BackColor = SystemColors.Control; + this.coloursLabel.BorderStyle = BorderStyle.Fixed3D; + this.coloursLabel.Dock = DockStyle.Fill; + this.coloursLabel.Location = new Point(102, 51); + this.coloursLabel.Margin = new Padding(3); + this.coloursLabel.Name = "coloursLabel"; + this.coloursLabel.Size = new Size(181, 18); + this.coloursLabel.TabIndex = 5; + this.coloursLabel.Text = "Red, Green, Blue"; + this.coloursLabel.TextAlign = ContentAlignment.MiddleLeft; + this.palIndexNumericUpDown.Anchor = AnchorStyles.Left; + this.palIndexNumericUpDown.Hexadecimal = true; + this.palIndexNumericUpDown.Location = new Point(102, 75); + this.palIndexNumericUpDown.Maximum = new Decimal(new int[4] + { + (int) byte.MaxValue, + 0, + 0, + 0 + }); + this.palIndexNumericUpDown.Name = "palIndexNumericUpDown"; + this.palIndexNumericUpDown.Size = new Size(50, 20); + this.palIndexNumericUpDown.TabIndex = 7; + this.hdmaChannelNumericUpDown.Anchor = AnchorStyles.Left; + this.hdmaChannelNumericUpDown.Location = new Point(102, 101); + this.hdmaChannelNumericUpDown.Maximum = new Decimal(new int[4] + { + 7, + 0, + 0, + 0 + }); + this.hdmaChannelNumericUpDown.Name = "hdmaChannelNumericUpDown"; + this.hdmaChannelNumericUpDown.Size = new Size(50, 20); + this.hdmaChannelNumericUpDown.TabIndex = 9; + this.Controls.Add((Control) tableLayoutPanel); + this.Size = new Size(286, 124); + this.UseVisualStyleBackColor = true; + tableLayoutPanel.ResumeLayout(false); + tableLayoutPanel.PerformLayout(); + this.palIndexNumericUpDown.EndInit(); + this.hdmaChannelNumericUpDown.EndInit(); + this.ResumeLayout(false); + } +} diff --git a/HDMA/Configuration/Mode3ChannelPropertyTab.resx b/HDMA/Configuration/Mode3ChannelPropertyTab.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/HDMA/Configuration/Mode3ChannelPropertyTab.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file diff --git a/HDMA/Configuration/UnconfigurablePropertyTab.cs b/HDMA/Configuration/UnconfigurablePropertyTab.cs new file mode 100644 index 0000000..423a099 --- /dev/null +++ b/HDMA/Configuration/UnconfigurablePropertyTab.cs @@ -0,0 +1,34 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Configuration.UnconfigurablePropertyTab +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA.Configuration; + +internal sealed class UnconfigurablePropertyTab : TabPage +{ + private Label m_label; + + public UnconfigurablePropertyTab() + { + Label label = new Label(); + label.AutoEllipsis = true; + label.AutoSize = false; + label.Dock = DockStyle.Fill; + label.Text = "This HDMA gradient cannot be configured."; + this.m_label = label; + this.Padding = new Padding(3); + this.Controls.Add((Control) this.m_label); + this.UseVisualStyleBackColor = true; + } + + public string Message + { + get => this.m_label.Text; + set => this.m_label.Text = value; + } +} diff --git a/HDMA/DataPoint.cs b/HDMA/DataPoint.cs new file mode 100644 index 0000000..4aba55f --- /dev/null +++ b/HDMA/DataPoint.cs @@ -0,0 +1,42 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.DataPoint +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal struct DataPoint : IEquatable +{ + public ushort Data1; + public ushort Data2; + public ushort Data3; + + public static bool operator ==(DataPoint left, DataPoint right) + { + return (int) left.Data1 == (int) right.Data1 && (int) left.Data2 == (int) right.Data2 && (int) left.Data3 == (int) right.Data3; + } + + public static bool operator !=(DataPoint left, DataPoint right) + { + return (int) left.Data1 != (int) right.Data1 || (int) left.Data2 != (int) right.Data2 || (int) left.Data3 != (int) right.Data3; + } + + public override int GetHashCode() => (int) this.Data1 ^ (int) this.Data2 ^ (int) this.Data3; + + public override bool Equals(object obj) + { + switch (obj) + { + case DataPoint dataPoint: + return dataPoint == this; + default: + return false; + } + } + + public bool Equals(DataPoint other) => this == other; +} diff --git a/HDMA/Generator2.cs b/HDMA/Generator2.cs new file mode 100644 index 0000000..2c031df --- /dev/null +++ b/HDMA/Generator2.cs @@ -0,0 +1,500 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Generator2 +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.Collections.Generic; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal static class Generator2 +{ + private const int c_col2 = 5; + private const int REG_43x0 = 17152; + private const int REG_43x2 = 17154; + private const int REG_43x4 = 17156; + private const string c_defaultName = "Gradient"; + + private static ushort ApplyChannelFlag(int n, ChannelType flag) + { + return (ushort) ((ChannelType) n | flag); + } + + private static ushort GetNormalModeDataValue(double r, double g, double b, ChannelType channels) + { + int num1 = 0; + double num2 = 0.0; + bool flag; + if ((flag = channels == ChannelType.Brightness) || channels == ChannelType.Grey) + { + num2 = r + g + b; + num1 = 3; + } + else + { + if ((channels & ChannelType.Red) == ChannelType.Red) + { + num2 += r; + ++num1; + } + if ((channels & ChannelType.Green) == ChannelType.Green) + { + num2 += g; + ++num1; + } + if ((channels & ChannelType.Blue) == ChannelType.Blue) + { + num2 += b; + ++num1; + } + } + return Generator2.ApplyChannelFlag(Generator2.GetV5(num2 / (double) num1, flag ? 15 : 31 /*0x1F*/), channels); + } + + private static int GetV5(double v, int range = 31 /*0x1F*/) + { + return (int) (v.Clamp() * (double) range + 0.5); + } + + private static ushort GetRGBChannelValue(double r, double g, double b) + { + return (ushort) (Generator2.GetV5(r) | Generator2.GetV5(g) << 5 | Generator2.GetV5(b) << 10); + } + + internal static void CreateMode0Table( + double[] chR, + double[] chG, + double[] chB, + ChannelType channels, + DataPoint[] result) + { + for (int index = 0; index < result.Length; ++index) + result[index] = new DataPoint() + { + Data1 = Generator2.GetNormalModeDataValue(chR[index], chG[index], chB[index], channels) + }; + } + + internal static void CreateMode2Table( + double[] chR, + double[] chG, + double[] chB, + ChannelType ch1, + ChannelType ch2, + DataPoint[] result) + { + for (int index = 0; index < result.Length; ++index) + { + double r = chR[index]; + double g = chG[index]; + double b = chB[index]; + result[index] = new DataPoint() + { + Data1 = Generator2.GetNormalModeDataValue(r, g, b, ch1), + Data2 = Generator2.GetNormalModeDataValue(r, g, b, ch2) + }; + } + } + + internal static void CreateScrollingTable( + double[] chR, + double[] chG, + double[] chB, + DataPoint[] result) + { + for (int index = 0; index < result.Length; ++index) + { + double v1 = chR[index]; + double v2 = chG[index]; + double v3 = chB[index]; + result[index] = new DataPoint() + { + Data1 = Generator2.ApplyChannelFlag(Generator2.GetV5(v1), ChannelType.Red), + Data2 = Generator2.ApplyChannelFlag(Generator2.GetV5(v2), ChannelType.Green), + Data3 = Generator2.ApplyChannelFlag(Generator2.GetV5(v3), ChannelType.Blue) + }; + } + } + + internal static void CreateMode1Table( + double[] chR, + double[] chG, + double[] chB, + ushort paletteIndex, + DataPoint[] result) + { + for (int index = 0; index < result.Length; ++index) + { + double r = chR[index]; + double g = chG[index]; + double b = chB[index]; + result[index] = new DataPoint() + { + Data1 = paletteIndex, + Data2 = Generator2.GetRGBChannelValue(r, g, b) + }; + } + } + + private static void DoNormalMode( + ref int srcI, + DataPoint[] src, + List dst, + bool allowCountAbove128) + { + DataPoint dataPoint = src[srcI]; + CompressedDataPoint compressedDataPoint = new CompressedDataPoint(dataPoint); + for (int index = srcI + 1; index < src.Length && src[index] == dataPoint && (allowCountAbove128 && compressedDataPoint.Count < (int) byte.MaxValue || compressedDataPoint.Count < 128 /*0x80*/); ++index) + ++compressedDataPoint.Count; + dst.Add(compressedDataPoint); + srcI += compressedDataPoint.Count; + } + + private static bool CheckForContinuousMode( + ref int srcI, + DataPoint[] src, + List dst) + { + if (srcI + 2 >= src.Length || !(src[srcI] != src[srcI + 1]) || srcI + 3 >= src.Length || !(src[srcI + 1] != src[srcI + 2])) + return false; + CompressedDataPoint compressedDataPoint = new CompressedDataPoint(src[srcI]); + for (int index = srcI + 1; compressedDataPoint.Data.Count < (int) sbyte.MaxValue && index < src.Length; ++index) + { + DataPoint dataPoint = src[index]; + if (index + 2 >= src.Length || dataPoint != src[index + 1]) + compressedDataPoint.Data.Add(dataPoint); + else + break; + } + dst.Add(compressedDataPoint); + srcI += compressedDataPoint.Data.Count; + return true; + } + + private static List CompressTable( + DataPoint[] dataPoints, + bool canUseContinuousMode) + { + List dst = new List(); + int srcI = 0; + while (srcI < dataPoints.Length) + { + if (!canUseContinuousMode || !Generator2.CheckForContinuousMode(ref srcI, dataPoints, dst)) + Generator2.DoNormalMode(ref srcI, dataPoints, dst, false); + } + return dst; + } + + internal static int GetNChannels(GradientChannels channels) + { + switch (channels) + { + case GradientChannels.RedGreenBlue: + return 3; + case GradientChannels.RedGreen: + case GradientChannels.GreenBlue: + case GradientChannels.RedBlue: + case GradientChannels.CyanRed: + case GradientChannels.YellowBlue: + case GradientChannels.MagentaGreen: + return 2; + case GradientChannels.Red: + case GradientChannels.Green: + case GradientChannels.Blue: + case GradientChannels.Cyan: + case GradientChannels.Yellow: + case GradientChannels.Magenta: + case GradientChannels.Grey: + case GradientChannels.Brightness: + return 1; + default: + throw new ArgumentException("Invalid channels."); + } + } + + internal static ChannelType GetChannel(GradientChannels channels, int index) + { + switch (channels) + { + case GradientChannels.RedGreenBlue: + if (index == 0) + return ChannelType.Red; + return index != 1 ? ChannelType.Blue : ChannelType.Green; + case GradientChannels.RedGreen: + return index != 0 ? ChannelType.Green : ChannelType.Red; + case GradientChannels.GreenBlue: + return index != 0 ? ChannelType.Blue : ChannelType.Green; + case GradientChannels.RedBlue: + return index != 0 ? ChannelType.Blue : ChannelType.Red; + case GradientChannels.CyanRed: + return index != 0 ? ChannelType.Red : ChannelType.Cyan; + case GradientChannels.YellowBlue: + return index != 0 ? ChannelType.Blue : ChannelType.Yellow; + case GradientChannels.MagentaGreen: + return index != 0 ? ChannelType.Green : ChannelType.Magenta; + case GradientChannels.Red: + return ChannelType.Red; + case GradientChannels.Green: + return ChannelType.Green; + case GradientChannels.Blue: + return ChannelType.Blue; + case GradientChannels.Cyan: + return ChannelType.Cyan; + case GradientChannels.Yellow: + return ChannelType.Yellow; + case GradientChannels.Magenta: + return ChannelType.Magenta; + case GradientChannels.Grey: + return ChannelType.Grey; + case GradientChannels.Brightness: + return ChannelType.Brightness; + default: + throw new ArgumentException("Invalid channels."); + } + } + + public static void GenerateCode( + double[] rBuffer, + double[] gBuffer, + double[] bBuffer, + Settings2 settings, + CodeGen code) + { + uint size = 0; + List outTable1 = (List) null; + List outTable2 = (List) null; + List outTable3 = (List) null; + DataPoint[] tmpBuffer = new DataPoint[rBuffer.Length]; + Generator2.DoChan(settings.Channel1, rBuffer, gBuffer, bBuffer, tmpBuffer, ref size, ref outTable1); + Generator2.DoChan(settings.Channel2, rBuffer, gBuffer, bBuffer, tmpBuffer, ref size, ref outTable2); + Generator2.DoChan(settings.Channel3, rBuffer, gBuffer, bBuffer, tmpBuffer, ref size, ref outTable3); + code.WriteBanner(); + code.WriteComment(settings.GetGradientTypeBanner()); + code.WriteComment("Channels: " + GradientChannelsHelper.GetChannelString(settings.Channels)); + code.WriteComment("Table Size: " + size.ToString("N0")); + code.WriteComment("No. of Writes: " + rBuffer.Length.ToString("N0")); + code.WriteComment(); + code.WriteComment("Generated by GradientTool"); + code.WriteBanner(); + Generator2.WriteActivator(settings, code); + string gradientName = settings.Name ?? "Gradient"; + Generator2.WriteChan(settings.Channel1, outTable1, code, gradientName); + Generator2.WriteChan(settings.Channel2, outTable2, code, gradientName); + Generator2.WriteChan(settings.Channel3, outTable3, code, gradientName); + } + + private static void DoChan( + Channel chan, + double[] rBuffer, + double[] gBuffer, + double[] bBuffer, + DataPoint[] tmpBuffer, + ref uint size, + ref List outTable) + { + if (chan == null) + return; + chan.GetRawData(rBuffer, gBuffer, bBuffer, tmpBuffer); + outTable = Generator2.CompressTable(tmpBuffer, chan.CanUseContinuousMode); + size += chan.CalculateTableSize((IList) outTable) + 1U; + } + + private static void WriteChan( + Channel chan, + List table, + CodeGen code, + string gradientName) + { + if (chan == null) + return; + code.AppendLine(); + chan.WriteData((IList) table, code, gradientName); + } + + private static void WriteActivator(Settings2 settings, CodeGen code) + { + if (!settings.GenerateInitializationCode) + return; + code.AppendLine(); + if (settings.Channel1 is CombinedChannel) + { + code.WriteComment("GradientTool doesn’t generate the code"); + code.WriteComment("to initialize scrolling gradients."); + code.WriteComment(); + code.WriteComment("See the ASM files in the folder titled"); + code.WriteComment("Example, located in the same folder as"); + code.WriteComment("GradientTool."); + } + else if (settings.Channel1 is Mode3Channel) + Generator2.WriteActivatorInternal(settings, (ushort) 8451, (ushort) 8451, (ushort) 8451, code); + else if (settings.Channel1 is Mode0Channel) + { + ushort num = settings.Channels != GradientChannels.Brightness ? (ushort) 12800 : (ushort) 0; + Generator2.WriteActivatorInternal(settings, num, num, num, code); + } + else if (settings.Channel1 is Mode2Channel) + { + Generator2.WriteActivatorInternal(settings, (ushort) 12802, (ushort) 12800, (ushort) 12800, code); + } + else + { + code.WriteComment("Something went wrong and the type of"); + code.WriteComment("HDMA gradient being generated couldn’t"); + code.WriteComment("be determined."); + } + } + + private static void WriteActivatorInternal( + Settings2 settings, + ushort transferMode0, + ushort transferMode1, + ushort transferMode2, + CodeGen code) + { + string chans = Generator2.GetChans(settings); + code.WriteComment("Set up the HDMA gradient."); + code.WriteComment($"Uses HDMA {chans}{(object) '.'}"); + code.AppendLabel("Init" + (settings.Name ?? "Gradient")); + code.AppendPlainText(':'); + code.AppendLine(); + code.Write16BitMode(5); + code.AppendLine(); + code.WriteComment("Set transfer modes.", (true ? 1 : 0) != 0); + code.WriteLDAIfNonzero(transferMode0, 5); + CodeGen codeGen1 = code; + int num1 = 5; + string chanStr1 = Generator2.GetChanStr(settings.Channel1); + int register1 = (int) Generator2.GetRegister(17152, settings.Channel1); + int num2 = (int) transferMode0; + int w1 = num1; + string comment1 = chanStr1; + codeGen1.WriteSTAIfNonzero((ushort) register1, (ushort) num2, w1, comment1); + if (settings.Channel2 != null) + { + if ((int) transferMode1 != (int) transferMode0) + { + CodeGen codeGen2 = code; + int num3 = 5; + int num4 = (int) transferMode1; + int w2 = num3; + codeGen2.WriteLDAIfNonzero((ushort) num4, w2); + } + CodeGen codeGen3 = code; + int num5 = 5; + string chanStr2 = Generator2.GetChanStr(settings.Channel2); + int register2 = (int) Generator2.GetRegister(17152, settings.Channel2); + int num6 = (int) transferMode1; + int w3 = num5; + string comment2 = chanStr2; + codeGen3.WriteSTAIfNonzero((ushort) register2, (ushort) num6, w3, comment2); + if (settings.Channel3 != null) + { + if ((int) transferMode2 != (int) transferMode1) + { + CodeGen codeGen4 = code; + int num7 = 5; + int num8 = (int) transferMode2; + int w4 = num7; + codeGen4.WriteLDAIfNonzero((ushort) num8, w4); + } + CodeGen codeGen5 = code; + int num9 = 5; + string chanStr3 = Generator2.GetChanStr(settings.Channel3); + int register3 = (int) Generator2.GetRegister(17152, settings.Channel3); + int num10 = (int) transferMode2; + int w5 = num9; + string comment3 = chanStr3; + codeGen5.WriteSTAIfNonzero((ushort) register3, (ushort) num10, w5, comment3); + } + } + code.AppendLine(); + code.WriteComment("Point to HDMA tables.", (true ? 1 : 0) != 0); + Generator2.WriteChanSourceLoader(settings.Channel1, settings.Name, code); + Generator2.WriteChanSourceLoader(settings.Channel2, settings.Name, code); + Generator2.WriteChanSourceLoader(settings.Channel3, settings.Name, code); + code.AppendLine(); + code.Write8BitMode(5); + code.AppendLine(); + code.WriteComment("Store program bank to $43x4.", (true ? 1 : 0) != 0); + code.WriteKeywordLine("PHK"); + code.WriteKeywordLine("PLA"); + Generator2.WriteChanBankLoader(settings.Channel1, code); + Generator2.WriteChanBankLoader(settings.Channel2, code); + Generator2.WriteChanBankLoader(settings.Channel3, code); + code.AppendLine(); + CodeGen codeGen6 = code; + bool flag = true; + string comment4 = $"Enable {chans}{(object) '.'}"; + int num11 = flag ? 1 : 0; + codeGen6.WriteComment(comment4, num11 != 0); + code.WriteLDA_b_c_bin(Generator2.GetHDMAFlags(settings), 5); + code.WriteTSB((ushort) 3487, 5); + code.AppendLine(); + code.AppendHardTab(); + code.AppendKeyword("RTS"); + code.WriteComment("<-- Can also be RTL.", space: (true ? 1 : 0) != 0); + code.AppendLine(); + code.AppendComment("; --- HDMA Tables below this line ---"); + } + + private static string GetChans(Settings2 settings) + { + if (settings.Channel2 == null) + return "channel " + settings.Channel1.HDMAChannel.ToString(); + return settings.Channel3 != null ? $"channels {settings.Channel1.HDMAChannel}, {settings.Channel2.HDMAChannel}, and {settings.Channel3.HDMAChannel}" : $"channels {settings.Channel1.HDMAChannel} and {settings.Channel2.HDMAChannel}"; + } + + private static string GetChanStr(Channel channel) => "Channel " + channel.HDMAChannel.ToString(); + + private static ushort GetRegister(int reg, int channel) => (ushort) (reg | (channel & 7) << 4); + + private static ushort GetRegister(int reg, Channel channel) + { + return (ushort) (reg | (channel.HDMAChannel & 7) << 4); + } + + private static byte GetHDMAFlags(Settings2 settings) + { + int hdmaFlags = 1 << (settings.Channel1.HDMAChannel & 7); + if (settings.Channel2 != null) + { + hdmaFlags |= 1 << (settings.Channel2.HDMAChannel & 7); + if (settings.Channel3 != null) + hdmaFlags |= 1 << (settings.Channel3.HDMAChannel & 7); + } + return (byte) hdmaFlags; + } + + private static void WriteChanSourceLoader(Channel channel, string gradientName, CodeGen code) + { + if (channel == null) + return; + string channelLabel = channel.GetChannelLabel(gradientName ?? "Gradient"); + CodeGen codeGen1 = code; + int num1 = 5; + string label = channelLabel; + int w1 = num1; + codeGen1.WriteLDA_Label(label, w1); + CodeGen codeGen2 = code; + int num2 = 5; + int register = (int) Generator2.GetRegister(17154, channel); + int w2 = num2; + codeGen2.WriteSTA((ushort) register, w2); + } + + private static void WriteChanBankLoader(Channel channel, CodeGen code) + { + if (channel == null) + return; + CodeGen codeGen = code; + int num = 5; + string chanStr = Generator2.GetChanStr(channel); + int register = (int) Generator2.GetRegister(17156, channel); + int w = num; + string comment = chanStr; + codeGen.WriteSTA((ushort) register, w, comment); + } +} diff --git a/HDMA/GradientChannels.cs b/HDMA/GradientChannels.cs new file mode 100644 index 0000000..1979305 --- /dev/null +++ b/HDMA/GradientChannels.cs @@ -0,0 +1,27 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.GradientChannels +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal enum GradientChannels +{ + RedGreenBlue, + RedGreen, + GreenBlue, + RedBlue, + CyanRed, + YellowBlue, + MagentaGreen, + Red, + Green, + Blue, + Cyan, + Yellow, + Magenta, + Grey, + Brightness, +} diff --git a/HDMA/GradientChannelsHelper.cs b/HDMA/GradientChannelsHelper.cs new file mode 100644 index 0000000..e89699a --- /dev/null +++ b/HDMA/GradientChannelsHelper.cs @@ -0,0 +1,35 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.GradientChannelsHelper +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal static class GradientChannelsHelper +{ + private static readonly string[] s_channelNames = new string[15] + { + "Red, Green, Blue", + "Red, Green", + "Green, Blue", + "Red, Blue", + "Cyan, Red", + "Yellow, Blue", + "Magenta, Green", + "Red", + "Green", + "Blue", + "Cyan", + "Yellow", + "Magenta", + "Grey", + "Brightness" + }; + + public static string GetChannelString(GradientChannels channelType) + { + return GradientChannelsHelper.s_channelNames[(int) channelType]; + } +} diff --git a/HDMA/Mode0Channel.cs b/HDMA/Mode0Channel.cs new file mode 100644 index 0000000..a61c5e0 --- /dev/null +++ b/HDMA/Mode0Channel.cs @@ -0,0 +1,84 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Mode0Channel +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA.Configuration; +using System.Collections.Generic; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal sealed class Mode0Channel : Channel +{ + public override bool HasSecondWrite => false; + + public override bool IsBackgroundOrBrightnessHDMA => true; + + public override string ChannelSuffix => this.FirstWriteType.ToString() + "Table"; + + public override uint CalculateTableSize(IList data) + { + uint count = (uint) data.Count; + uint num = 0; + for (int index = 0; (long) index < (long) count; ++index) + num += (uint) data[index].Data.Count; + return count + num; + } + + public override TabPage CreatePropertiesPage( + Mode0Channel sib, + ref ColourChannelsRef channelsReference) + { + if (channelsReference == null) + channelsReference = new ColourChannelsRef(); + Mode0ChannelPropertyTab propertiesPage = new Mode0ChannelPropertyTab(this, channelsReference); + propertiesPage.Text = this.FirstWriteType.ToString(); + return (TabPage) propertiesPage; + } + + public override void ApplySettings(TabPage propertiesPage) + { + ((Mode0ChannelPropertyTab) propertiesPage).ApplyChanges(this); + } + + public override void GetRawData( + double[] rBuffer, + double[] gBuffer, + double[] bBuffer, + DataPoint[] dataBuffer) + { + Generator2.CreateMode0Table(rBuffer, gBuffer, bBuffer, this.FirstWriteType, dataBuffer); + } + + protected override void DoWriteData(IList hdmaTable, CodeGen code) + { + for (int index1 = 0; index1 < hdmaTable.Count; ++index1) + { + CompressedDataPoint compressedDataPoint = hdmaTable[index1]; + if (compressedDataPoint.Data.Count > 0) + { + code.AppendKeyword("db"); + code.AppendSpace(); + if (compressedDataPoint.Data.Count > 1) + { + code.WriteHexAddress((byte) (compressedDataPoint.Data.Count | 128 /*0x80*/)); + for (int index2 = 0; index2 < compressedDataPoint.Data.Count; ++index2) + { + code.AppendPlainText(','); + code.WriteHexAddress((byte) compressedDataPoint.Data[index2].Data1); + } + } + else + { + code.WriteHexAddress((byte) compressedDataPoint.Count); + code.AppendPlainText(','); + code.WriteHexAddress((byte) compressedDataPoint.Data[0].Data1); + } + code.AppendLine(); + } + } + } +} diff --git a/HDMA/Mode2Channel.cs b/HDMA/Mode2Channel.cs new file mode 100644 index 0000000..74c0845 --- /dev/null +++ b/HDMA/Mode2Channel.cs @@ -0,0 +1,89 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Mode2Channel +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA.Configuration; +using System.Collections.Generic; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal sealed class Mode2Channel : Channel +{ + public override bool HasSecondWrite => true; + + public override bool IsBackgroundOrBrightnessHDMA => true; + + public override string ChannelSuffix + { + get => $"{this.FirstWriteType.ToString()}{this.SecondWriteType.ToString()}Table"; + } + + public override uint CalculateTableSize(IList data) + { + uint count = (uint) data.Count; + uint num = 0; + for (int index = 0; (long) index < (long) count; ++index) + num += (uint) (data[index].Data.Count * 2); + return count + num; + } + + public override TabPage CreatePropertiesPage( + Mode0Channel sib, + ref ColourChannelsRef channelsReference) + { + if (channelsReference == null && sib != null) + channelsReference = new ColourChannelsRef(); + return (TabPage) new Mode2ChannelPropertyTab(this, sib, channelsReference); + } + + public override void ApplySettings(TabPage propertiesPage) + { + ((Mode2ChannelPropertyTab) propertiesPage).ApplyChanges(this); + } + + public override void GetRawData( + double[] rBuffer, + double[] gBuffer, + double[] bBuffer, + DataPoint[] dataBuffer) + { + Generator2.CreateMode2Table(rBuffer, gBuffer, bBuffer, this.FirstWriteType, this.SecondWriteType, dataBuffer); + } + + protected override void DoWriteData(IList hdmaTable, CodeGen code) + { + for (int index1 = 0; index1 < hdmaTable.Count; ++index1) + { + CompressedDataPoint compressedDataPoint = hdmaTable[index1]; + if (compressedDataPoint.Data.Count > 0) + { + code.AppendKeyword("db"); + code.AppendSpace(); + if (compressedDataPoint.Data.Count > 1) + { + code.WriteHexAddress((byte) (compressedDataPoint.Data.Count | 128 /*0x80*/)); + for (int index2 = 0; index2 < compressedDataPoint.Data.Count; ++index2) + { + code.AppendPlainText(','); + code.WriteHexAddress((byte) compressedDataPoint.Data[index2].Data1); + code.AppendPlainText(','); + code.WriteHexAddress((byte) compressedDataPoint.Data[index2].Data2); + } + } + else + { + code.WriteHexAddress((byte) compressedDataPoint.Count); + code.AppendPlainText(','); + code.WriteHexAddress((byte) compressedDataPoint.Data[0].Data1); + code.AppendPlainText(','); + code.WriteHexAddress((byte) compressedDataPoint.Data[0].Data2); + } + code.AppendLine(); + } + } + } +} diff --git a/HDMA/Mode3Channel.cs b/HDMA/Mode3Channel.cs new file mode 100644 index 0000000..13e17b4 --- /dev/null +++ b/HDMA/Mode3Channel.cs @@ -0,0 +1,100 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Mode3Channel +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA.Configuration; +using System.Collections.Generic; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal sealed class Mode3Channel : Channel +{ + public byte PaletteIndex { get; set; } + + public override bool HasSecondWrite => false; + + public override bool IsBackgroundOrBrightnessHDMA => false; + + public override string ChannelSuffix => "Table"; + + public override uint CalculateTableSize(IList data) + { + uint count = (uint) data.Count; + uint num = 0; + for (int index = 0; (long) index < (long) count; ++index) + num += (uint) (data[index].Data.Count * 4); + return count + num; + } + + public override TabPage CreatePropertiesPage( + Mode0Channel sib, + ref ColourChannelsRef channelsReference) + { + Mode3ChannelPropertyTab propertiesPage = new Mode3ChannelPropertyTab(this); + propertiesPage.Text = "Channel"; + return (TabPage) propertiesPage; + } + + public override void ApplySettings(TabPage propertiesPage) + { + ((Mode3ChannelPropertyTab) propertiesPage).ApplyChanges(this); + } + + public override void GetRawData( + double[] rBuffer, + double[] gBuffer, + double[] bBuffer, + DataPoint[] dataBuffer) + { + Generator2.CreateMode1Table(rBuffer, gBuffer, bBuffer, (ushort) ((uint) this.PaletteIndex << 8), dataBuffer); + } + + protected override void DoWriteData(IList hdmaTable, CodeGen code) + { + for (int index1 = 0; index1 < hdmaTable.Count; ++index1) + { + CompressedDataPoint compressedDataPoint = hdmaTable[index1]; + if (compressedDataPoint.Data.Count > 0) + { + code.AppendKeyword("db"); + code.AppendSpace(); + if (compressedDataPoint.Data.Count > 1) + { + code.WriteHexAddress((byte) (compressedDataPoint.Data.Count | 128 /*0x80*/)); + code.AppendSpace(); + code.AppendPlainText(':'); + code.AppendSpace(); + code.AppendKeyword("dw"); + code.AppendSpace(); + code.WriteHexAddress(compressedDataPoint.Data[0].Data1); + code.AppendPlainText(','); + code.WriteHexAddress(compressedDataPoint.Data[0].Data2); + for (int index2 = 1; index2 < compressedDataPoint.Data.Count; ++index2) + { + code.AppendPlainText(','); + code.WriteHexAddress(compressedDataPoint.Data[index2].Data1); + code.AppendPlainText(','); + code.WriteHexAddress(compressedDataPoint.Data[index2].Data2); + } + } + else + { + code.WriteHexAddress((byte) compressedDataPoint.Count); + code.AppendSpace(); + code.AppendPlainText(':'); + code.AppendSpace(); + code.AppendKeyword("dw"); + code.AppendSpace(); + code.WriteHexAddress(compressedDataPoint.Data[0].Data1); + code.AppendPlainText(','); + code.WriteHexAddress(compressedDataPoint.Data[0].Data2); + } + code.AppendLine(); + } + } + } +} diff --git a/HDMA/Settings2.cs b/HDMA/Settings2.cs new file mode 100644 index 0000000..84195b9 --- /dev/null +++ b/HDMA/Settings2.cs @@ -0,0 +1,253 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HDMA.Settings2 +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool.HDMA; + +internal struct Settings2 +{ + public const int Mode0AllArrangement = 0; + public const int Mode2Mode0Arrangement = 1; + public const int Mode3Arrangement = 2; + public const int CombinedArrangement = 3; + private int m_arrangement; + private GradientChannels m_channels; + private string m_name; + private Channel m_ch1; + private Channel m_ch2; + private Channel m_ch3; + + public int Arrangement => this.m_arrangement; + + public string GetGradientTypeBanner() + { + switch (this.m_arrangement) + { + case 1: + return this.m_channels != GradientChannels.RedGreenBlue ? "Mode 2 COLDATA Gradient" : "Mode 2 + Mode 0 COLDATA Gradient"; + case 2: + return "Mode 3 CGADD + CGDATA Gradient"; + case 3: + return "Scrolling Gradient"; + default: + return this.m_channels == GradientChannels.Brightness ? "Mode 0 INIDISP Gradient" : "Mode 0 COLDATA Gradient"; + } + } + + public GradientChannels Channels + { + get => this.m_channels; + set + { + if (this.m_channels == value) + return; + if (value == GradientChannels.Brightness) + { + if (this.m_arrangement != 0 && MessageBox.Show("Brightness gradients work with Transfer Mode 0 HDMA channels.\r\nDo you want to change the gradient to use only Transfer Mode 0 channels?", "GradientTool", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) + throw new SilentException(); + this.MakeMode0All(value); + } + else + { + switch (this.m_arrangement) + { + case 0: + this.MakeMode0All(value); + break; + case 1: + this.MakeMode2Mode0(value); + break; + } + } + } + } + + public string Name + { + get => this.m_name; + set + { + value = value.Trim(); + if (value.Length == 0) + value = (string) null; + if (!(this.m_name != value)) + return; + this.m_name = Settings2.ValidateName(value) ? value : throw new ArgumentException("The specified name contains invalid characters.", nameof (value)); + } + } + + public static bool ValidateName(string name) + { + if (name == null) + return true; + bool flag = true; + for (int index = 0; index < name.Length; ++index) + { + char ch = name[index]; + if (ch != '_' && (ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z') && (index <= 0 || ch < '0' || ch > '9')) + flag = false; + } + return flag; + } + + public bool GenerateInitializationCode { get; set; } + + public Channel Channel1 => this.m_ch1; + + public Channel Channel2 => this.m_ch2; + + public Channel Channel3 => this.m_ch3; + + public static Settings2 CreateMode0All(GradientChannels channels, string name = null) + { + Settings2 mode0All = new Settings2(); + mode0All.m_arrangement = 0; + mode0All.m_channels = channels; + mode0All.Name = name; + ref Settings2 local1 = ref mode0All; + Mode0Channel mode0Channel1 = new Mode0Channel(); + mode0Channel1.HDMAChannel = 3; + mode0Channel1.FirstWriteType = Generator2.GetChannel(channels, 0); + Mode0Channel mode0Channel2 = mode0Channel1; + local1.m_ch1 = (Channel) mode0Channel2; + ref Settings2 local2 = ref mode0All; + Mode0Channel mode0Channel3; + if (Generator2.GetNChannels(channels) <= 1) + { + mode0Channel3 = (Mode0Channel) null; + } + else + { + Mode0Channel mode0Channel4 = new Mode0Channel(); + mode0Channel4.HDMAChannel = 4; + mode0Channel4.FirstWriteType = Generator2.GetChannel(channels, 1); + mode0Channel3 = mode0Channel4; + } + local2.m_ch2 = (Channel) mode0Channel3; + ref Settings2 local3 = ref mode0All; + Mode0Channel mode0Channel5; + if (channels != GradientChannels.RedGreenBlue) + { + mode0Channel5 = (Mode0Channel) null; + } + else + { + Mode0Channel mode0Channel6 = new Mode0Channel(); + mode0Channel6.HDMAChannel = 5; + mode0Channel6.FirstWriteType = ChannelType.Blue; + mode0Channel5 = mode0Channel6; + } + local3.m_ch3 = (Channel) mode0Channel5; + return mode0All; + } + + public static Settings2 CreateMode2Mode0(GradientChannels channels, string name = null) + { + if (Generator2.GetNChannels(channels) < 2) + throw new ArgumentException("To generate a Transfer Mode 2 HDMA table, there must be at least two colour channels.", nameof (channels)); + Settings2 mode2Mode0 = new Settings2(); + mode2Mode0.m_arrangement = 1; + mode2Mode0.m_channels = channels; + mode2Mode0.Name = name; + ref Settings2 local1 = ref mode2Mode0; + Mode2Channel mode2Channel1 = new Mode2Channel(); + mode2Channel1.HDMAChannel = 3; + mode2Channel1.FirstWriteType = Generator2.GetChannel(channels, 0); + mode2Channel1.SecondWriteType = Generator2.GetChannel(channels, 1); + Mode2Channel mode2Channel2 = mode2Channel1; + local1.m_ch1 = (Channel) mode2Channel2; + ref Settings2 local2 = ref mode2Mode0; + Mode0Channel mode0Channel1; + if (channels != GradientChannels.RedGreenBlue) + { + mode0Channel1 = (Mode0Channel) null; + } + else + { + Mode0Channel mode0Channel2 = new Mode0Channel(); + mode0Channel2.HDMAChannel = 4; + mode0Channel2.FirstWriteType = ChannelType.Blue; + mode0Channel1 = mode0Channel2; + } + local2.m_ch2 = (Channel) mode0Channel1; + return mode2Mode0; + } + + public static Settings2 CreateMode3(string name = null) + { + Settings2 mode3 = new Settings2(); + mode3.m_arrangement = 2; + mode3.Name = name; + mode3.m_channels = GradientChannels.RedGreenBlue; + ref Settings2 local = ref mode3; + Mode3Channel mode3Channel1 = new Mode3Channel(); + mode3Channel1.HDMAChannel = 3; + Mode3Channel mode3Channel2 = mode3Channel1; + local.m_ch1 = (Channel) mode3Channel2; + return mode3; + } + + public static Settings2 CreateCombined(string name = null) + { + return new Settings2() + { + m_arrangement = 3, + Name = name, + m_channels = GradientChannels.RedGreenBlue, + m_ch1 = (Channel) new CombinedChannel() + }; + } + + public void MakeMode0All(GradientChannels channels) + { + bool initializationCode = this.GenerateInitializationCode; + int hdmaChannel = this.m_ch1.HDMAChannel; + int num1 = this.m_ch2 != null ? this.m_ch2.HDMAChannel : 4; + int num2 = this.m_ch3 != null ? this.m_ch3.HDMAChannel : 5; + this = Settings2.CreateMode0All(channels, this.Name); + this.GenerateInitializationCode = initializationCode; + this.m_ch1.HDMAChannel = hdmaChannel; + if (this.m_ch2 != null) + this.m_ch2.HDMAChannel = num1; + if (this.m_ch3 == null) + return; + this.m_ch3.HDMAChannel = num2; + } + + public void MakeMode2Mode0(GradientChannels channels) + { + bool initializationCode = this.GenerateInitializationCode; + int hdmaChannel = this.m_ch1.HDMAChannel; + int num = this.m_ch2 != null ? this.m_ch2.HDMAChannel : 4; + this = Settings2.CreateMode2Mode0(channels, this.Name); + this.GenerateInitializationCode = initializationCode; + this.m_ch1.HDMAChannel = hdmaChannel; + if (this.m_ch2 == null) + return; + this.m_ch2.HDMAChannel = num; + } + + public void MakeMode3() + { + bool initializationCode = this.GenerateInitializationCode; + int hdmaChannel = this.m_ch1.HDMAChannel; + this = Settings2.CreateMode3(this.Name); + this.GenerateInitializationCode = initializationCode; + this.m_ch1.HDMAChannel = hdmaChannel; + } + + public void MakeCombined() + { + bool initializationCode = this.GenerateInitializationCode; + int hdmaChannel = this.m_ch1.HDMAChannel; + this = Settings2.CreateCombined(this.Name); + this.GenerateInitializationCode = initializationCode; + this.m_ch1.HDMAChannel = hdmaChannel; + } +} diff --git a/HermiteConfiguration.cs b/HermiteConfiguration.cs new file mode 100644 index 0000000..aa5036e --- /dev/null +++ b/HermiteConfiguration.cs @@ -0,0 +1,178 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HermiteConfiguration +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal class HermiteConfiguration : Form +{ + private IContainer components; + private TableLayoutPanel tableLayoutPanel1; + private Label label1; + private Label label2; + private Button closeButton; + private NumericUpDown biasNumericUpDown; + private NumericUpDown tensionTumericUpDown; + private Action m_updater; + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.tableLayoutPanel1 = new TableLayoutPanel(); + this.label1 = new Label(); + this.label2 = new Label(); + this.biasNumericUpDown = new NumericUpDown(); + this.tensionTumericUpDown = new NumericUpDown(); + this.closeButton = new Button(); + this.tableLayoutPanel1.SuspendLayout(); + this.biasNumericUpDown.BeginInit(); + this.tensionTumericUpDown.BeginInit(); + this.SuspendLayout(); + this.tableLayoutPanel1.ColumnCount = 2; + this.tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle()); + this.tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100f)); + this.tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20f)); + this.tableLayoutPanel1.Controls.Add((Control) this.label1, 0, 0); + this.tableLayoutPanel1.Controls.Add((Control) this.label2, 0, 1); + this.tableLayoutPanel1.Controls.Add((Control) this.biasNumericUpDown, 1, 0); + this.tableLayoutPanel1.Controls.Add((Control) this.tensionTumericUpDown, 1, 1); + this.tableLayoutPanel1.Controls.Add((Control) this.closeButton, 0, 3); + this.tableLayoutPanel1.Dock = DockStyle.Fill; + this.tableLayoutPanel1.Location = new Point(9, 9); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 4; + this.tableLayoutPanel1.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100f)); + this.tableLayoutPanel1.RowStyles.Add(new RowStyle()); + this.tableLayoutPanel1.Size = new Size(160 /*0xA0*/, 87); + this.tableLayoutPanel1.TabIndex = 0; + this.label1.Anchor = AnchorStyles.Right; + this.label1.AutoSize = true; + this.label1.Location = new Point(21, 6); + this.label1.Name = "label1"; + this.label1.Size = new Size(30, 13); + this.label1.TabIndex = 0; + this.label1.Text = "Bias:"; + this.label2.Anchor = AnchorStyles.Right; + this.label2.AutoSize = true; + this.label2.Location = new Point(3, 32 /*0x20*/); + this.label2.Name = "label2"; + this.label2.Size = new Size(48 /*0x30*/, 13); + this.label2.TabIndex = 1; + this.label2.Text = "Tension:"; + this.biasNumericUpDown.Anchor = AnchorStyles.Left | AnchorStyles.Right; + this.biasNumericUpDown.DecimalPlaces = 3; + this.biasNumericUpDown.Increment = new Decimal(new int[4] + { + 5, + 0, + 0, + 65536 /*0x010000*/ + }); + this.biasNumericUpDown.Location = new Point(57, 3); + this.biasNumericUpDown.Maximum = new Decimal(new int[4] + { + 20, + 0, + 0, + 0 + }); + this.biasNumericUpDown.Minimum = new Decimal(new int[4] + { + 20, + 0, + 0, + int.MinValue + }); + this.biasNumericUpDown.Name = "biasNumericUpDown"; + this.biasNumericUpDown.Size = new Size(100, 20); + this.biasNumericUpDown.TabIndex = 4; + this.biasNumericUpDown.ValueChanged += new EventHandler(this.biasNumericUpDown_ValueChanged); + this.tensionTumericUpDown.Anchor = AnchorStyles.Left | AnchorStyles.Right; + this.tensionTumericUpDown.DecimalPlaces = 3; + this.tensionTumericUpDown.Increment = new Decimal(new int[4] + { + 5, + 0, + 0, + 65536 /*0x010000*/ + }); + this.tensionTumericUpDown.Location = new Point(57, 29); + this.tensionTumericUpDown.Minimum = new Decimal(new int[4] + { + 100, + 0, + 0, + int.MinValue + }); + this.tensionTumericUpDown.Name = "tensionTumericUpDown"; + this.tensionTumericUpDown.Size = new Size(100, 20); + this.tensionTumericUpDown.TabIndex = 5; + this.tensionTumericUpDown.ValueChanged += new EventHandler(this.tensionTumericUpDown_ValueChanged); + this.closeButton.Anchor = AnchorStyles.Right; + this.tableLayoutPanel1.SetColumnSpan((Control) this.closeButton, 2); + this.closeButton.DialogResult = DialogResult.Cancel; + this.closeButton.Location = new Point(82, 61); + this.closeButton.Name = "closeButton"; + this.closeButton.Size = new Size(75, 23); + this.closeButton.TabIndex = 2; + this.closeButton.Text = "&Close"; + this.closeButton.UseVisualStyleBackColor = true; + this.AcceptButton = (IButtonControl) this.closeButton; + this.AutoScaleDimensions = new SizeF(6f, 13f); + this.AutoScaleMode = AutoScaleMode.Font; + this.CancelButton = (IButtonControl) this.closeButton; + this.ClientSize = new Size(178, 105); + this.Controls.Add((Control) this.tableLayoutPanel1); + this.FormBorderStyle = FormBorderStyle.FixedDialog; + this.MaximizeBox = false; + this.MinimizeBox = false; + this.Name = nameof (HermiteConfiguration); + this.Padding = new Padding(9); + this.Text = "Interpolation Settings"; + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); + this.biasNumericUpDown.EndInit(); + this.tensionTumericUpDown.EndInit(); + this.ResumeLayout(false); + } + + public HermiteConfiguration(Action updatedCallback) + { + this.InitializeComponent(); + this.biasNumericUpDown.Value = (Decimal) (HermiteSettings.Bias * 10.0); + this.tensionTumericUpDown.Value = (Decimal) (HermiteSettings.Tension * 10.0); + this.m_updater = updatedCallback; + } + + private void biasNumericUpDown_ValueChanged(object sender, EventArgs e) + { + HermiteSettings.Bias = (double) (this.biasNumericUpDown.Value / 10M); + if (this.m_updater == null) + return; + this.m_updater(); + } + + private void tensionTumericUpDown_ValueChanged(object sender, EventArgs e) + { + HermiteSettings.Tension = (double) (this.tensionTumericUpDown.Value / 10M); + if (this.m_updater == null) + return; + this.m_updater(); + } +} diff --git a/HermiteConfiguration.resx b/HermiteConfiguration.resx new file mode 100644 index 0000000..d58980a --- /dev/null +++ b/HermiteConfiguration.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + \ No newline at end of file diff --git a/HermiteSettings.cs b/HermiteSettings.cs new file mode 100644 index 0000000..255501b --- /dev/null +++ b/HermiteSettings.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.HermiteSettings +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +#nullable disable +namespace SFXProductions.GradientTool; + +internal static class HermiteSettings +{ + public static double Tension; + public static double Bias; +} diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..e274ee7 --- /dev/null +++ b/Program.cs @@ -0,0 +1,1257 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.Program +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA; +using SFXProductions.GradientTool.Properties; +using System; +using System.Collections; +using System.ComponentModel; +using System.Drawing; +using System.Globalization; +using System.IO; +using System.Media; +using System.Text; +using System.Windows.Forms; +using System.Windows.Forms.Layout; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal class Program : Form +{ + private IContainer components; + private ToolStrip toolStrip1; + private ToolStripButton generateToolStripButton; + private ToolStripButton saveToolStripButton; + private ToolStripButton aboutToolStripButton; + private ToolStripDropDownButton typeToolStripDropDownButton; + private ToolStripDropDownButton colourspaceToolStripDropDownButton; + private ToolStripDropDownButton channelsToolStripDropDownButton; + private ToolStripMenuItem rgbToolStripMenuItem; + private ToolStripMenuItem hsvToolStripMenuItem; + private ToolStripMenuItem hslToolStripMenuItem; + private ToolStripMenuItem redGreenBlueToolStripMenuItem; + private ToolStripMenuItem yellowBlueToolStripMenuItem; + private ToolStripMenuItem redCyanToolStripMenuItem; + private ToolStripMenuItem magentaGreenToolStripMenuItem; + private ToolStripMenuItem redGreenToolStripMenuItem; + private ToolStripMenuItem redBlueToolStripMenuItem; + private ToolStripMenuItem greenBlueToolStripMenuItem; + private ToolStripMenuItem greyToolStripMenuItem; + private ToolStripMenuItem redToolStripMenuItem; + private ToolStripMenuItem greenToolStripMenuItem; + private ToolStripMenuItem blueToolStripMenuItem; + private ToolStripMenuItem cyanToolStripMenuItem; + private ToolStripMenuItem yellowToolStripMenuItem; + private ToolStripMenuItem magentaToolStripMenuItem; + private RichTextBox richTextBox1; + private ContextMenuStrip viewerContextMenuStrip; + private ToolStripMenuItem copyToolStripMenuItem; + private ToolStripSeparator toolStripSeparator9; + private ToolStripMenuItem selectAllToolStripMenuItem; + private ToolStripButton exportImgToolStripButton; + private Panel panel2; + private ToolStripDropDownButton zoomToolStripDropDownButton; + private ToolStripMenuItem x1ToolStripMenuItem; + private ToolStripMenuItem x2ToolStripMenuItem; + private ToolStripMenuItem x3ToolStripMenuItem; + private ToolStripMenuItem x4ToolStripMenuItem; + private ToolStripMenuItem x6ToolStripMenuItem; + private ToolStripMenuItem x8ToolStripMenuItem; + private ToolStripMenuItem x10ToolStripMenuItem; + private ToolStripMenuItem fitToWindowToolStripMenuItem; + private GradientControl gradientControl1; + private ToolStripMenuItem hsyToolStripMenuItem; + private ToolStripSplitButton configToolStripSplitButton; + private ToolStripTextBox nWritesToolStripTextBox; + private ToolStripTextBox gradientNameToolStripTextBox; + private ToolStripMenuItem linearToolStripMenuItem; + private ToolStripMenuItem circularToolStripMenuItem; + private ToolStripSeparator toolStripSeparator14; + private ToolStripMenuItem generateInitializationCodeToolStripMenuItem; + private ToolStripMenuItem configureChannelSetupToolStripMenuItem; + private ToolStripMenuItem brightnessToolStripMenuItem; + private ToolStripMenuItem cubicToolStripMenuItem; + private StatusStrip statusStrip1; + private ToolStripMenuItem gradientTypeToolStripMenuItem; + private ToolStripMenuItem mode0ToolStripMenuItem; + private ToolStripMenuItem mode2ToolStripMenuItem; + private ToolStripSeparator toolStripSeparator16; + private ToolStripMenuItem scrollableGradientToolStripMenuItem; + private ToolStripMenuItem writeToPaletteToolStripMenuItem; + private ToolStripTextBox paletteIndexToolStripTextBox; + private ToolStripMenuItem catmullRomToolStripMenuItem; + private ToolStripSeparator toolStripSeparator17; + private ToolStripMenuItem hermiteToolStripMenuItem; + private ToolStripMenuItem configureToolStripMenuItem; + private ToolStripSeparator toolStripSeparator18; + private ToolStripMenuItem showGridToolStripMenuItem; + private ToolStripMenuItem rgbvToolStripMenuItem; + private ToolStripMenuItem rgblToolStripMenuItem; + private ToolStripMenuItem rgbbToolStripMenuItem; + private string m_asm; + private int m_zoom; + private bool m_dirty = true; + + protected override void Dispose(bool disposing) + { + if (disposing && this.components != null) + this.components.Dispose(); + base.Dispose(disposing); + } + + private void InitializeComponent() + { + this.components = (IContainer) new System.ComponentModel.Container(); + ComponentResourceManager componentResourceManager = new ComponentResourceManager(typeof (Program)); + this.toolStrip1 = new ToolStrip(); + this.typeToolStripDropDownButton = new ToolStripDropDownButton(); + this.linearToolStripMenuItem = new ToolStripMenuItem(); + this.circularToolStripMenuItem = new ToolStripMenuItem(); + this.cubicToolStripMenuItem = new ToolStripMenuItem(); + this.catmullRomToolStripMenuItem = new ToolStripMenuItem(); + this.hermiteToolStripMenuItem = new ToolStripMenuItem(); + this.toolStripSeparator17 = new ToolStripSeparator(); + this.configureToolStripMenuItem = new ToolStripMenuItem(); + this.colourspaceToolStripDropDownButton = new ToolStripDropDownButton(); + this.rgbToolStripMenuItem = new ToolStripMenuItem(); + this.rgbvToolStripMenuItem = new ToolStripMenuItem(); + this.rgbbToolStripMenuItem = new ToolStripMenuItem(); + this.rgblToolStripMenuItem = new ToolStripMenuItem(); + this.hsvToolStripMenuItem = new ToolStripMenuItem(); + this.hslToolStripMenuItem = new ToolStripMenuItem(); + this.hsyToolStripMenuItem = new ToolStripMenuItem(); + this.channelsToolStripDropDownButton = new ToolStripDropDownButton(); + this.redGreenBlueToolStripMenuItem = new ToolStripMenuItem(); + this.redCyanToolStripMenuItem = new ToolStripMenuItem(); + this.yellowBlueToolStripMenuItem = new ToolStripMenuItem(); + this.magentaGreenToolStripMenuItem = new ToolStripMenuItem(); + this.redBlueToolStripMenuItem = new ToolStripMenuItem(); + this.redGreenToolStripMenuItem = new ToolStripMenuItem(); + this.greenBlueToolStripMenuItem = new ToolStripMenuItem(); + this.redToolStripMenuItem = new ToolStripMenuItem(); + this.greenToolStripMenuItem = new ToolStripMenuItem(); + this.blueToolStripMenuItem = new ToolStripMenuItem(); + this.cyanToolStripMenuItem = new ToolStripMenuItem(); + this.yellowToolStripMenuItem = new ToolStripMenuItem(); + this.magentaToolStripMenuItem = new ToolStripMenuItem(); + this.brightnessToolStripMenuItem = new ToolStripMenuItem(); + this.greyToolStripMenuItem = new ToolStripMenuItem(); + this.zoomToolStripDropDownButton = new ToolStripDropDownButton(); + this.x1ToolStripMenuItem = new ToolStripMenuItem(); + this.fitToWindowToolStripMenuItem = new ToolStripMenuItem(); + this.x2ToolStripMenuItem = new ToolStripMenuItem(); + this.x3ToolStripMenuItem = new ToolStripMenuItem(); + this.x4ToolStripMenuItem = new ToolStripMenuItem(); + this.x6ToolStripMenuItem = new ToolStripMenuItem(); + this.x8ToolStripMenuItem = new ToolStripMenuItem(); + this.x10ToolStripMenuItem = new ToolStripMenuItem(); + this.toolStripSeparator18 = new ToolStripSeparator(); + this.showGridToolStripMenuItem = new ToolStripMenuItem(); + this.configToolStripSplitButton = new ToolStripSplitButton(); + this.nWritesToolStripTextBox = new ToolStripTextBox(); + this.gradientNameToolStripTextBox = new ToolStripTextBox(); + this.gradientTypeToolStripMenuItem = new ToolStripMenuItem(); + this.mode0ToolStripMenuItem = new ToolStripMenuItem(); + this.mode2ToolStripMenuItem = new ToolStripMenuItem(); + this.toolStripSeparator16 = new ToolStripSeparator(); + this.scrollableGradientToolStripMenuItem = new ToolStripMenuItem(); + this.writeToPaletteToolStripMenuItem = new ToolStripMenuItem(); + this.paletteIndexToolStripTextBox = new ToolStripTextBox(); + this.toolStripSeparator14 = new ToolStripSeparator(); + this.generateInitializationCodeToolStripMenuItem = new ToolStripMenuItem(); + this.configureChannelSetupToolStripMenuItem = new ToolStripMenuItem(); + this.generateToolStripButton = new ToolStripButton(); + this.exportImgToolStripButton = new ToolStripButton(); + this.saveToolStripButton = new ToolStripButton(); + this.aboutToolStripButton = new ToolStripButton(); + this.richTextBox1 = new RichTextBox(); + this.viewerContextMenuStrip = new ContextMenuStrip(this.components); + this.copyToolStripMenuItem = new ToolStripMenuItem(); + this.toolStripSeparator9 = new ToolStripSeparator(); + this.selectAllToolStripMenuItem = new ToolStripMenuItem(); + this.panel2 = new Panel(); + this.statusStrip1 = new StatusStrip(); + this.gradientControl1 = new GradientControl(); + ToolStripSeparator toolStripSeparator1 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator2 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator3 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator4 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator5 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator6 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator7 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator8 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator9 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator10 = new ToolStripSeparator(); + ToolStripLabel toolStripLabel1 = new ToolStripLabel(); + ToolStripSeparator toolStripSeparator11 = new ToolStripSeparator(); + ToolStripLabel toolStripLabel2 = new ToolStripLabel(); + ToolStripSeparator toolStripSeparator12 = new ToolStripSeparator(); + ToolStripSeparator toolStripSeparator13 = new ToolStripSeparator(); + ToolStripLabel toolStripLabel3 = new ToolStripLabel(); + ToolStripLabel toolStripLabel4 = new ToolStripLabel(); + this.toolStrip1.SuspendLayout(); + this.viewerContextMenuStrip.SuspendLayout(); + this.panel2.SuspendLayout(); + this.SuspendLayout(); + toolStripSeparator1.Name = "toolStripSeparator5"; + toolStripSeparator1.Size = new Size(6, 25); + toolStripSeparator2.Name = "toolStripSeparator6"; + toolStripSeparator2.Size = new Size(6, 25); + toolStripSeparator3.Name = "toolStripSeparator4"; + toolStripSeparator3.Size = new Size(153, 6); + toolStripSeparator4.Name = "toolStripSeparator1"; + toolStripSeparator4.Size = new Size(219, 6); + toolStripSeparator5.Name = "toolStripSeparator2"; + toolStripSeparator5.Size = new Size(153, 6); + toolStripSeparator6.Name = "toolStripSeparator3"; + toolStripSeparator6.Size = new Size(153, 6); + toolStripSeparator7.Name = "toolStripSeparator7"; + toolStripSeparator7.Size = new Size(153, 6); + toolStripSeparator8.Name = "toolStripSeparator8"; + toolStripSeparator8.Size = new Size(153, 6); + toolStripSeparator9.Name = "toolStripSeparator12"; + toolStripSeparator9.Size = new Size(137, 6); + toolStripSeparator10.Name = "toolStripSeparator10"; + toolStripSeparator10.Size = new Size(6, 25); + toolStripLabel1.Font = new Font("Tahoma", 8.25f, FontStyle.Bold); + toolStripLabel1.Name = "toolStripLabel1"; + toolStripLabel1.Size = new Size(94, 13); + toolStripLabel1.Text = "Gradient Name:"; + toolStripSeparator11.Name = "toolStripSeparator11"; + toolStripSeparator11.Size = new Size(204, 6); + toolStripLabel2.Font = new Font("Tahoma", 8.25f, FontStyle.Bold); + toolStripLabel2.Name = "toolStripLabel2"; + toolStripLabel2.Size = new Size(78, 13); + toolStripLabel2.Text = "№ of Writes:"; + toolStripSeparator12.Name = "toolStripSeparator13"; + toolStripSeparator12.Size = new Size(6, 25); + toolStripSeparator13.Name = "toolStripSeparator15"; + toolStripSeparator13.Size = new Size(204, 6); + toolStripLabel3.Font = new Font("Tahoma", 8.25f, FontStyle.Bold); + toolStripLabel3.Name = "toolStripLabel3"; + toolStripLabel3.Size = new Size(35, 13); + toolStripLabel3.Text = "Misc."; + toolStripLabel4.Font = new Font("Tahoma", 8.25f, FontStyle.Bold); + toolStripLabel4.Name = "toolStripLabel4"; + toolStripLabel4.Size = new Size(57, 13); + toolStripLabel4.Text = "Common"; + this.toolStrip1.GripStyle = ToolStripGripStyle.Hidden; + this.toolStrip1.Items.AddRange(new ToolStripItem[13] + { + (ToolStripItem) this.typeToolStripDropDownButton, + (ToolStripItem) this.colourspaceToolStripDropDownButton, + (ToolStripItem) this.channelsToolStripDropDownButton, + (ToolStripItem) toolStripSeparator1, + (ToolStripItem) this.zoomToolStripDropDownButton, + (ToolStripItem) toolStripSeparator12, + (ToolStripItem) this.configToolStripSplitButton, + (ToolStripItem) this.generateToolStripButton, + (ToolStripItem) toolStripSeparator10, + (ToolStripItem) this.exportImgToolStripButton, + (ToolStripItem) this.saveToolStripButton, + (ToolStripItem) toolStripSeparator2, + (ToolStripItem) this.aboutToolStripButton + }); + this.toolStrip1.Location = new Point(0, 0); + this.toolStrip1.Name = "toolStrip1"; + this.toolStrip1.Size = new Size(488, 25); + this.toolStrip1.TabIndex = 0; + this.toolStrip1.Text = "toolStrip1"; + this.typeToolStripDropDownButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + this.typeToolStripDropDownButton.DropDownItems.AddRange(new ToolStripItem[7] + { + (ToolStripItem) this.linearToolStripMenuItem, + (ToolStripItem) this.circularToolStripMenuItem, + (ToolStripItem) this.cubicToolStripMenuItem, + (ToolStripItem) this.catmullRomToolStripMenuItem, + (ToolStripItem) this.hermiteToolStripMenuItem, + (ToolStripItem) this.toolStripSeparator17, + (ToolStripItem) this.configureToolStripMenuItem + }); + this.typeToolStripDropDownButton.Image = (Image) Resources.layer_shape_curve; + this.typeToolStripDropDownButton.Name = "typeToolStripDropDownButton"; + this.typeToolStripDropDownButton.Size = new Size(29, 22); + this.typeToolStripDropDownButton.Text = "Gradient Interpolation"; + this.linearToolStripMenuItem.Checked = true; + this.linearToolStripMenuItem.CheckState = CheckState.Checked; + this.linearToolStripMenuItem.Name = "linearToolStripMenuItem"; + this.linearToolStripMenuItem.Size = new Size(165, 22); + this.linearToolStripMenuItem.Text = "Linear"; + this.linearToolStripMenuItem.Click += new EventHandler(this.InterpolationGroupChanged); + this.circularToolStripMenuItem.Name = "circularToolStripMenuItem"; + this.circularToolStripMenuItem.Size = new Size(165, 22); + this.circularToolStripMenuItem.Text = "Smooth"; + this.circularToolStripMenuItem.Click += new EventHandler(this.InterpolationGroupChanged); + this.cubicToolStripMenuItem.Name = "cubicToolStripMenuItem"; + this.cubicToolStripMenuItem.Size = new Size(165, 22); + this.cubicToolStripMenuItem.Text = "Cubic"; + this.cubicToolStripMenuItem.Click += new EventHandler(this.InterpolationGroupChanged); + this.catmullRomToolStripMenuItem.Name = "catmullRomToolStripMenuItem"; + this.catmullRomToolStripMenuItem.Size = new Size(165, 22); + this.catmullRomToolStripMenuItem.Text = "Catmull-Rom"; + this.catmullRomToolStripMenuItem.Click += new EventHandler(this.InterpolationGroupChanged); + this.hermiteToolStripMenuItem.Name = "hermiteToolStripMenuItem"; + this.hermiteToolStripMenuItem.Size = new Size(165, 22); + this.hermiteToolStripMenuItem.Text = "Hermite"; + this.hermiteToolStripMenuItem.Click += new EventHandler(this.InterpolationGroupChanged); + this.toolStripSeparator17.Name = "toolStripSeparator17"; + this.toolStripSeparator17.Size = new Size(162, 6); + this.configureToolStripMenuItem.Name = "configureToolStripMenuItem"; + this.configureToolStripMenuItem.Size = new Size(165, 22); + this.configureToolStripMenuItem.Text = "Hermite Settings..."; + this.configureToolStripMenuItem.Click += new EventHandler(this.configureToolStripMenuItem_Click); + this.colourspaceToolStripDropDownButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + this.colourspaceToolStripDropDownButton.DropDownItems.AddRange(new ToolStripItem[8] + { + (ToolStripItem) this.rgbToolStripMenuItem, + (ToolStripItem) this.rgbvToolStripMenuItem, + (ToolStripItem) this.rgbbToolStripMenuItem, + (ToolStripItem) this.rgblToolStripMenuItem, + (ToolStripItem) toolStripSeparator4, + (ToolStripItem) this.hsvToolStripMenuItem, + (ToolStripItem) this.hslToolStripMenuItem, + (ToolStripItem) this.hsyToolStripMenuItem + }); + this.colourspaceToolStripDropDownButton.Image = (Image) Resources.color; + this.colourspaceToolStripDropDownButton.Name = "colourspaceToolStripDropDownButton"; + this.colourspaceToolStripDropDownButton.Size = new Size(29, 22); + this.colourspaceToolStripDropDownButton.Text = "Gradient Colourspace"; + this.rgbToolStripMenuItem.Name = "rgbToolStripMenuItem"; + this.rgbToolStripMenuItem.Size = new Size(222, 22); + this.rgbToolStripMenuItem.Text = "Red / Green / Blue"; + this.rgbToolStripMenuItem.Click += new EventHandler(this.ColourspaceGroupChanged); + this.rgbvToolStripMenuItem.Checked = true; + this.rgbvToolStripMenuItem.CheckState = CheckState.Checked; + this.rgbvToolStripMenuItem.Name = "rgbvToolStripMenuItem"; + this.rgbvToolStripMenuItem.Size = new Size(222, 22); + this.rgbvToolStripMenuItem.Text = "Red / Green / Blue / Value"; + this.rgbvToolStripMenuItem.Click += new EventHandler(this.ColourspaceGroupChanged); + this.rgbbToolStripMenuItem.Name = "rgbbToolStripMenuItem"; + this.rgbbToolStripMenuItem.Size = new Size(222, 22); + this.rgbbToolStripMenuItem.Text = "Red / Green / Blue / Brightness"; + this.rgbbToolStripMenuItem.Visible = false; + this.rgbbToolStripMenuItem.Click += new EventHandler(this.ColourspaceGroupChanged); + this.rgblToolStripMenuItem.Name = "rgblToolStripMenuItem"; + this.rgblToolStripMenuItem.Size = new Size(222, 22); + this.rgblToolStripMenuItem.Text = "Red / Green / Blue / Lightness"; + this.rgblToolStripMenuItem.Click += new EventHandler(this.ColourspaceGroupChanged); + this.hsvToolStripMenuItem.Name = "hsvToolStripMenuItem"; + this.hsvToolStripMenuItem.Size = new Size(222, 22); + this.hsvToolStripMenuItem.Text = "Hue / Saturation / Value"; + this.hsvToolStripMenuItem.Click += new EventHandler(this.ColourspaceGroupChanged); + this.hslToolStripMenuItem.Name = "hslToolStripMenuItem"; + this.hslToolStripMenuItem.Size = new Size(222, 22); + this.hslToolStripMenuItem.Text = "Hue / Saturation / Lightness"; + this.hslToolStripMenuItem.Click += new EventHandler(this.ColourspaceGroupChanged); + this.hsyToolStripMenuItem.Name = "hsyToolStripMenuItem"; + this.hsyToolStripMenuItem.Size = new Size(222, 22); + this.hsyToolStripMenuItem.Text = "Hue / Saturation / Luminance"; + this.hsyToolStripMenuItem.Visible = false; + this.hsyToolStripMenuItem.Click += new EventHandler(this.ColourspaceGroupChanged); + this.channelsToolStripDropDownButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + this.channelsToolStripDropDownButton.DropDownItems.AddRange(new ToolStripItem[20] + { + (ToolStripItem) this.redGreenBlueToolStripMenuItem, + (ToolStripItem) toolStripSeparator5, + (ToolStripItem) this.redCyanToolStripMenuItem, + (ToolStripItem) this.yellowBlueToolStripMenuItem, + (ToolStripItem) this.magentaGreenToolStripMenuItem, + (ToolStripItem) toolStripSeparator6, + (ToolStripItem) this.redBlueToolStripMenuItem, + (ToolStripItem) this.redGreenToolStripMenuItem, + (ToolStripItem) this.greenBlueToolStripMenuItem, + (ToolStripItem) toolStripSeparator3, + (ToolStripItem) this.redToolStripMenuItem, + (ToolStripItem) this.greenToolStripMenuItem, + (ToolStripItem) this.blueToolStripMenuItem, + (ToolStripItem) toolStripSeparator7, + (ToolStripItem) this.cyanToolStripMenuItem, + (ToolStripItem) this.yellowToolStripMenuItem, + (ToolStripItem) this.magentaToolStripMenuItem, + (ToolStripItem) toolStripSeparator8, + (ToolStripItem) this.brightnessToolStripMenuItem, + (ToolStripItem) this.greyToolStripMenuItem + }); + this.channelsToolStripDropDownButton.Image = (Image) Resources.block; + this.channelsToolStripDropDownButton.Name = "channelsToolStripDropDownButton"; + this.channelsToolStripDropDownButton.Size = new Size(29, 22); + this.channelsToolStripDropDownButton.Text = "Gradient Channels"; + this.channelsToolStripDropDownButton.DropDownOpening += new EventHandler(this.channelsToolStripDropDownButton_DropDownOpening); + this.redGreenBlueToolStripMenuItem.Checked = true; + this.redGreenBlueToolStripMenuItem.CheckState = CheckState.Checked; + this.redGreenBlueToolStripMenuItem.Name = "redGreenBlueToolStripMenuItem"; + this.redGreenBlueToolStripMenuItem.Size = new Size(156, 22); + this.redGreenBlueToolStripMenuItem.Text = "Red, Green, Blue"; + this.redGreenBlueToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.redCyanToolStripMenuItem.Name = "redCyanToolStripMenuItem"; + this.redCyanToolStripMenuItem.Size = new Size(156, 22); + this.redCyanToolStripMenuItem.Text = "Cyan, Red"; + this.redCyanToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.yellowBlueToolStripMenuItem.Name = "yellowBlueToolStripMenuItem"; + this.yellowBlueToolStripMenuItem.Size = new Size(156, 22); + this.yellowBlueToolStripMenuItem.Text = "Yellow, Blue"; + this.yellowBlueToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.magentaGreenToolStripMenuItem.Name = "magentaGreenToolStripMenuItem"; + this.magentaGreenToolStripMenuItem.Size = new Size(156, 22); + this.magentaGreenToolStripMenuItem.Text = "Magenta, Green"; + this.magentaGreenToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.redBlueToolStripMenuItem.Name = "redBlueToolStripMenuItem"; + this.redBlueToolStripMenuItem.Size = new Size(156, 22); + this.redBlueToolStripMenuItem.Text = "Red, Blue"; + this.redBlueToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.redGreenToolStripMenuItem.Name = "redGreenToolStripMenuItem"; + this.redGreenToolStripMenuItem.Size = new Size(156, 22); + this.redGreenToolStripMenuItem.Text = "Red, Green"; + this.redGreenToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.greenBlueToolStripMenuItem.Name = "greenBlueToolStripMenuItem"; + this.greenBlueToolStripMenuItem.Size = new Size(156, 22); + this.greenBlueToolStripMenuItem.Text = "Green, Blue"; + this.greenBlueToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.redToolStripMenuItem.Name = "redToolStripMenuItem"; + this.redToolStripMenuItem.Size = new Size(156, 22); + this.redToolStripMenuItem.Text = "Red"; + this.redToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.greenToolStripMenuItem.Name = "greenToolStripMenuItem"; + this.greenToolStripMenuItem.Size = new Size(156, 22); + this.greenToolStripMenuItem.Text = "Green"; + this.greenToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.blueToolStripMenuItem.Name = "blueToolStripMenuItem"; + this.blueToolStripMenuItem.Size = new Size(156, 22); + this.blueToolStripMenuItem.Text = "Blue"; + this.blueToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.cyanToolStripMenuItem.Name = "cyanToolStripMenuItem"; + this.cyanToolStripMenuItem.Size = new Size(156, 22); + this.cyanToolStripMenuItem.Text = "Cyan"; + this.cyanToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.yellowToolStripMenuItem.Name = "yellowToolStripMenuItem"; + this.yellowToolStripMenuItem.Size = new Size(156, 22); + this.yellowToolStripMenuItem.Text = "Yellow"; + this.yellowToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.magentaToolStripMenuItem.Name = "magentaToolStripMenuItem"; + this.magentaToolStripMenuItem.Size = new Size(156, 22); + this.magentaToolStripMenuItem.Text = "Magenta"; + this.magentaToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.brightnessToolStripMenuItem.Name = "brightnessToolStripMenuItem"; + this.brightnessToolStripMenuItem.Size = new Size(156, 22); + this.brightnessToolStripMenuItem.Text = "Brightness"; + this.brightnessToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.greyToolStripMenuItem.Name = "greyToolStripMenuItem"; + this.greyToolStripMenuItem.Size = new Size(156, 22); + this.greyToolStripMenuItem.Text = "Grey"; + this.greyToolStripMenuItem.Click += new EventHandler(this.ChannelsGroupChanged); + this.zoomToolStripDropDownButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + this.zoomToolStripDropDownButton.DropDownItems.AddRange(new ToolStripItem[11] + { + (ToolStripItem) this.x1ToolStripMenuItem, + (ToolStripItem) this.fitToWindowToolStripMenuItem, + (ToolStripItem) toolStripSeparator9, + (ToolStripItem) this.x2ToolStripMenuItem, + (ToolStripItem) this.x3ToolStripMenuItem, + (ToolStripItem) this.x4ToolStripMenuItem, + (ToolStripItem) this.x6ToolStripMenuItem, + (ToolStripItem) this.x8ToolStripMenuItem, + (ToolStripItem) this.x10ToolStripMenuItem, + (ToolStripItem) this.toolStripSeparator18, + (ToolStripItem) this.showGridToolStripMenuItem + }); + this.zoomToolStripDropDownButton.Image = (Image) Resources.magnifier_zoom; + this.zoomToolStripDropDownButton.Name = "zoomToolStripDropDownButton"; + this.zoomToolStripDropDownButton.Size = new Size(29, 22); + this.zoomToolStripDropDownButton.Text = "Zoom"; + this.x1ToolStripMenuItem.Image = (Image) Resources.magnifier_zoom_actual; + this.x1ToolStripMenuItem.Name = "x1ToolStripMenuItem"; + this.x1ToolStripMenuItem.Size = new Size(140, 22); + this.x1ToolStripMenuItem.Text = "Actual Size"; + this.x1ToolStripMenuItem.Click += new EventHandler(this.actualSizeToolStripMenuItem_Click); + this.fitToWindowToolStripMenuItem.Checked = true; + this.fitToWindowToolStripMenuItem.CheckState = CheckState.Checked; + this.fitToWindowToolStripMenuItem.Image = (Image) Resources.magnifier_zoom_fit; + this.fitToWindowToolStripMenuItem.Name = "fitToWindowToolStripMenuItem"; + this.fitToWindowToolStripMenuItem.Size = new Size(140, 22); + this.fitToWindowToolStripMenuItem.Text = "Fit to Window"; + this.fitToWindowToolStripMenuItem.Click += new EventHandler(this.actualSizeToolStripMenuItem_Click); + this.x2ToolStripMenuItem.Name = "x2ToolStripMenuItem"; + this.x2ToolStripMenuItem.Size = new Size(140, 22); + this.x2ToolStripMenuItem.Text = "2x"; + this.x2ToolStripMenuItem.Click += new EventHandler(this.actualSizeToolStripMenuItem_Click); + this.x3ToolStripMenuItem.Name = "x3ToolStripMenuItem"; + this.x3ToolStripMenuItem.Size = new Size(140, 22); + this.x3ToolStripMenuItem.Text = "3x"; + this.x3ToolStripMenuItem.Click += new EventHandler(this.actualSizeToolStripMenuItem_Click); + this.x4ToolStripMenuItem.Name = "x4ToolStripMenuItem"; + this.x4ToolStripMenuItem.Size = new Size(140, 22); + this.x4ToolStripMenuItem.Text = "4x"; + this.x4ToolStripMenuItem.Click += new EventHandler(this.actualSizeToolStripMenuItem_Click); + this.x6ToolStripMenuItem.Name = "x6ToolStripMenuItem"; + this.x6ToolStripMenuItem.Size = new Size(140, 22); + this.x6ToolStripMenuItem.Text = "6x"; + this.x6ToolStripMenuItem.Click += new EventHandler(this.actualSizeToolStripMenuItem_Click); + this.x8ToolStripMenuItem.Name = "x8ToolStripMenuItem"; + this.x8ToolStripMenuItem.Size = new Size(140, 22); + this.x8ToolStripMenuItem.Text = "8x"; + this.x8ToolStripMenuItem.Click += new EventHandler(this.actualSizeToolStripMenuItem_Click); + this.x10ToolStripMenuItem.Name = "x10ToolStripMenuItem"; + this.x10ToolStripMenuItem.Size = new Size(140, 22); + this.x10ToolStripMenuItem.Text = "10x"; + this.x10ToolStripMenuItem.Click += new EventHandler(this.actualSizeToolStripMenuItem_Click); + this.toolStripSeparator18.Name = "toolStripSeparator18"; + this.toolStripSeparator18.Size = new Size(137, 6); + this.showGridToolStripMenuItem.Checked = true; + this.showGridToolStripMenuItem.CheckOnClick = true; + this.showGridToolStripMenuItem.CheckState = CheckState.Checked; + this.showGridToolStripMenuItem.Name = "showGridToolStripMenuItem"; + this.showGridToolStripMenuItem.Size = new Size(140, 22); + this.showGridToolStripMenuItem.Text = "Show Grid"; + this.showGridToolStripMenuItem.CheckedChanged += new EventHandler(this.showGridToolStripMenuItem_CheckedChanged); + this.configToolStripSplitButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + this.configToolStripSplitButton.DropDownItems.AddRange(new ToolStripItem[10] + { + (ToolStripItem) toolStripLabel2, + (ToolStripItem) this.nWritesToolStripTextBox, + (ToolStripItem) toolStripSeparator11, + (ToolStripItem) toolStripLabel1, + (ToolStripItem) this.gradientNameToolStripTextBox, + (ToolStripItem) toolStripSeparator13, + (ToolStripItem) this.gradientTypeToolStripMenuItem, + (ToolStripItem) this.toolStripSeparator14, + (ToolStripItem) this.generateInitializationCodeToolStripMenuItem, + (ToolStripItem) this.configureChannelSetupToolStripMenuItem + }); + this.configToolStripSplitButton.Image = (Image) Resources.wrench_screwdriver; + this.configToolStripSplitButton.Name = "configToolStripSplitButton"; + this.configToolStripSplitButton.Size = new Size(32 /*0x20*/, 22); + this.configToolStripSplitButton.Text = "Configure HDMA"; + this.configToolStripSplitButton.ButtonClick += new EventHandler(this.configToolStripSplitButton_Click); + this.configToolStripSplitButton.DropDownClosed += new EventHandler(this.channelsToolStripDropDownButton_DropDownClosed); + this.configToolStripSplitButton.DropDownOpening += new EventHandler(this.configToolStripSplitButton_DropDownOpening); + this.nWritesToolStripTextBox.Name = "nWritesToolStripTextBox"; + this.nWritesToolStripTextBox.Size = new Size(100, 21); + this.nWritesToolStripTextBox.Text = "224"; + this.nWritesToolStripTextBox.ToolTipText = "Number of Writes"; + this.gradientNameToolStripTextBox.Name = "gradientNameToolStripTextBox"; + this.gradientNameToolStripTextBox.Size = new Size(100, 21); + this.gradientNameToolStripTextBox.Text = "Gradient1"; + this.gradientNameToolStripTextBox.ToolTipText = "Gradient Name"; + this.gradientTypeToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[8] + { + (ToolStripItem) toolStripLabel4, + (ToolStripItem) this.mode0ToolStripMenuItem, + (ToolStripItem) this.mode2ToolStripMenuItem, + (ToolStripItem) this.toolStripSeparator16, + (ToolStripItem) toolStripLabel3, + (ToolStripItem) this.scrollableGradientToolStripMenuItem, + (ToolStripItem) this.writeToPaletteToolStripMenuItem, + (ToolStripItem) this.paletteIndexToolStripTextBox + }); + this.gradientTypeToolStripMenuItem.Name = "gradientTypeToolStripMenuItem"; + this.gradientTypeToolStripMenuItem.Size = new Size(207, 22); + this.gradientTypeToolStripMenuItem.Text = "Gradient Type"; + this.gradientTypeToolStripMenuItem.DropDownClosed += new EventHandler(this.gradientTypeToolStripMenuItem_DropDownClosed); + this.gradientTypeToolStripMenuItem.DropDownOpening += new EventHandler(this.gradientTypeToolStripMenuItem_DropDownOpening); + this.mode0ToolStripMenuItem.Name = "mode0ToolStripMenuItem"; + this.mode0ToolStripMenuItem.Size = new Size(163, 22); + this.mode0ToolStripMenuItem.Text = "Mode 0"; + this.mode0ToolStripMenuItem.Click += new EventHandler(this.GradientModeClicked); + this.mode2ToolStripMenuItem.Checked = true; + this.mode2ToolStripMenuItem.CheckState = CheckState.Checked; + this.mode2ToolStripMenuItem.Name = "mode2ToolStripMenuItem"; + this.mode2ToolStripMenuItem.Size = new Size(163, 22); + this.mode2ToolStripMenuItem.Text = "Mode 2"; + this.mode2ToolStripMenuItem.Click += new EventHandler(this.GradientModeClicked); + this.toolStripSeparator16.Name = "toolStripSeparator16"; + this.toolStripSeparator16.Size = new Size(160 /*0xA0*/, 6); + this.scrollableGradientToolStripMenuItem.Name = "scrollableGradientToolStripMenuItem"; + this.scrollableGradientToolStripMenuItem.Size = new Size(163, 22); + this.scrollableGradientToolStripMenuItem.Text = "Scrollable Gradient"; + this.scrollableGradientToolStripMenuItem.Click += new EventHandler(this.GradientModeClicked); + this.writeToPaletteToolStripMenuItem.Name = "writeToPaletteToolStripMenuItem"; + this.writeToPaletteToolStripMenuItem.Size = new Size(163, 22); + this.writeToPaletteToolStripMenuItem.Text = "Write to Palette:"; + this.writeToPaletteToolStripMenuItem.Click += new EventHandler(this.GradientModeClicked); + this.paletteIndexToolStripTextBox.Name = "paletteIndexToolStripTextBox"; + this.paletteIndexToolStripTextBox.Size = new Size(100, 21); + this.paletteIndexToolStripTextBox.Text = "00"; + this.toolStripSeparator14.Name = "toolStripSeparator14"; + this.toolStripSeparator14.Size = new Size(204, 6); + this.generateInitializationCodeToolStripMenuItem.CheckOnClick = true; + this.generateInitializationCodeToolStripMenuItem.Name = "generateInitializationCodeToolStripMenuItem"; + this.generateInitializationCodeToolStripMenuItem.Size = new Size(207, 22); + this.generateInitializationCodeToolStripMenuItem.Text = "Generate Initialization Code"; + this.generateInitializationCodeToolStripMenuItem.CheckedChanged += new EventHandler(this.generateInitializationCodeToolStripMenuItem_CheckedChanged); + this.configureChannelSetupToolStripMenuItem.Name = "configureChannelSetupToolStripMenuItem"; + this.configureChannelSetupToolStripMenuItem.Size = new Size(207, 22); + this.configureChannelSetupToolStripMenuItem.Text = "Configure Channel Setup..."; + this.configureChannelSetupToolStripMenuItem.Click += new EventHandler(this.configToolStripSplitButton_Click); + this.generateToolStripButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + this.generateToolStripButton.Image = (Image) Resources.gear__arrow; + this.generateToolStripButton.Name = "generateToolStripButton"; + this.generateToolStripButton.Size = new Size(23, 22); + this.generateToolStripButton.Text = "Generate HDMA Code"; + this.generateToolStripButton.Click += new EventHandler(this.GenerateToolStripButtonClicked); + this.exportImgToolStripButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + this.exportImgToolStripButton.Image = (Image) Resources.image_export; + this.exportImgToolStripButton.Name = "exportImgToolStripButton"; + this.exportImgToolStripButton.Size = new Size(23, 22); + this.exportImgToolStripButton.Text = "Export as Bitmap"; + this.exportImgToolStripButton.Click += new EventHandler(this.ExportToolStripButtonClicked); + this.saveToolStripButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + this.saveToolStripButton.Enabled = false; + this.saveToolStripButton.Image = (Image) Resources.disk; + this.saveToolStripButton.Name = "saveToolStripButton"; + this.saveToolStripButton.Size = new Size(23, 22); + this.saveToolStripButton.Text = "Save HDMA"; + this.saveToolStripButton.Click += new EventHandler(this.SaveToolStripButtonClicked); + this.aboutToolStripButton.DisplayStyle = ToolStripItemDisplayStyle.Image; + this.aboutToolStripButton.Image = (Image) Resources.information_frame; + this.aboutToolStripButton.Name = "aboutToolStripButton"; + this.aboutToolStripButton.Size = new Size(23, 22); + this.aboutToolStripButton.Text = "About GradientTool"; + this.aboutToolStripButton.Click += new EventHandler(this.AboutToolStripButtonClicked); + this.richTextBox1.BackColor = Color.White; + this.richTextBox1.ContextMenuStrip = this.viewerContextMenuStrip; + this.richTextBox1.Dock = DockStyle.Fill; + this.richTextBox1.Font = new Font("Courier New", 9.75f, FontStyle.Regular, GraphicsUnit.Point, (byte) 0); + this.richTextBox1.ForeColor = Color.Black; + this.richTextBox1.Location = new Point(83, 25); + this.richTextBox1.Name = "richTextBox1"; + this.richTextBox1.ReadOnly = true; + this.richTextBox1.Size = new Size(405, 518); + this.richTextBox1.TabIndex = 4; + this.richTextBox1.Text = ""; + this.richTextBox1.WordWrap = false; + this.viewerContextMenuStrip.Items.AddRange(new ToolStripItem[3] + { + (ToolStripItem) this.copyToolStripMenuItem, + (ToolStripItem) this.toolStripSeparator9, + (ToolStripItem) this.selectAllToolStripMenuItem + }); + this.viewerContextMenuStrip.Name = "contextMenuStrip1"; + this.viewerContextMenuStrip.ShowImageMargin = false; + this.viewerContextMenuStrip.Size = new Size(93, 54); + this.copyToolStripMenuItem.Name = "copyToolStripMenuItem"; + this.copyToolStripMenuItem.ShortcutKeys = Keys.C | Keys.Control; + this.copyToolStripMenuItem.ShowShortcutKeys = false; + this.copyToolStripMenuItem.Size = new Size(92, 22); + this.copyToolStripMenuItem.Text = "&Copy"; + this.copyToolStripMenuItem.Click += new EventHandler(this.CopyClicked); + this.toolStripSeparator9.Name = "toolStripSeparator9"; + this.toolStripSeparator9.Size = new Size(89, 6); + this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem"; + this.selectAllToolStripMenuItem.Size = new Size(92, 22); + this.selectAllToolStripMenuItem.Text = "Select &All"; + this.selectAllToolStripMenuItem.Click += new EventHandler(this.SelectAllClicked); + this.panel2.AutoScroll = true; + this.panel2.Controls.Add((Control) this.gradientControl1); + this.panel2.Dock = DockStyle.Left; + this.panel2.Location = new Point(0, 25); + this.panel2.Name = "panel2"; + this.panel2.Padding = new Padding(2, 2, 0, 2); + this.panel2.Size = new Size(83, 518); + this.panel2.TabIndex = 6; + this.panel2.Resize += new EventHandler(this.panel2_Resize); + this.statusStrip1.Location = new Point(0, 543); + this.statusStrip1.Name = "statusStrip1"; + this.statusStrip1.RenderMode = ToolStripRenderMode.ManagerRenderMode; + this.statusStrip1.Size = new Size(488, 22); + this.statusStrip1.TabIndex = 7; + this.statusStrip1.Text = "statusStrip1"; + this.gradientControl1.Channels = GradientChannels.RedGreenBlue; + this.gradientControl1.Colourspace = GradientColourspace.RGBV; + this.gradientControl1.Dock = DockStyle.Fill; + this.gradientControl1.GenerateHDMAInitializationCode = false; + this.gradientControl1.GradientName = "Gradient1"; + this.gradientControl1.Location = new Point(2, 2); + this.gradientControl1.Name = "gradientControl1"; + this.gradientControl1.ShowGrid = true; + this.gradientControl1.Size = new Size(81, 514); + this.gradientControl1.TabIndex = 4; + this.gradientControl1.Text = "gradientControl1"; + this.gradientControl1.Type = GradientType.Linear; + this.gradientControl1.GradientChanged += new EventHandler(this.gradientControl1_GradientChanged); + this.AutoScaleDimensions = new SizeF(6f, 13f); + this.AutoScaleMode = AutoScaleMode.Font; + this.ClientSize = new Size(488, 565); + this.Controls.Add((Control) this.richTextBox1); + this.Controls.Add((Control) this.panel2); + this.Controls.Add((Control) this.toolStrip1); + this.Controls.Add((Control) this.statusStrip1); + this.Icon = (Icon) componentResourceManager.GetObject("$this.Icon"); + this.MinimumSize = new Size(250, 350); + this.Name = nameof (Program); + this.Text = "GradientTool*"; + this.toolStrip1.ResumeLayout(false); + this.toolStrip1.PerformLayout(); + this.viewerContextMenuStrip.ResumeLayout(false); + this.panel2.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + } + + public Program() + { + this.InitializeComponent(); + this.richTextBox1.Rtf = Resources.NoCodeGeneratedMessage; + } + + private void InterpolationGroupChanged(object sender, EventArgs e) + { + foreach (object dropDownItem in (ArrangedElementCollection) this.typeToolStripDropDownButton.DropDownItems) + { + if (dropDownItem is ToolStripMenuItem objA) + { + if (!object.ReferenceEquals((object) objA, sender)) + { + objA.Checked = false; + } + else + { + objA.Checked = true; + if (object.ReferenceEquals((object) objA, (object) this.linearToolStripMenuItem)) + this.gradientControl1.Type = GradientType.Linear; + else if (object.ReferenceEquals((object) objA, (object) this.circularToolStripMenuItem)) + this.gradientControl1.Type = GradientType.Circular; + else if (object.ReferenceEquals((object) objA, (object) this.cubicToolStripMenuItem)) + this.gradientControl1.Type = GradientType.Cubic; + else if (object.ReferenceEquals((object) objA, (object) this.catmullRomToolStripMenuItem)) + this.gradientControl1.Type = GradientType.CatmullRom; + else if (object.ReferenceEquals((object) objA, (object) this.hermiteToolStripMenuItem)) + this.gradientControl1.Type = GradientType.Hermite; + } + } + } + } + + private void ColourspaceGroupChanged(object sender, EventArgs e) + { + foreach (object dropDownItem in (ArrangedElementCollection) this.colourspaceToolStripDropDownButton.DropDownItems) + { + if (dropDownItem is ToolStripMenuItem objA) + { + if (!object.ReferenceEquals((object) objA, sender)) + { + objA.Checked = false; + } + else + { + objA.Checked = true; + if (object.ReferenceEquals((object) objA, (object) this.rgbToolStripMenuItem)) + this.gradientControl1.Colourspace = GradientColourspace.RGB; + else if (object.ReferenceEquals((object) objA, (object) this.rgbvToolStripMenuItem)) + this.gradientControl1.Colourspace = GradientColourspace.RGBV; + else if (object.ReferenceEquals((object) objA, (object) this.rgbbToolStripMenuItem)) + this.gradientControl1.Colourspace = GradientColourspace.RGBB; + else if (object.ReferenceEquals((object) objA, (object) this.rgblToolStripMenuItem)) + this.gradientControl1.Colourspace = GradientColourspace.RGBL; + else if (object.ReferenceEquals((object) objA, (object) this.hsvToolStripMenuItem)) + this.gradientControl1.Colourspace = GradientColourspace.HSV; + else if (object.ReferenceEquals((object) objA, (object) this.hslToolStripMenuItem)) + this.gradientControl1.Colourspace = GradientColourspace.HSL; + else if (object.ReferenceEquals((object) objA, (object) this.hsyToolStripMenuItem)) + this.gradientControl1.Colourspace = GradientColourspace.HSY; + } + } + } + } + + private void ChannelsGroupChanged(object sender, EventArgs e) + { + ToolStripMenuItem toolStripMenuItem = (ToolStripMenuItem) null; + bool flag = true; + try + { + foreach (object dropDownItem in (ArrangedElementCollection) this.channelsToolStripDropDownButton.DropDownItems) + { + if (dropDownItem is ToolStripMenuItem objA) + { + if (!object.ReferenceEquals((object) objA, sender)) + { + if (objA.Checked) + toolStripMenuItem = objA; + objA.Checked = false; + } + else + { + if (object.ReferenceEquals((object) objA, (object) this.redGreenBlueToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.RedGreenBlue; + else if (object.ReferenceEquals((object) objA, (object) this.redGreenToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.RedGreen; + else if (object.ReferenceEquals((object) objA, (object) this.greenBlueToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.GreenBlue; + else if (object.ReferenceEquals((object) objA, (object) this.redBlueToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.RedBlue; + else if (object.ReferenceEquals((object) objA, (object) this.redCyanToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.CyanRed; + else if (object.ReferenceEquals((object) objA, (object) this.yellowBlueToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.YellowBlue; + else if (object.ReferenceEquals((object) objA, (object) this.magentaGreenToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.MagentaGreen; + else if (object.ReferenceEquals((object) objA, (object) this.redToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.Red; + else if (object.ReferenceEquals((object) objA, (object) this.greenToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.Green; + else if (object.ReferenceEquals((object) objA, (object) this.blueToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.Blue; + else if (object.ReferenceEquals((object) objA, (object) this.cyanToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.Cyan; + else if (object.ReferenceEquals((object) objA, (object) this.yellowToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.Yellow; + else if (object.ReferenceEquals((object) objA, (object) this.magentaToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.Magenta; + else if (object.ReferenceEquals((object) objA, (object) this.brightnessToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.Brightness; + else if (object.ReferenceEquals((object) objA, (object) this.greyToolStripMenuItem)) + this.gradientControl1.Channels = GradientChannels.Grey; + objA.Checked = true; + } + } + flag = false; + } + } + catch (ArgumentException ex) + { + int num = (int) MessageBox.Show((IWin32Window) this, "Gradients that use a Transfer Mode 2 table must have at least 2 colour channels.", "GradientTool", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + catch (SilentException ex) + { + } + if (!flag) + return; + toolStripMenuItem.Checked = true; + } + + private void GenerateToolStripButtonClicked(object sender, EventArgs e) + { + int lineFromCharIndex = this.richTextBox1.GetLineFromCharIndex(this.richTextBox1.SelectionStart); + int num = this.richTextBox1.SelectionStart - this.richTextBox1.GetFirstCharIndexOfCurrentLine(); + CodeGen code = new CodeGen(); + this.gradientControl1.GenerateASM(code); + code.SetTextBoxText(this.richTextBox1); + this.m_asm = code.GetText(); + this.saveToolStripButton.Enabled = true; + int start; + if (lineFromCharIndex >= this.richTextBox1.Lines.Length) + { + start = this.richTextBox1.TextLength; + } + else + { + string line = this.richTextBox1.Lines[lineFromCharIndex]; + if (num > line.Length) + num = line.Length; + start = num + this.richTextBox1.GetFirstCharIndexFromLine(lineFromCharIndex); + } + this.richTextBox1.Select(start, 0); + this.Clean(); + } + + private void SaveToolStripButtonClicked(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(this.m_asm)) + { + this.saveToolStripButton.Enabled = false; + SystemSounds.Beep.Play(); + } + else + { + if (this.m_dirty) + { + switch (MessageBox.Show((IWin32Window) this, "The gradient has been modified since you last generated the code.\r\nDo you want to re-generate the code?", "GradientTool", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question)) + { + case DialogResult.Cancel: + return; + case DialogResult.Yes: + this.GenerateToolStripButtonClicked((object) null, (EventArgs) null); + break; + } + } + string path = Utils.PromptForFilename((IWin32Window) this, "ASM Files (.asm)|*.asm|All files|*.*", "asm", this.gradientNameToolStripTextBox.Text); + if (path == null) + return; + File.WriteAllText(path, this.m_asm, Encoding.Default); + } + } + + private unsafe void ExportToolStripButtonClicked(object sender, EventArgs e) + { + int num = 1; + string filename; + do + { + string text = this.gradientNameToolStripTextBox.Text; + string typeId = "ExportGradientAsBitmap"; + filename = Utils.PromptForFilename((IWin32Window) this, (this.gradientControl1.Channels != GradientChannels.Brightness ? "15-bit" : "4-bit") + " Gradient (.png, .bmp, .dib, .jpeg, .gif)|*.png;*.bmp;*.dib;*.jpeg;*.jpg;*.jpe;*.gif|24-bit Gradient (.png, .bmp, .dib, .jpeg, .gif)|*.png;*.bmp;*.dib;*.jpeg;*.jpg;*.jpe;*.gif|All Files|*.*", "png", &num, text, typeId); + } + while (filename != null && !this.gradientControl1.SaveGradient(filename, num == 2)); + } + + private void AboutToolStripButtonClicked(object sender, EventArgs e) + { + using (AboutBox aboutBox = new AboutBox()) + { + int num = (int) aboutBox.ShowDialog((IWin32Window) this); + } + } + + private void CopyClicked(object sender, EventArgs e) + { + if (this.richTextBox1.SelectionLength > 0) + { + this.richTextBox1.Copy(); + } + else + { + int selectionStart = this.richTextBox1.SelectionStart; + int indexOfCurrentLine = this.richTextBox1.GetFirstCharIndexOfCurrentLine(); + this.richTextBox1.Select(indexOfCurrentLine, this.richTextBox1.Lines[this.richTextBox1.GetLineFromCharIndex(indexOfCurrentLine)].Length + 1); + this.richTextBox1.Copy(); + this.richTextBox1.Select(selectionStart, 0); + } + } + + private void SelectAllClicked(object sender, EventArgs e) => this.richTextBox1.SelectAll(); + + [STAThread] + private static int Main() + { + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + try + { + Program mainForm; + try + { + mainForm = new Program(); + } + catch (OutOfMemoryException ex) + { + int num = (int) MessageBox.Show("There is not enough memory for the application to start.", "GradientTool", MessageBoxButtons.OK, MessageBoxIcon.Hand); + return 14; + } + Application.Run((Form) mainForm); + return 0; + } + catch (Exception ex) + { + int num = (int) MessageBox.Show("An unhandled exception occurred.\r\n\r\n" + ex.ToString(), "GradientTool", MessageBoxButtons.OK, MessageBoxIcon.Hand); + throw; + } + } + + private void channelsToolStripDropDownButton_DropDownClosed(object sender, EventArgs e) + { + try + { + this.gradientControl1.GradientName = this.gradientNameToolStripTextBox.Text.Trim(); + } + catch (ArgumentException ex) + { + int num = (int) MessageBox.Show((IWin32Window) this, "The specified gradient name contains invalid characters.\r\nNames may contain [a-z], [A-Z], [0-9], and [_].\r\nNot that they cannot start with a numeric character.", "GradientTool", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + string s = this.nWritesToolStripTextBox.Text.Trim(); + int result; + if (!int.TryParse(s, NumberStyles.Number, (IFormatProvider) null, out result)) + { + int startIndex; + if (s[0] == '$' && s.Length > (startIndex = 1) || s[0] == '0' && char.ToLowerInvariant(s[1]) == 'x' && s.Length > (startIndex = 2) || s[0] == '&' && char.ToLowerInvariant(s[1]) == 'h' && s.Length > (startIndex = 2)) + { + if (int.TryParse(s.Substring(startIndex), NumberStyles.HexNumber, (IFormatProvider) null, out result)) + goto label_6; + } + int num = (int) MessageBox.Show((IWin32Window) this, "Could not parse number.\r\nThe number must be an integer in decimal or hexadecimal format.\r\nNumbers in decimal format are permitted to have thousands separators.", "GradientTool", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + return; + } +label_6: + try + { + try + { + this.gradientControl1.SetSizeOfGradient(result); + GC.Collect(); + } + catch (OutOfMemoryException ex) + { + int num = (int) MessageBox.Show((IWin32Window) this, "Not enough memory. No change was made.", "GradientTool", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + GC.Collect(); + } + if (this.m_zoom <= 0) + return; + this.gradientControl1.Height = this.gradientControl1.SizeOfGradient * this.m_zoom + 18; + } + catch (ArgumentOutOfRangeException ex) + { + int num = (int) MessageBox.Show((IWin32Window) this, "The entered value must be between 4 and 32,767, or 0x7FFF.", "GradientTool", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + + private void ResetZoom() + { + this.panel2.BorderStyle = BorderStyle.None; + this.panel2.Padding = new Padding(2, 2, 0, 2); + this.panel2.Width = 83; + this.gradientControl1.Dock = DockStyle.Fill; + this.m_zoom = 0; + } + + private void SetZoom(int n) + { + this.m_zoom = n; + int num = this.gradientControl1.SizeOfGradient * n + 18; + this.panel2.BorderStyle = BorderStyle.Fixed3D; + this.panel2.Padding = Padding.Empty; + this.panel2.Width = 85 + (this.panel2.VerticalScroll.Visible ? SystemInformation.VerticalScrollBarWidth : 0); + this.gradientControl1.Dock = DockStyle.Top; + this.gradientControl1.Height = num; + this.gradientControl1.Width = 81; + this.gradientControl1.Top = this.gradientControl1.Left = 0; + } + + private void actualSizeToolStripMenuItem_Click(object sender, EventArgs e) + { + foreach (object dropDownItem in (ArrangedElementCollection) this.zoomToolStripDropDownButton.DropDownItems) + { + if (dropDownItem is ToolStripMenuItem objA) + { + if (!object.ReferenceEquals((object) objA, sender)) + { + if (!object.ReferenceEquals((object) objA, (object) this.showGridToolStripMenuItem)) + objA.Checked = false; + } + else + { + objA.Checked = true; + if (object.ReferenceEquals(sender, (object) this.fitToWindowToolStripMenuItem)) + this.ResetZoom(); + else if (object.ReferenceEquals(sender, (object) this.x1ToolStripMenuItem)) + this.SetZoom(1); + else if (object.ReferenceEquals(sender, (object) this.x2ToolStripMenuItem)) + this.SetZoom(2); + else if (object.ReferenceEquals(sender, (object) this.x3ToolStripMenuItem)) + this.SetZoom(3); + else if (object.ReferenceEquals(sender, (object) this.x4ToolStripMenuItem)) + this.SetZoom(4); + else if (object.ReferenceEquals(sender, (object) this.x6ToolStripMenuItem)) + this.SetZoom(6); + else if (object.ReferenceEquals(sender, (object) this.x8ToolStripMenuItem)) + this.SetZoom(8); + else if (object.ReferenceEquals(sender, (object) this.x10ToolStripMenuItem)) + this.SetZoom(10); + } + } + } + } + + private void panel2_Resize(object sender, EventArgs e) + { + this.panel2.Width = 85 + (this.panel2.VerticalScroll.Visible ? SystemInformation.VerticalScrollBarWidth : 0); + } + + private void configToolStripSplitButton_Click(object sender, EventArgs e) + { + Settings2 settings = this.gradientControl1.Settings; + int sizeOfGradient = this.gradientControl1.SizeOfGradient; + if (!Config2.ConfigureSettings((IWin32Window) this, ref settings, ref sizeOfGradient)) + return; + try + { + this.gradientControl1.Settings = settings; + this.gradientControl1.SetSizeOfGradient(sizeOfGradient); + } + catch + { + int num = (int) MessageBox.Show((IWin32Window) this, "An error occured and some settings may not have been changed.", "GradientTool", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + + private void generateInitializationCodeToolStripMenuItem_CheckedChanged( + object sender, + EventArgs e) + { + this.gradientControl1.GenerateHDMAInitializationCode = this.generateInitializationCodeToolStripMenuItem.Checked; + } + + private void channelsToolStripDropDownButton_DropDownOpening(object sender, EventArgs e) + { + switch (this.gradientControl1.Settings.Arrangement) + { + case 0: + IEnumerator enumerator1 = this.channelsToolStripDropDownButton.DropDownItems.GetEnumerator(); + try + { + while (enumerator1.MoveNext()) + { + if (enumerator1.Current is ToolStripMenuItem current) + current.Enabled = true; + } + break; + } + finally + { + if (enumerator1 is IDisposable disposable) + disposable.Dispose(); + } + case 1: + this.redGreenBlueToolStripMenuItem.Enabled = this.redGreenToolStripMenuItem.Enabled = this.redBlueToolStripMenuItem.Enabled = this.greenBlueToolStripMenuItem.Enabled = this.redCyanToolStripMenuItem.Enabled = this.magentaGreenToolStripMenuItem.Enabled = this.yellowBlueToolStripMenuItem.Enabled = this.brightnessToolStripMenuItem.Enabled = true; + this.redToolStripMenuItem.Enabled = this.greenToolStripMenuItem.Enabled = this.blueToolStripMenuItem.Enabled = this.cyanToolStripMenuItem.Enabled = this.magentaToolStripMenuItem.Enabled = this.yellowToolStripMenuItem.Enabled = this.greyToolStripMenuItem.Enabled = false; + break; + case 2: + case 3: + IEnumerator enumerator2 = this.channelsToolStripDropDownButton.DropDownItems.GetEnumerator(); + try + { + while (enumerator2.MoveNext()) + { + if (enumerator2.Current is ToolStripMenuItem current) + { + bool flag; + current.Enabled = (flag = object.ReferenceEquals((object) current, (object) this.redGreenBlueToolStripMenuItem)) || object.ReferenceEquals((object) current, (object) this.brightnessToolStripMenuItem); + current.Checked = flag; + } + } + break; + } + finally + { + if (enumerator2 is IDisposable disposable) + disposable.Dispose(); + } + } + } + + private void configToolStripSplitButton_DropDownOpening(object sender, EventArgs e) + { + this.nWritesToolStripTextBox.Text = this.gradientControl1.SizeOfGradient.ToString(); + this.gradientNameToolStripTextBox.Text = this.gradientControl1.GradientName; + this.generateInitializationCodeToolStripMenuItem.Checked = this.gradientControl1.GenerateHDMAInitializationCode; + } + + private void gradientTypeToolStripMenuItem_DropDownOpening(object sender, EventArgs e) + { + bool flag = false; + this.mode2ToolStripMenuItem.Enabled = Generator2.GetNChannels(this.gradientControl1.Channels) >= 2; + switch (this.gradientControl1.Settings.Arrangement) + { + case 1: + this.mode0ToolStripMenuItem.Checked = false; + this.writeToPaletteToolStripMenuItem.Checked = false; + this.scrollableGradientToolStripMenuItem.Checked = false; + this.mode2ToolStripMenuItem.Checked = true; + break; + case 2: + this.mode0ToolStripMenuItem.Checked = false; + this.mode2ToolStripMenuItem.Checked = false; + this.scrollableGradientToolStripMenuItem.Checked = false; + this.writeToPaletteToolStripMenuItem.Checked = true; + if (this.gradientControl1.Settings.Channel1 is Mode3Channel channel1) + { + flag = true; + this.paletteIndexToolStripTextBox.Text = channel1.PaletteIndex.ToString("X2"); + break; + } + break; + case 3: + this.mode0ToolStripMenuItem.Checked = false; + this.mode2ToolStripMenuItem.Checked = false; + this.writeToPaletteToolStripMenuItem.Checked = false; + this.scrollableGradientToolStripMenuItem.Checked = true; + break; + default: + this.mode2ToolStripMenuItem.Checked = false; + this.writeToPaletteToolStripMenuItem.Checked = false; + this.scrollableGradientToolStripMenuItem.Checked = false; + this.mode0ToolStripMenuItem.Checked = true; + break; + } + if (flag) + return; + this.paletteIndexToolStripTextBox.Text = "00"; + } + + private void Dirty() + { + if (this.m_dirty) + return; + this.m_dirty = true; + this.Text = "GradientTool*"; + } + + private void Clean() + { + if (!this.m_dirty) + return; + this.m_dirty = false; + this.Text = "GradientTool"; + } + + private void gradientControl1_GradientChanged(object sender, EventArgs e) => this.Dirty(); + + private void DoChange(int mode) + { + Settings2 settings = this.gradientControl1.Settings; + switch (mode) + { + case 0: + settings.MakeMode0All(settings.Channels); + break; + case 1: + settings.MakeMode2Mode0(settings.Channels); + break; + case 2: + settings.MakeMode3(); + break; + case 3: + settings.MakeCombined(); + break; + } + this.gradientControl1.Settings = settings; + } + + private void GradientModeClicked(object sender, EventArgs e) + { + if (object.ReferenceEquals(sender, (object) this.mode0ToolStripMenuItem)) + this.DoChange(0); + else if (object.ReferenceEquals(sender, (object) this.mode2ToolStripMenuItem)) + this.DoChange(1); + else if (object.ReferenceEquals(sender, (object) this.writeToPaletteToolStripMenuItem)) + this.DoChange(2); + else if (object.ReferenceEquals(sender, (object) this.scrollableGradientToolStripMenuItem)) + this.DoChange(3); + foreach (object dropDownItem in (ArrangedElementCollection) this.gradientTypeToolStripMenuItem.DropDownItems) + { + if (dropDownItem is ToolStripMenuItem objA) + objA.Checked = object.ReferenceEquals((object) objA, sender); + } + } + + private void gradientTypeToolStripMenuItem_DropDownClosed(object sender, EventArgs e) + { + if (!(this.gradientControl1.Settings.Channel1 is Mode3Channel channel1)) + return; + int result; + if (int.TryParse(this.paletteIndexToolStripTextBox.Text, NumberStyles.HexNumber, (IFormatProvider) null, out result) && result >= 0 && result <= (int) byte.MaxValue) + { + channel1.PaletteIndex = (byte) result; + this.Dirty(); + } + else + { + int num = (int) MessageBox.Show((IWin32Window) this, "Palette index must be a hexadecimal number between 0x00 and 0xFF.", "GradientTool", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } + } + + private void configureToolStripMenuItem_Click(object sender, EventArgs e) + { + using (HermiteConfiguration hermiteConfiguration = new HermiteConfiguration(new Action(this.gradientControl1.UpdateGradient))) + { + int num = (int) hermiteConfiguration.ShowDialog((IWin32Window) this); + } + } + + private void showGridToolStripMenuItem_CheckedChanged(object sender, EventArgs e) + { + this.gradientControl1.ShowGrid = this.showGridToolStripMenuItem.Checked; + } +} diff --git a/Program.resx b/Program.resx new file mode 100644 index 0000000..ecd918b --- /dev/null +++ b/Program.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 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/6FfFuewZxfToV8W56pkF9v/xTj/tWoYzLdsGVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////aP///6b///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+zqKioyXl3d+TYy8v/c3Fx3m1tbdvTxsb/x4lE///jkv//1Wr//9Fd///RXf//0V3//9hz/8N5I8wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///9oUFBQ4SYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwHR0d+NDGxv+6sbH/zMLC/42Hh/3Uysr/0J9q/8eJQv/Rk0z/zY9I/9KUTf//5Zf/0ocuzNCFLVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+mJiYm8LaOAP+2jwD/to8A/7aOAP+2jwD/to4A/7aOAP+2jwD/to4A/7aOAP+2jgD/to4A/7aOAP+2jgD/to4A/7aPAP+2jgD/to4A/7aOAP+2jgD/to8A/7aOAP+2jgD/on8D/25bG//Mxsb/w729/+TZ2f/36Oj/9+jo/+TZ2f/Dvb3/zMbG/86QRPfakTfT3pM3XAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8PXNP//yvgD/874A//K9AP/yvgD/874A//O9AP/zvQD/8r0A//K+AP/zvgD/870A//K9AP/yvQD/8r0A//K9AP/yvgD/874A//O9AP/zvQD/870A//O9AP+7kwr/jnIR/45yEf+fmID/1M/P/8a0kP+WeRn/lnkZ/8a0kP/Uz8//hoaG/bSKVPCAXTGrJSUlRQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8PXNP//yvQD/870A//K+AP/yvQD/874A//O9AP/yvgD/870A//K9AP/yvQD/8r0A//O9AP/zvQD/870A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8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8PXNP//yvQD/8r0A//K9AP/yvQD/870A//O9AP/yvQD/8r0A//O9AP/yvQD/870A//K+AP/zvQD/8r0A//K9AP/yvQD/8r0A//O9AP/zvQD/874A//O9AP/zvQD/8r0A//O9AP/zvQD/8r0A//O9AP/zvQD/870A//O9AP+2jgD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8PXNP//yvgD/870A//K9AP/yvQD/870A//K9AP/zvgD/870A//K9AP/zvQD/874A//O9AP/yvQD/870A//K9AP/yvQD/8r0A//K9AP/yvQD/870A//O9AP/zvQD/870A//K9AP/yvQD/8r0A//O9AP/zvQD/8r0A//K9AP+2jgD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8PPIP//vtwD/77cA//C2AP/vtgD/77cA/++3AP/vtwD/77cA/++3AP/vtgD/77cA/++2AP/vtwD/8LcA//C2AP/vtgD/77cA/++3AP/vtwD/77cA/++2AP/vtwD/77cA/++2AP/vtwD/8LYA//C3AP/vtwD/8LYA/++3AP+0iQD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8O/CP//rrgD/664A/+uuAP/rrgD/664A/+uuAP/rrgD/664A/+uuAP/rrgD/664A/+uuAP/rrgD/664A/+uuAP/rrQD/664A/+utAP/rrgD/664A/+uuAP/rrQD/664A/+uuAP/rrgD/664A/+uuAP/rrgD/664A/+uuAP+wgwD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8Oy7P//mpgD/5qUA/+elAP/npQD/56UA/+elAP/npQD/5qUA/+elAP/npgD/56YA/+elAP/npgD/56YA/+elAP/npQD/56YA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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8NOOP//FagD/xWkA/8VpAP/EaQD/xGoA/8VqAP/FaQD/xWoA/8RqAP/EagD/xWkA/8VqAP/FagD/xWoA/8VpAP/EagD/xWkA/8VqAP/EagD/xWoA/8VqAP/FagD/xWkA/8VqAP/FagD/xWoA/8VpAP/FagD/xWoA/8RqAP+UTwD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8NOOP//FaQD/xWkA/8VpAP/FaQD/xWkA/8VqAP/FaQD/xWoA/8RqAP/FaQD/xWkA/8VqAP/FagD/xWkA/8VqAP/FagD/xWkA/8VqAP/FagD/xWoA/8VqAP/EaQD/xWoA/8VpAP/FaQD/xWoA/8VqAP/EagD/xGoA/8VpAP+UTwD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8NOOP//EagD/xWkA/8VqAP/FagD/xWoA/8VqAP/FaQD/xWkA/8VqAP/FaQD/xWoA/8RqAP/FaQD/xWoA/8VqAP/EagD/xWoA/8VqAP/FagD/xWoA/8VpAP/FaQD/xWoA/8VqAP/FagD/xWoA/8VpAP/FagD/xWoA/8RpAP+UTwD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8NOOP//FagD/xWkA/8VqAP/FagD/xWoA/8VpAP/FaQD/xWoA/8VqAP/FaQD/xWoA/8VqAP/FagD/xWkA/8VpAP/FaQD/xWoA/8VpAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FaQD/xWoA/8VpAP/FagD/xWoA/8VpAP+UTwD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+zJiYm8NOOP//EagD/xWkA/8VqAP/FagD/xWoA/8VqAP/EagD/xWoA/8VqAP/FaQD/xGoA/8RpAP/FagD/xWkA/8RqAP/FaQD/xWoA/8VqAP/FagD/xWkA/8VpAP/FagD/xWkA/8VqAP/EaQD/xWoA/8VqAP/FaQD/xWoA/8VpAP+UTwD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///+mJiYm8NOOP//Tjj//044//9KOP//Sjj//044//9OOP//Sjj//0o4//9OOP//Tjj//044//9OOP//Tjj//044//9KOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//JiYm8P///6YAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///9oUFBQ4SYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwUFBQ4f///2gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////aP///6b///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+m////aAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD///////8AAP///////wAA////////AAD////8AA8AAP////wADwAA/////wAHAAD+AAAAAAcAAPwAAAAABwAA/AAAAAAPAAD8AAAAAA8AAPwAAAAADwAA/AAAAAAPAAD8AAAAAA8AAPwAAAAAHwAA/AAAAAAfAAD8AAAAAB8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/AAAAAA/AAD8AAAAAD8AAPwAAAAAPwAA/gAAAAB/AAD///////8AAP///////wAA////////AAD///////8AAP///////wAA////////AAAoAAAAIAAAAEAAAAABACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAwAAAAWAAAAGgAAABoAAAAaAAAAGgAAABoAAAAaAAAAGgAAABqYTwaekUwFYQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAP///2j///+m////s////7P///+z////s////7P///+z////s////7P///+z////s////7P5+fm039/fusXFxcC7u7vCu7u7woyMjM9kZGTcZGRk3IyMjM+7u7vCu7u7wqpqKPCqZyHkplwOXgAAAAAAAAAAAAAAAAAAAAD///9oUFBQ4SYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwHR0d9BcXF/ghISHyFxcX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/8VqAP/FagD/lE8A/yYmJvD///+zAAAAAAAAAAAAAAAAAAAAAP///7MmJibw044//8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP+UTwD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAA////syYmJvDTjj//xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/5RPAP8mJibw////swAAAAAAAAAAAAAAAAAAAAD///+mJiYm8NOOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//yYmJvD///+mAAAAAAAAAAAAAAAAAAAAAP///2hQUFDhJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwUFBQ4f///2gAAAAAAAAAAAAAAAAAAAAAAAAAAP///2j///+m////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////6b///9oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA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/812AP+aWAD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAA////syYmJvDUkT//x24A/8dtAP/HbQD/yG0A/8dtAP/HbgD/x20A/8dtAP/HbQD/x20A/8dtAP/HbQD/x24A/8dtAP+VUgD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAA////syYmJvDTjj//xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP+UTwD/JiYm8P///7MAAAAAAAAAAAAAAAAAAAAA////piYmJvDTjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//JiYm8P///6YAAAAAAAAAAAAAAAAAAAAA////aFBQUOEmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwUFBQ4f///2gAAAAAAAAAAAAAAAAAAAAAAAAAAP///2j///+m////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+z////s////7P///+m////aAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAUH/gAFB4AAAQcAAAEHAAABBwAABQcAAAUHAAAFBwAABQcAAAUHAAANBwAADQcAAA0HAAANBwAADQcAAA0HAAANBwAADQcAAA0HAAANBwAADQeAAB0H///9B////QSgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAABMAAAAaAAAAGgAAABoAAAAaAAAAGgAAABYAAAAGAAAAAAAAAAD///9o////pv///7P///+z////s/b29rXNzc2+u7u7wo2Njc9mZmbciIiIx52dnYYAAAAsAAAADAAAAAD///9oUFBQ4SYmJvAmJibwJiYm8CYmJvAmJibwOjg4+kRBQfoaGhr459nZ/xoaGvhST0/1Z2RkyQAAAAAAAAAA////piYmJvC2jgD/to4A/7aOAP+2jgD/to4A/3doN//a0dH/nJKB/9DIyP+Vi3r/2tHR/4KAgOAAAAAAAAAAAP///7MmJibw9c0///O9AP/zvQD/870A/8KZCf+OchH/opqB/97V1f/15+f/3tXV/4mHh/2BgYHYJycnPQAAAAD///+zJiYm8PXNP//zvQD/870A//O9AP+Yexb/zs7O/8bGxv/h29v/cVgC/+Hb2//FxcX/zs7O/zAwMHcAAAAA////syYmJvDvwD//6qwA/+qsAP/qqwD/wpEM/5x5Gv+upo//2NjY/93d3f/Y2Nj/lJWV/ZaWltU4ODg6AAAAAP///7MmJibw57I//+CYAP/gmQD/4ZkA/+CYAP+kh0r/7e7u/7qxm//k5OT/saqa/+Xm5v+lpaXhAAAAAAAAAAD///+zJiYm8OCkP//WhwD/1ocA/9eHAP/WhwD/on5D/6aGT/+dbiD//f39/31bH/9gYGD5qKio3gAAAAAAAAAA////syYmJvDZlz//zHYA/8x2AP/MdgD/zXYA/812AP/NdgD/s24Q/5xoIf+LVxD/JiYm8P///7MAAAAAAAAAAP///7MmJibw044//8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/lE8A/yYmJvD///+zAAAAAAAAAAD///+zJiYm8NOOP//FagD/xWoA/8VqAP/FagD/xWoA/8VqAP/FagD/xWoA/5RPAP8mJibw////swAAAAAAAAAA////piYmJvDTjj//044//9OOP//Tjj//044//9OOP//Tjj//044//9OOP//Tjj//JiYm8P///6YAAAAAAAAAAP///2hQUFDhJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8CYmJvAmJibwJiYm8FBQUOH///9oAAAAAAAAAAAAAAAA////aP///6b///+z////s////7P///+z////s////7P///+z////s////6b///9oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/gCsQcAArEGAAaxBgAGsQYAArEGAAKxBgACsQYABrEGAAaxBgAGsQYABrEGAAaxBgAGsQYABrEHAA6xB//+sQQs= + + \ No newline at end of file diff --git a/Properties/Resources.cs b/Properties/Resources.cs new file mode 100644 index 0000000..6efd9f5 --- /dev/null +++ b/Properties/Resources.cs @@ -0,0 +1,141 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.Properties.Resources +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System.CodeDom.Compiler; +using System.ComponentModel; +using System.Diagnostics; +using System.Drawing; +using System.Globalization; +using System.Resources; +using System.Runtime.CompilerServices; + +#nullable disable +namespace SFXProductions.GradientTool.Properties; + +[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] +[DebuggerNonUserCode] +[CompilerGenerated] +internal class Resources +{ + private static ResourceManager resourceMan; + private static CultureInfo resourceCulture; + + internal Resources() + { + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + internal static ResourceManager ResourceManager + { + get + { + if (object.ReferenceEquals((object) SFXProductions.GradientTool.Properties.Resources.resourceMan, (object) null)) + SFXProductions.GradientTool.Properties.Resources.resourceMan = new ResourceManager("SFXProductions.GradientTool.Properties.Resources", typeof (SFXProductions.GradientTool.Properties.Resources).Assembly); + return SFXProductions.GradientTool.Properties.Resources.resourceMan; + } + } + + [EditorBrowsable(EditorBrowsableState.Advanced)] + internal static CultureInfo Culture + { + get => SFXProductions.GradientTool.Properties.Resources.resourceCulture; + set => SFXProductions.GradientTool.Properties.Resources.resourceCulture = value; + } + + internal static Bitmap block + { + get => (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject(nameof (block), SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + + internal static Bitmap color + { + get => (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject(nameof (color), SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + + internal static Bitmap disk + { + get => (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject(nameof (disk), SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + + internal static Bitmap gear__arrow + { + get => (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject("gear--arrow", SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + + internal static Bitmap hues + { + get => (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject(nameof (hues), SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + + internal static Bitmap image_export + { + get => (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject("image-export", SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + + internal static Bitmap information_frame + { + get + { + return (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject("information-frame", SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + } + + internal static Bitmap layer_shape_curve + { + get + { + return (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject("layer-shape-curve", SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + } + + internal static Bitmap magnifier_zoom + { + get + { + return (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject("magnifier-zoom", SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + } + + internal static Bitmap magnifier_zoom_actual + { + get + { + return (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject("magnifier-zoom-actual", SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + } + + internal static Bitmap magnifier_zoom_fit + { + get + { + return (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject("magnifier-zoom-fit", SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + } + + internal static string NoCodeGeneratedMessage + { + get + { + return SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetString(nameof (NoCodeGeneratedMessage), SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + } + + internal static Bitmap pipette + { + get + { + return (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject(nameof (pipette), SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + } + + internal static Bitmap wrench_screwdriver + { + get + { + return (Bitmap) SFXProductions.GradientTool.Properties.Resources.ResourceManager.GetObject("wrench-screwdriver", SFXProductions.GradientTool.Properties.Resources.resourceCulture); + } + } +} diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..d4a881d --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + {\rtf1\ansi\deff0{\colortbl;\red0\green127\blue0;}\cf1;=======================================\cf0\line\cf1; No code was generated yet.\cf0\line\cf1; \cf0\line\cf1; Create a gradient using the editor on\cf0\line\cf1; the left.\cf0\line\cf1; \cf0\line\cf1; When you are finished, press the\cf0\line\cf1; generate button on the toolbar above\cf0\line\cf1; to generate the gradient\u8217's code.\cf0\line\cf1; \cf0\line\cf1; You can then either save the generated\cf0\line\cf1; code as an ASM file, or you can paste\cf0\line\cf1; the code into your own ASM file.\cf0\line\cf1; \cf0\line\cf1; Alternatively, you can export a bitmap\cf0\line\cf1; containing the gradient you created.\cf0\line\cf1;=======================================\cf0\line\line} + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAXgIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAB3ElEQVQ4T2P8//8/A9WAFSMjwxogfoqEHwHZ96H4HiOj3XVGxo1nGBm37WdkdNoFsxmbRpghMANgmv9MmPD/XWnp/00MDAfXggxAtxHZdhAbZACy5of+/v/vhoX9X8TAcHweyAB0DUh8GyB79UNGxgyQs0E2I2uewcDgPg1kwH4ceB8Dw5n/K1b8v8PIuB6XZrABi11dwXipuzvDMg8POF7i5hazHWjIn8mTsdoM0gw2oLOzE4x7e3sZJkyYAMZ9fX0qdXV1aWVLLlUDA+rMnZCQ/7MYGE5NZ2CogmnEaQBM8+uPP64vP/JoM8iQxUBD3gMDbiqQBmIGZIziAnTNOy+8mKOrq5sWJyAQA3QBSLMHsuYCZC8AvaFcXV2dCrMZpFlbWztVVlZWJZqXl2Emks0gjWqwRBQREcEQExPDkJycnICsWVlZOUFCQkJZSkqKAWYAikaYAfb29gyOjo5K0YnpOSA/g2wGaowRFBRUEhAQYGBnZ8efVTg5ORmkpaVjQbZb2rvm8vDwxHJwcCiysLAQncfkgLaEsrGxJTMzMzsAdekBsRbUm0pAWg6IJYFYFIgFgJgHiDmAmBWImUC28EMVSEFpcahiYSAtCJXnBdLcUI1sQBrkPGYgZgQAVsH8nb4cZMMAAAAASUVORK5CYIIL + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAALQMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACq0lEQVQ4T5WTXUiTYRTHzz4KhxZ9bNKHKBuWo8TKUZNtTltjFZU09CL7wsiLclCB2kXURSUimCAE0s1ruyiCIuiDcunQoSZzbc4Nv1rp62I2ff3A5qZukm/nkS2S7aYHfhzO/zn/85z34X04EF3CtCOQlVcB29MOrynJySkgEAikXC63GlMNshuZQNpXV1frl5aWRkKhIKDJAMoSIxTdGlzHuTu0/sI9L/3AOGH90Dvb+t0ftH4eCFgaXkzZiE72iQd01xxxnKhwSk/fcNFNb72m7pHpzvlQ5GdgccU/HQh/+zGz6Hja4ms9g/ukDhQXLYmgbja4rG3uSYtvdtFrqHGyWMeSJpj3DfkC1qpGtw01CrKL3iWCpj6OtpAG9rG5/rlgZB7r2NGp4DjRCM/NtBk1GjJ1rxIR+eT0rxUSyMlY93cCMkXX0HQPahGQaF8ngja2jLURM/Nr2RNe+b2AdSyJ5B5Ig5ft3k7UaMg6aUoEZah1OjoGma6ZQNh36baNxTqWRDINXmRfZb3LjRoFGo0GCgsLQa1WQ35+PqhUKpBrrityi7smm9+PO8aZ0DAxxZhdCI+96WBsspJeOudsjzSugVKpzMAmlXWPzayitJ+5/8Tv7h0IfvHPLQ/bBoP2OmpqSHXZQ8tLh/WHiu34i/0zARr36XTH75pMZlYkSn24V1GjPnrVTyE0EolGquCKT5p3/iusa4Dj5+n1xbXd3XZWLJY84vP5eySyKtCUM3FgA9ivfQabRDKIff+psrLyRpdrlM3JOdiEZhmPxwMOhwPi3Oo4Yu9nLaanp4NcLq/yeBi2oOBYM5q1xPg/K0kkEmmFQmENmg1oPIBkI1IkE8mIvsRUjFuRFCQJ2YBwyUF8hGzuQnYiO6K5EOM2ZAuyGUlGBMjGqIeHkfMHu+afpal2Z7IAAAAASUVORK5CYIIL + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA5AIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACYklEQVQ4T2P0K7jKgA1wc/MwcHJyajAxMZUC5Z2AWBqInwLxvn///nV///79xtevXxgYQAZgwxFV9wOjax/eb1rw9MTWk2933Xn+5cTRK58O9C5/eQokDpIHW+6WcRYDe2Sd1/DJu3R/2saHO47ceH3o0ZtvZ5+8/XYOhEHs+duf7PIFyoPUMVjFHMCG5xb0Xjyx+9KLA1cffzoO0wyjrz35dKJkwqXTQL1zGXT8NmHD9+duu7sDZAAuvHT3gz1AvfcZVNxWY8O/dp5/DteM7gIg/+zha6+PAfX+YlByWYsN31+w495ukO0gxdgMWLXv4SGg3vsM6p47sOG52e3nz+678urw/ZdfTqMb8Oj113PF3RcvAfXOZXBycmJwcHBgsLOzY7C1tWWwsbFhMHfKtDIKOvRi/uYHZ28++4xiwPP33y9t2P/qlHHIyft6Acc0MAywtraWBxpS3DF5z3+ryAuvGmc8u3TyyufTz9/9uH7q6pczHfNeXrOJu3XfPPJ6oGHwGWASQ3IBUKOWm5t7zY4de/6Lioo2q1m22DkmP58LxPeB+BeUnmuf+ETDIuomA4oBQOdbBAYGtx05cua/oqJSDwsLi6qScQmDU8orDAw0gEHbZQmDnXcRA8z/PgkJKRMuXrz7X0/PYCpQszEzMzMDIyMjg6JRKQZGyTtycnIM5ubmJbduvfpvb+88D6jZBaSRFMAB9K+LiIhIC1BzNlCjPhDrALEGEKsAsTw0J4oBaUEg5gFiDiBmBWImkEUsQCwOxFJALAnEElC+KJAWBmIBIOYDYm4g5gRidqhmZiDNCABROqZrx6hIBgAAAABJRU5ErkJgggs= + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAfwMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAC/UlEQVQ4T22TX0iTURTAz5X9808up7M5UVEnGmJIujlxbnPawGTiNqe+9Eey2WaYg/woKyhB0qiHxIcQJcqKyocZGos5QyjXaFJOA03sTS0YPiRSEMTt3GGW2Qc/7na+e373nHP5iM1mg3+fcDgMEolkJxwVFSUhhKgwIGPB0dFRLy7rVqsVQKfTmfCHHWErMCwWC9TV1UUwm82S5ubmVp9vcmptbe2rVCptxWR5aWlpZC977BsbG7SlpYWrqqoC9kKlUoHJZPrN0YmJ8ZfLyx+pWl1yiyUrlUqoqalJRYGcCUw5OTlcIBAINTU1cSw5Pz8f9Ho9VFdXM07Pzb3bdDod47i3iCUYjcZUjJ/FQ07t9KlQKLjp6ekQmrnc3FzIy8sDg8EAWFV7MPiWMpTKYlZBUVubs391dXUT23fsml92djbn8XhC5eXlXEpKCqjVaqLVal1+/wz1el9EJA6HY5y1g4OcKSgoqN9zA1lZWZzb7Q4VFhZyiEWj0XROTnopk8zORirZGhoaCmDy5bS0tOQ9AhbIzMzk7rpci69jYxcWOs5RbO9aXFzc9W2u4HpMLBYfSE7GfKFQCImJicBKzsjIABwo4AxsY0LhOu3tpW4+f+2iTNbu4vMhOjp6BxRARBAfH79LgKeZcQZ90ydO0hsCwecvtbXflgh5tkjI+TlC4My26L+C9PR0q15f0e/3B2lJifqmLSHB9Rxgdstup5g88Z4Q7g1KppAeHg+Ox8b+qUAmk9UbDFWDweAHWlamGZDL5fWtWOYYQI8bJd87Oigme/yEXGCCpzirh2xg2y00VFYa783Pf6JarX44KSmpgc2kWCQCTGabe56g5EdXF8Vkn4+QS38LGisqjjxYWlqnOp1hBHtrjImJ2XU77HMbQcl9lPzs7qaY/OoxwNVIBbi5d2UljCcbHolEIjuGpIiYvUKEiAjZh0g6AW4Po4TdziBAEAHg8XiNAoGgj8/nO/HvYeQgko4ksg6R/UgKokAOuQAG7qCkGeC8BgO/APJtDfDgdBQUAAAAAElFTkSuQmCCCw== + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAngIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACHElEQVQ4T6WTXUhTYRjH366CCPIu86YgkfRmu8jk+IFNadTo7CLa0Allk/C4UnMaU4ezBDtbJzDpY0MwR5YtqrVcWPax6sYQVlchjKiLwsGkCLXz6nFt/857uuzGsQd+L88L7+/PwwvPFgAkr2IB+UAsg4O8SmuO8Mc9HsIgx9xuQZ0gp2KOCnMJMbtcjkw2C26YolqkqJMoDl6mqFH7o1cpGvwy7OMybr6SEXz2HqHZWZiczrN1bW2kpqWFEFN39xklk0Hn1Br6H1H4ZiiGn1J4VSTWT8sQozJef5IxEYlok5bbbOf3NzaWl5nNhBzq6GiX02mcvD4C8UkM4ThFJL6GtwsUj+d/4G7sM+48n8N4OAp/KITFVEoLUeW+Up6vIAZBOLe8sYEyBw+u9wSuTL/AXGIF7xZ+I/6FIpFUsLT8B0o6+98/7amv95Aqu935c30dBeZa7LIexr7TDeB6HLD6fOgaC+LiZAjeyXuQbgUhBgL4lkxqQTs5bqiwsrKKHGhq6klRilLbCHTNfnCO2zC6wrB6YxDGPqLv4Vd4Xy7hxvwKLoyOavIOne5SgV5frYYQordYXElZhv5UABXCBGq77uOIOwqL+AbN1z6gPZhA74NFDM38woB/Cv2ShBKTyb3bYCB7jUbCjoGUouD76uqmYG+Zw2QtYHtxcSsbKRdUR9hWVEQYrLaqFKqw22Zgb5nzr/JZJG2T8w34C5B1S24sW0XcAAAAAElFTkSuQmCCCw== + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAfgIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAB/ElEQVQ4T4WST0hUQRzHv3P1EEGEKIt0kU1eS1JpgWW7/mOxkq3cQwuGCHssOrSCGokS/aEOCYkQuhGKsR4WEg/92dpD0CEHImIz2y2ISolahLrvr/mN74277wkNfJj5zvzmM/OGJ0R7P9A5ANOE6FHju1sTZnQJRIsmPU+ilHkAiGtZN5nmxfW/vcslcuCs6jLuWiIC+oN9EFefllMIPflFBxc+GzirmoKrTl1ICbJ837oAxOBjh/yxpXVqfPTJwFmt58tqYE3EtgRa4rMgLqaY1SPpr7Rv9oOBM8/b6whOW4guoFKgJbUNEPGHKwdSBfIn3xk487wCwfsNerMRvATCCukQa4ys8YbA3IpBC2JTueCU32w2gmdAeu3EyWIpMUjM7MAQRSMjmr2d5zZq+jaxLh//0ZuCLCOsH3FJnf6nqYt+Yo+H8TOQN2UHpYrxCm69DxUjc0hrQVoJfgda6Rt8Hq70QF5/00aTq6eJewfO3dOQWjCvBN/rmymPGg+Jbsjx1600kTtF3Dtw7rhnC5JK8MUXoBx2e7jQBTn6qoXuvA0T9w6cj962BZNKUKjbTx931XuIhyBHsof11bl34HxozBacB2aGlWQ7zrZADr1oohvL7RWfwNlK2AL1/1QpqhW1Lvw72jC/Mwq5HWptRj/if5pb6mQ+sIoF/wB1k7lyQifSuAAAAABJRU5ErkJgggs= + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAZQMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAC40lEQVQ4T6XTbUhTYRQH8KOuZRBBgZrFKogIe8E+VhRl9ELQt4RhVJjYC5ahg0Q0i+bMZsveQAhz5HxpoaaJTp2ao7KGL5mbXbdiFLjMzDGuounm7r+jH2ZC0IcuHB6ey3N+zznPvU8IAPqvZw6oKCPqf070MZ/ImkAR/QdJ6dgRlueIlJc45CtLHLJteQMUp+yjExECachONWQhM81vvgi4TXHO66sMoyVn+6ZfGj3SW4tfan/lnzY0eUYTi/qcq7INAt2K+ztQT4ecVYqWmc9PRdjKAeM1IFcFqHjMKQOKuzDzwCY61z5tsVPdoUUVlFdTtK17hWna82QC7kLAyomNakCvA3SPAE09cKWTxy+YVn+fsC23msxkiQ62oLdQquCOH5qVioGJdGCoALDrgfYqoLoFKP0AFH4FMkTM5gYg7HMPGcmaGgS0Vqr7NKn95UYmvLiB2VlO9jYDri6gxwm0jiFg8GH8JvCNi/uQNPlLR9a6IHD+NTlsgSKpE5dhhxZDeIYJWBGYcUMamcJULzBcCwh3gXdpQMeFgJRCrx1B4GAHuZoDt6RKpKKRgTcMDDAwjJ/4IQKD7zmRgSYGjAzoTwakI9ThCgLrzNSWN57sK+AK7nELpTCgmYEujKGHgVYGKozAQ24hLwW4eGDct4HMbUEgpIKydg7GiukMpCMHBaiEHt2oYqB6nM+wn8+wms9QAySeBmLWD4qhVJsVBEhNCrlJLhwTT/mSuQUVt6BGD3TwQMeAxsZfkVtI1AJ7j4s+2RKTQPRYsQCk8W2oJOWyhij3fu9VfwJqkIxeXGLgEgPnGEh4AezJ8frDFQ1uoiol0f2FX3n+MsVwpIUpZfoYQdGpEneNNvuO+kekox6/tLt91Lcus1OUxeoFkqs4ect8ykIFRDKeR3FspY1LD9OZzXdIE2+h/AwXZee7KEFjoa1Jdyh802Fes51jNYfsTyCUXyzniORY84+Y22hubegc8Bv+OkVzATHVkQAAAABJRU5ErkJgggs= + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAGwMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACmUlEQVQ4T5WTX0hTcRTHz/4UDi36s0l/RJlYjhIrR21sc9oaq8ikMR+yIox8KIUK1Jeoh0pEMEEIopcbPhSC4UtgWg2RNJmmrY2pZdlVUa+bTk3vnG7k7ZwxI9le+sGH7zm/8/ueey73/kQQXfKUE5CpLYPdKccjO4mJSSCTyVRisbgKUxOyH5lCOtbX1+uCweDXQIAHNJWDvqgRCu8MbuLiXdZ6+f44+7BxytHa63/3g+MdHz1LnfVN3j7apzp5wHJjIIYzZU5VwS0X22TnHGO+wNhiIDS9tBLmCIqbO2Yc57FO50B3pTMezO16l2PUy49hXSDmFtYiSkz6gxOVDe4+jBnIKnwdD5Z5M9pGDbAuzPOhRYpJKaf4pZ21Y8xChuVVPEJvnVwnHfT6gwKNPulf+UxK+a+V8HTX0GwPekOQbm6JB9vY9vM9NcC6sBb+vUxmUsqpQXPH+AeMWcg82x4PprzGOTA+G5jAukD4/KsRJRYCIa6izuXGmAGTyQT5+flgNBohNzcXDAYDaEw3dTm2rpkW+9T3ueW1v1+ApuBXw77WrjmPuqiXzb7Qo4ppoNfr07BJRe0Tu6Ar/uJ78Ixz93r4T9z86nDfIN9fy3iHDFdHWE3xsPWYrR9/sX8mQOMhi+X0vfZ2u6BQJD86qKs2nrzOMQiLhKLK5F2bVGkvfYNNDXB8rdVqq+nu7heUyvTHUqn0QLq6EkylvhiwARw2v4BtCjVsvP+5kpLSBpdrVMjOPvoUzWqJRAIikQiUOVUxbNyfiKampoJGo6kcGfEJeXmnnqPZTMb/WQkKhcIsl8ur0VyOxiNIFqJCMpC06E1MRt2JJCEJyBZETA+SIlTch+xF9kRzOeouZAeyHUlEZMjWqEeCKvoDhfKfBbfK0SIAAAAASUVORK5CYIIL + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAAgMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACgElEQVQ4T6WQXUiTURjHz3JLhhl6M/uaRCkSbmEbuK0uBpZYc9H8uIjQZFBIVlfSwKgIQUQQam1hEJRSGdRNyiLITPDjFfa+sU9Tc9myTYf3I/Lm6fzfV2tBdNOBH8/D8/z/f845KiJi/3UQ4HA4mNPpZA0NDayxsVGuzc3NNk77JrbcHbTwAJYb4HK5jnLhJV73om5sbFA2m6XcGTR/Daivrz/m8Xjurq+vk9vtvs5Fl1dX0wTQY4YdNND+cYO6ujrGuZpMJkkUg5ROpygQCCylUikC6BOJhLyDBtpNj/IEm83G7Hb7vqampluRSJjC4RAtL3+mlZWvMugxww4aaOGxWCxKgNVqtfNBJxgaGkzE4zEaHn42bzAY7gP0mGG3pYPnV4DJZPJIkkgTE+9pdlagaDRKRuPh3ry8PAbQY4YdNNDCw1FuUFlZ2TU9PU1jY2OEGot9pKoqU7dKpWIAPWa5Gng4SkB5eXltWVnZDeDz+b+EQnEaHX0XMpurbwL0mGFXfe25eKT19kt4OEpAaWkp0+v1+00mc78gSDQ+PkWLiynKZL7LoMcMO2ufmLF4P8UsvuUW/jAlQKfTgW5BCNPIyFuanJTI73+YDAbj1PE4TMf7xR9OX4RO3vlAp/1RGkgTcbNk7Am3yAHFxcXgVE1N7VNRXKCKikPeoqKiHkGI0Ym+Wbr3jahjjqg18pvOBaKDXVOSHICjVquZVqt1FBQU9Obn5x9AnZ9fo4sDQdK1Da2VtL+KyfXCiyXrDNGujtfS7itvlBvAzynh8G9lZqDRaNp4UB9AvzUvPDs4V3juSWRny/B5HqL8AT/bODs4Os6ef7H9zINHGqfXvelhPwFdc8W1rfrU+wAAAABJRU5ErkJgggs= + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAdgMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAC9ElEQVQ4T02PbUhTYRiGXxUZJvQjiREUIdUsyVwqCCtXjJaT5dycZX6naCUMIz/AybIvEI2IoDT8IcMF/pCZphAI2ZZSbuk8anocaiynCSn6I/rt3fu8WvTCxbnP897XwzkROTk5LCIigkVGRoon5yDnFGNMydnPofOL8xPAAmeTw3Z2dhg9GS0wm80sNzdXYbVaM+rq6hp9Pt/sxsYG1tfXBZTHx8dna2trG6lDXXLI/btAYbFYsp1OZzcJrwcW0PB0GkZbQEDZ1S9jbW0VXV1d3dTlCxRigclkIi7wC1coFEKpfQLXm5ZQ83wb9R2/Udf+G7ZnW7jWuCjulpeX0NnZ6SKHXGY0GpU2m83x/XsIhQ0+lD8O4/aTTWTfmee/uHso32zdQHHzbicYDKK6utpBLjMYDDqP58Ncu8uP3Pp5lD0Mw1wbhP5W4N8CyjQrdIRwpWYGL7vHMTQ0OEcu0+v1xfRZVQ4vSh+EkFktCXSVX6AyvMExvRsJWQM4frlPoL0xJrqTkxMgl+l0OpskSThX9B5F977hYoUfausITmQN8tIkAoEAjhve8vchQcrVEdEdGxsDuUyr1dZQMT1/GNl355Fo9iDBNAKVcVjIsiyLTDPiTN5H0fV6vSCXaTSackmaRkn9MLSVEhLz/IKT5lEhh8Nhkf/OT+d9El2vdxTksvT09MzeXvdC2ysvzl7zILUsiKRC/iV5E0Le2toSmWbEqZz3aG33wOl0LZDL0tLSDlks1papqTlcKhtCcr4fKeUrSCr4KuTt7W2R1WUrSLT6RMfvn4bZbGkhl6nVapacnGxobn7knplZwvl8N45efofEAhnqih8CyjSjO0lahMPx0E0OuUypVLL4+PgYlUpVbLc/6JflNbR1fIapsg8HUl8KKNNMlldht9/vpy455NKJ5OxTKBSH4+LiSjSajBc9PYPLi4ub+B+a0R11ePcIOXsui+IhjqPipERHR+tiYmKqYmNjmzitezTRjO6ow0nYc6L+AHuNFJyvBvpKAAAAAElFTkSuQmCCCw== + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAALAIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABqklEQVQ4T6WTyS9DURTGT/MIUqlGtdGmUhUxVSkSLBALC4mFUkNL2BgiaI1F7LFiaYMEGyJinu0sxYo/gaUl6/rO7btNX4ghXvJ755537/fdc4enq5i9rSQi5l4FIfq8PT/Sy90mvb88xb5xI927TLokA73u9hOVz9wEI5HIA0fAeYySyQsqHj8j19ipwNm2ROaqgDAwda4RdERl4etqEFIj5wIpjjdgk6LQCeUO7ZO1ZytmQJ7pKz8wAm5rxF8ZFAaPiREVlE5dMo2giGd1T5yLclkokUuQFWgMWAQcoANivRz8awOekYGgDrTCwA4UtGtAmOO3FcR1Kmh7gB/0gTk+HY5qzt892ERFs4R4d7lG3mkMqgXzHJEnIGaBdlBfMHpEjNhES3WXOF9pxGLVQAzi2eLy1PyRw27gzBs+iBrIR293CzO+KAwLpUG2b1G0WQRKgfeTgeaufpGk2FziAgETGMgZ3NNW8JMB96eV+cjRt9OQ3b+7wFEuQYc+BSSCZKAHBmDk/wZkAAvIBFZb7/YKn44axbx/MjC1rDRn+NdXzYGNJlEBv/7DBwSbST67PPGnAAAAAElFTkSuQmCCCw== + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAARwIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABxUlEQVQ4T6XOT0iTcRzH8e+eZ3cPHYSILt27SOBVvFR4CGSJovkvpUN0CjwoOoiazq1N2Jgomkq1mQhNCN2mOLdoI+hQmqioKYlhDNQwGQz26fd5dFAgT0aD1zZ+v8/72SwA5L9eTbpHmnTvPaXX1tXVeh7cnjQekUb1prhXX/5QfwbI/wU33LJhKw26mzyLIxnk8nlkczlT3HDLhq3U6y7q+zj8HT9VfHB8bIobbtmwlTu6k3wfBnaxn83i2+GhKW64ZcNWajUHBd4HvmJP/fqXTMYUN9yyYSs12mMaSPm2sLlxgJ2jI1PccMuGrVRrj2go6V1H1LF4LtyyYStVmp1G4u5V9NweQ7dt9Ey8K0j7t8GGrdi0Tno+2/MZruoXSKXSSCSSf+AZ7161JeGpDeFt3wbYsJVKrZ1CkSef4K0bRywWR8cNv2FqatrAM97xAYG7r7HwdA1s2MotrY0mY91L8DVOIhyOGp8UCoUNhTM+4Nn9Gcy7VsCGrVywXJJSS2XZTcuDqP364P7ERAT9LWFDMPjGUDjjA4IP45hzLoN7tnxdVq5ekWvN5dLyzmq1Os/Cu9+VSMXwaStF6kuxcvEfsSn6Bb/OPjvwg4uNAAAAAElFTkSuQmCCCw== + + + AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAegAAAAJCTXoAAAAAAAAAdgAAACgAAAAHAAAAAQAAAAEABAAAAAAAAAAAAMQOAADEDgAAEAAAABAAAAAAAAD/AACA/wCAAP8AgID/gAAA/4AAgP+AgAD/gICA/8DAwP8AAP//AP8A/wD/////AAD//wD/////AP//////m67NkAs= + + \ No newline at end of file diff --git a/Properties/Settings.cs b/Properties/Settings.cs new file mode 100644 index 0000000..ce64230 --- /dev/null +++ b/Properties/Settings.cs @@ -0,0 +1,21 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.Properties.Settings +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System.CodeDom.Compiler; +using System.Configuration; +using System.Runtime.CompilerServices; + +#nullable disable +namespace SFXProductions.GradientTool.Properties; + +[CompilerGenerated] +[GeneratedCode("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] +internal sealed class Settings : ApplicationSettingsBase +{ + private static Settings defaultInstance = (Settings) SettingsBase.Synchronized((SettingsBase) new Settings()); + + public static Settings Default => Settings.defaultInstance; +} diff --git a/Resources/InvertedCrosshair.cur b/Resources/InvertedCrosshair.cur new file mode 100644 index 0000000..a9d4349 Binary files /dev/null and b/Resources/InvertedCrosshair.cur differ diff --git a/Resources/blank.cur b/Resources/blank.cur new file mode 100644 index 0000000..cf49ae3 Binary files /dev/null and b/Resources/blank.cur differ diff --git a/SilentException.cs b/SilentException.cs new file mode 100644 index 0000000..548f82c --- /dev/null +++ b/SilentException.cs @@ -0,0 +1,14 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.SilentException +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal sealed class SilentException : ApplicationException +{ +} diff --git a/UpgradeLog.htm b/UpgradeLog.htm new file mode 100644 index 0000000..ca2d72a --- /dev/null +++ b/UpgradeLog.htm @@ -0,0 +1,329 @@ + + + + Migration Report +

+ Migration Report - GradientTool

Overview

ProjectPathErrorsWarningsMessages
SolutionGradientTool.sln012
GradientToolGradientTool.csproj0051

Solution and projects

Solution

Message
GradientTool.sln: + Visual Studio needs to make non-functional changes to this project in order to enable the project to open in released versions of Visual Studio newer than Visual Studio 2010 SP1 without impacting project behavior.
+ Show 2 additional messages +
GradientTool.sln: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientTool.sln
GradientTool.sln: + Solution migrated successfully
+ Hide 2 additional messages +

GradientTool

Message
+ Show 51 additional messages +
GradientTool.csproj: + Project file successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientTool.csproj
Gradient.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Gradient.cs
GradientType.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientType.cs
GradientColourspace.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientColourspace.cs
HermiteConfiguration.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HermiteConfiguration.cs
CodeGen.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\CodeGen.cs
BitmapCalc.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\BitmapCalc.cs
Combiner.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Combiner.cs
Config2.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Config2.cs
Utils.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Utils.cs
DoubleBufferedPanel.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\DoubleBufferedPanel.cs
Program.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Program.cs
Vector.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Vector.cs
GradientStop.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientStop.cs
Eyedropper.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Eyedropper.cs
AboutBox.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\AboutBox.cs
GradientControl.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientControl.cs
SilentException.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\SilentException.cs
HermiteSettings.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HermiteSettings.cs
ColourSelector.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\ColourSelector.cs
HDMA\Channel.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Channel.cs
HDMA\CombinedChannel.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\CombinedChannel.cs
HDMA\Settings2.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Settings2.cs
HDMA\Mode0Channel.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Mode0Channel.cs
HDMA\DataPoint.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\DataPoint.cs
HDMA\CompressedDataPoint.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\CompressedDataPoint.cs
HDMA\Mode3Channel.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Mode3Channel.cs
HDMA\Generator2.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Generator2.cs
HDMA\GradientChannels.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\GradientChannels.cs
HDMA\GradientChannelsHelper.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\GradientChannelsHelper.cs
HDMA\Mode2Channel.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Mode2Channel.cs
HDMA\ChannelType.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\ChannelType.cs
HDMA\Configuration\Mode3ChannelPropertyTab.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode3ChannelPropertyTab.cs
HDMA\Configuration\Mode0ChannelPropertyTab.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode0ChannelPropertyTab.cs
HDMA\Configuration\Mode2ChannelPropertyTab.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode2ChannelPropertyTab.cs
HDMA\Configuration\UnconfigurablePropertyTab.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\UnconfigurablePropertyTab.cs
HDMA\Configuration\ColourChannelsRef.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\ColourChannelsRef.cs
Properties\Settings.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Properties\Settings.cs
Properties\Resources.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Properties\Resources.cs
AssemblyInfo.cs: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\AssemblyInfo.cs
AboutBox.resx: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\AboutBox.resx
ColourSelector.resx: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\ColourSelector.resx
Config2.resx: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Config2.resx
HDMA\Configuration\Mode0ChannelPropertyTab.resx: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode0ChannelPropertyTab.resx
HDMA\Configuration\Mode2ChannelPropertyTab.resx: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode2ChannelPropertyTab.resx
HDMA\Configuration\Mode3ChannelPropertyTab.resx: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode3ChannelPropertyTab.resx
HermiteConfiguration.resx: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HermiteConfiguration.resx
Program.resx: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Program.resx
Properties\Resources.resx: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Properties\Resources.resx
Resources\blank.cur: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Resources\blank.cur
Resources\InvertedCrosshair.cur: + File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Resources\InvertedCrosshair.cur
+ Hide 51 additional messages +
\ No newline at end of file diff --git a/Utils.cs b/Utils.cs new file mode 100644 index 0000000..21a106f --- /dev/null +++ b/Utils.cs @@ -0,0 +1,393 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.Utils +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using SFXProductions.GradientTool.HDMA; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Windows.Forms; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal static class Utils +{ + private static Dictionary s_records = new Dictionary(); + private static SaveFileDialog s_saveDialog = new SaveFileDialog(); + + internal static int IndexOfGradientStop(this IList gradientStopList, ulong id) + { + for (int index = 0; index < gradientStopList.Count; ++index) + { + if ((long) gradientStopList[index].Id == (long) id) + return index; + } + return -1; + } + + internal static Decimal Clamp(this Decimal value, Decimal max = 100M, Decimal min = 0M) + { + if (value < min) + value = min; + else if (value > max) + value = max; + return value; + } + + internal static double Clamp(this double value, double max = 1.0, double min = 0.0) + { + if (value < min) + value = min; + else if (value > max) + value = max; + return value; + } + + internal static int Clamp(this int value, int max, int min = 0) + { + if (value < min) + value = min; + else if (value > max) + value = max; + return value; + } + + internal static bool HasFlag(this ChannelType chType, ChannelType flag) + { + return (chType & flag) == flag; + } + + internal static bool EditGradientStop( + IWin32Window owner, + ref GradientStop gradientStop, + string title = null) + { + using (ColourSelector colourSelector = new ColourSelector()) + { + colourSelector.SetColour(gradientStop.Colour); + colourSelector.SetOffset(gradientStop.Position); + if (title != null) + colourSelector.Text = title; + if (colourSelector.ShowDialog(owner) == DialogResult.OK) + { + gradientStop.Colour = colourSelector.GetColour(); + gradientStop.Position = colourSelector.GetOffset(); + return true; + } + } + return false; + } + + internal static unsafe string PromptForFilename( + IWin32Window owner, + string filter, + string defaultExt, + string defaultName = null, + string typeId = null) + { + string defaultName1 = defaultName; + string typeId1 = typeId; + return Utils.PromptForFilename(owner, filter, defaultExt, (int*) null, defaultName1, typeId1); + } + + internal static unsafe string PromptForFilename( + IWin32Window owner, + string filter, + string defaultExt, + int* pFilterIndex, + string defaultName = null, + string typeId = null) + { + string str = string.Empty; + string key = typeId ?? filter; + if (!Utils.s_records.ContainsKey(key)) + Utils.s_records.Add(key, str); + else + str = Utils.s_records[key]; + Utils.s_saveDialog.InitialDirectory = str; + Utils.s_saveDialog.FileName = defaultName ?? string.Empty; + Utils.s_saveDialog.DefaultExt = defaultExt; + Utils.s_saveDialog.Filter = filter; + if ((IntPtr) pFilterIndex != IntPtr.Zero && *pFilterIndex > 0) + Utils.s_saveDialog.FilterIndex = *pFilterIndex; + if (Utils.s_saveDialog.ShowDialog(owner) != DialogResult.OK) + return (string) null; + if ((IntPtr) pFilterIndex != IntPtr.Zero) + *pFilterIndex = Utils.s_saveDialog.FilterIndex; + Utils.s_records[filter] = Path.GetDirectoryName(Utils.s_saveDialog.FileName); + return Utils.s_saveDialog.FileName; + } + + internal static ushort RoundToWord(double v) + { + return (ushort) Math.Min(v + 0.5, (double) ushort.MaxValue); + } + + internal static byte RoundToByte(double v) => (byte) Math.Min(v + 0.5, (double) byte.MaxValue); + + internal static void Get5BitChannels( + this Color colour, + out byte red, + out byte green, + out byte blue) + { + red = Utils.RoundToByte((double) colour.R * ((double) byte.MaxValue / 31.0)); + green = Utils.RoundToByte((double) colour.G * ((double) byte.MaxValue / 31.0)); + blue = Utils.RoundToByte((double) colour.B * ((double) byte.MaxValue / 31.0)); + } + + internal static Vector ToColourspace(this Color colour, GradientColourspace colourspace) + { + switch (colourspace) + { + case GradientColourspace.RGB: + return new Vector() + { + X = (double) colour.R / (double) byte.MaxValue, + Y = (double) colour.G / (double) byte.MaxValue, + Z = (double) colour.B / (double) byte.MaxValue + }; + case GradientColourspace.HSV: + case GradientColourspace.HSL: + case GradientColourspace.HSY: + return new Vector() + { + X = ((double) colour.R / (double) byte.MaxValue), + Y = ((double) colour.G / (double) byte.MaxValue), + Z = ((double) colour.B / (double) byte.MaxValue) + }.HDRToColourspace(colourspace); + default: + throw new ArgumentException("Invalid colourspace."); + } + } + + internal static Vector HDRToColourspace(this Vector vector, GradientColourspace toColourspace) + { + switch (toColourspace) + { + case GradientColourspace.RGB: + case GradientColourspace.RGBV: + case GradientColourspace.RGBB: + case GradientColourspace.RGBL: + return vector; + case GradientColourspace.HSV: + case GradientColourspace.HSL: + case GradientColourspace.HSY: + double num1 = Math.Max(vector.X, Math.Max(vector.Y, vector.Z)); + double num2 = Math.Min(vector.X, Math.Min(vector.Y, vector.Z)); + if (num1 <= 0.0) + return new Vector() + { + X = double.NaN, + Y = double.NaN, + Z = 0.0 + }; + double num3 = num1 - num2; + double num4 = double.NaN; + if (num3 > 0.0) + { + if (num1 == vector.X) + num4 = (vector.Y - vector.Z) / num3 % 6.0; + else if (num1 == vector.Y) + num4 = (vector.Z - vector.X) / num3 + 2.0; + else if (num1 == vector.Z) + num4 = (vector.X - vector.Y) / num3 + 4.0; + } + double d = num4 / 6.0; + double num5 = d - Math.Floor(d); + switch (toColourspace) + { + case GradientColourspace.HSV: + return new Vector() + { + X = num5, + Y = num3 / num1, + Z = num1 + }; + case GradientColourspace.HSL: + double num6 = (num1 + num2) / 2.0; + return new Vector() + { + X = num5, + Y = num3 / (num6 <= 0.5 ? 2.0 * num6 : 2.0 - 2.0 * num6), + Z = num6 + }; + default: + double num7 = (vector.X + vector.Y + vector.Z) / 3.0; + return new Vector() + { + X = num5, + Y = 1.0 - 3.0 / (vector.X + vector.Y + vector.Z) * num2, + Z = num7 + }; + } + default: + throw new ArgumentException("Invalid colourspace."); + } + } + + internal static double GetRGBValue(this Vector vector) + { + return Math.Max(vector.X, Math.Max(vector.Y, vector.Z)); + } + + internal static double GetRGBBrightness(this Vector vector) + { + return (vector.X + vector.Y + vector.Z) / 3.0; + } + + internal static double GetRGBLightness(this Vector vector) + { + return (Math.Max(vector.X, Math.Max(vector.Y, vector.Z)) + Math.Min(vector.X, Math.Min(vector.Y, vector.Z))) / 2.0; + } + + internal static Vector Adjust(this Vector vector, double orig, double @new) + { + if (orig == 0.0) + return new Vector(); + double num = @new / orig; + vector.X *= num; + vector.Y *= num; + vector.Z *= num; + return vector; + } + + private static void GetR1G1B1( + double hue, + double chroma, + out double r1, + out double g1, + out double b1) + { + hue = (hue - Math.Floor(hue)) * 6.0; + if (double.IsNaN(hue)) + hue = 0.0; + double num = chroma * (1.0 - Math.Abs(hue % 2.0 - 1.0)); + if (double.IsNaN(hue) || double.IsNaN(chroma) || chroma <= 0.0) + r1 = g1 = b1 = 0.0; + else if (hue < 1.0) + { + r1 = chroma; + g1 = num; + b1 = 0.0; + } + else if (hue < 2.0) + { + r1 = num; + g1 = chroma; + b1 = 0.0; + } + else if (hue < 3.0) + { + r1 = 0.0; + g1 = chroma; + b1 = num; + } + else if (hue < 4.0) + { + r1 = 0.0; + g1 = num; + b1 = chroma; + } + else if (hue < 5.0) + { + r1 = num; + g1 = 0.0; + b1 = chroma; + } + else + { + r1 = chroma; + g1 = 0.0; + b1 = num; + } + } + + internal static Vector ToHDR(this Vector vector, GradientColourspace fromColourspace) + { + switch (fromColourspace) + { + case GradientColourspace.RGB: + case GradientColourspace.RGBV: + case GradientColourspace.RGBB: + case GradientColourspace.RGBL: + return vector; + case GradientColourspace.HSV: + double chroma = vector.Y * vector.Z; + double r1_1; + double g1_1; + double b1_1; + Utils.GetR1G1B1(vector.X, chroma, out r1_1, out g1_1, out b1_1); + double num1 = vector.Z - chroma; + r1_1 += num1; + double num2 = g1_1 + num1; + double num3 = b1_1 + num1; + return new Vector() { X = r1_1, Y = num2, Z = num3 }; + case GradientColourspace.HSL: + double num4 = (1.0 - Math.Abs(2.0 * vector.Z - 1.0)) * vector.Y; + if (double.IsNaN(num4)) + num4 = 0.0; + double r1_2; + double g1_2; + double b1_2; + Utils.GetR1G1B1(vector.X, num4, out r1_2, out g1_2, out b1_2); + double num5 = vector.Z - num4 * 0.5; + r1_2 += num5; + g1_2 += num5; + double num6 = b1_2 + num5; + return new Vector() { X = r1_2, Y = g1_2, Z = num6 }; + case GradientColourspace.HSY: + return Utils.HSYToRGB(vector); + default: + throw new ArgumentException("Invalid colourspace."); + } + } + + private static Vector HSYToRGB(Vector v) + { + v.X -= Math.Floor(v.X); + v.X *= 360.0; + Vector rgb = new Vector(); + if (0.0 < v.X && v.X <= 120.0) + { + rgb.Z = 1.0 / 3.0 * (1.0 - v.Y); + rgb.X = 1.0 / 3.0 * (1.0 + v.Y * Math.Cos(v.X) / Math.Cos(60.0 - v.X)); + rgb.Y = 1.0 - (rgb.X + rgb.Z); + } + else if (120.0 < v.X && v.X <= 240.0) + { + v.X -= 120.0; + rgb.X = 1.0 / 3.0 * (1.0 - v.Y); + rgb.Y = 1.0 / 3.0 * (1.0 + v.Y * Math.Cos(v.X) / Math.Cos(60.0 - v.X)); + rgb.Z = 1.0 - (rgb.X + rgb.Y); + } + else + { + v.X -= 240.0; + rgb.Y = 1.0 / 3.0 * (1.0 - v.Y); + rgb.Z = 1.0 / 3.0 * (1.0 + v.Y * Math.Cos(v.X) / Math.Cos(60.0 - v.X)); + rgb.X = 1.0 - (rgb.Y + rgb.Z); + } + return rgb; + } + + internal static Color ToRGB(this Vector vector, GradientColourspace fromColourspace) + { + switch (fromColourspace) + { + case GradientColourspace.RGB: + return Color.FromArgb((int) Utils.RoundToByte(vector.X * (double) byte.MaxValue), (int) Utils.RoundToByte(vector.Y * (double) byte.MaxValue), (int) Utils.RoundToByte(vector.Z * (double) byte.MaxValue)); + case GradientColourspace.HSV: + case GradientColourspace.HSL: + case GradientColourspace.HSY: + vector = vector.ToHDR(fromColourspace); + return Color.FromArgb((int) Utils.RoundToByte(vector.X * (double) byte.MaxValue), (int) Utils.RoundToByte(vector.Y * (double) byte.MaxValue), (int) Utils.RoundToByte(vector.Z * (double) byte.MaxValue)); + default: + throw new ArgumentException("Invalid colourspace."); + } + } +} diff --git a/Vector.cs b/Vector.cs new file mode 100644 index 0000000..247a9ab --- /dev/null +++ b/Vector.cs @@ -0,0 +1,306 @@ +// Decompiled with JetBrains decompiler +// Type: SFXProductions.GradientTool.Vector +// Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null +// MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B +// Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe + +using System; + +#nullable disable +namespace SFXProductions.GradientTool; + +internal struct Vector +{ + public double X; + public double Y; + public double Z; + + public static Vector LerpRGB(Vector a, Vector b, double x, GradientColourspace gamma) + { + if (x > 1.0) + x = 1.0; + else if (x < 0.0) + x = 0.0; + double num = 1.0 - x; + Vector vector; + vector.X = a.X * num + b.X * x; + vector.Y = a.Y * num + b.Y * x; + vector.Z = a.Z * num + b.Z * x; + switch (gamma) + { + case GradientColourspace.RGBV: + vector = vector.Adjust(vector.GetRGBValue(), a.GetRGBValue() * num + b.GetRGBValue() * x); + break; + case GradientColourspace.RGBB: + vector = vector.Adjust(vector.GetRGBBrightness(), a.GetRGBBrightness() * num + b.GetRGBBrightness() * x); + break; + case GradientColourspace.RGBL: + vector = vector.Adjust(vector.GetRGBLightness(), a.GetRGBLightness() * num + b.GetRGBLightness() * x); + break; + } + return vector; + } + + public static Vector LerpH(Vector a, Vector b, double x) + { + if (x > 1.0) + x = 1.0; + else if (x < 0.0) + x = 0.0; + double num1 = 1.0 - x; + if (double.IsNaN(a.X)) + a.X = b.X; + else if (!double.IsNaN(b.X)) + { + double num2 = a.X >= b.X ? a.X - b.X : 1.0 + a.X - b.X; + double num3 = a.X >= b.X ? 1.0 + b.X - a.X : b.X - a.X; + a.X = num3 <= num2 ? a.X + num3 * x : a.X - num2 * x; + if (a.X < 0.0) + ++a.X; + else if (a.X > 1.0) + --a.X; + } + if (double.IsNaN(a.Y)) + a.Y = b.Y; + else if (!double.IsNaN(b.Y)) + a.Y = a.Y * num1 + b.Y * x; + a.Z = a.Z * num1 + b.Z * x; + return a; + } + + public static Vector CerpRGB(Vector a, Vector b, double x, GradientColourspace gamma) + { + return Vector.LerpRGB(a, b, (1.0 - Math.Cos(x * Math.PI)) / 2.0, gamma); + } + + public static Vector CerpH(Vector a, Vector b, double x) + { + return Vector.LerpH(a, b, (1.0 - Math.Cos(x * Math.PI)) / 2.0); + } + + private static double cubic( + double v0, + double v1, + double v2, + double v3, + double x, + bool catmullRom) + { + double num1 = x * x; + double num2; + double num3; + double num4; + double num5; + if (catmullRom) + { + num2 = -0.5 * v0 + 1.5 * v1 - 1.5 * v2 + 0.5 * v3; + num3 = v0 - 2.5 * v1 + 2.0 * v2 - 0.5 * v3; + num4 = -0.5 * v0 + 0.5 * v2; + num5 = v1; + } + else + { + num2 = v3 - v2 - v0 + v1; + num3 = v0 - v1 - num2; + num4 = v2 - v0; + num5 = v1; + } + return num2 * x * num1 + num3 * num1 + num4 * x + num5; + } + + public static Vector CubicRGB( + Vector pre, + Vector a, + Vector b, + Vector post, + double x, + bool catmullRom, + GradientColourspace gamma) + { + if (x > 1.0) + x = 1.0; + else if (x < 0.0) + x = 0.0; + Vector vector = new Vector() + { + X = Vector.cubic(pre.X, a.X, b.X, post.X, x, catmullRom), + Y = Vector.cubic(pre.Y, a.Y, b.Y, post.Y, x, catmullRom), + Z = Vector.cubic(pre.Z, a.Z, b.Z, post.Z, x, catmullRom) + }; + switch (gamma) + { + case GradientColourspace.RGBV: + vector = vector.Adjust(vector.GetRGBValue(), Vector.cubic(pre.GetRGBValue(), a.GetRGBValue(), b.GetRGBValue(), post.GetRGBValue(), x, catmullRom)); + break; + case GradientColourspace.RGBL: + vector = vector.Adjust(vector.GetRGBLightness(), Vector.cubic(pre.GetRGBLightness(), a.GetRGBLightness(), b.GetRGBLightness(), post.GetRGBLightness(), x, catmullRom)); + break; + } + return vector; + } + + public static Vector CubicH( + Vector pre, + Vector a, + Vector b, + Vector post, + double x, + bool catmullRom) + { + if (x > 1.0) + x = 1.0; + else if (x < 0.0) + x = 0.0; + Vector vector = new Vector(); + vector.X = vector.Y = double.NaN; + if (double.IsNaN(a.X) && !double.IsNaN(b.X)) + a.X = b.X; + else if (double.IsNaN(b.X) && !double.IsNaN(a.X)) + b.X = a.X; + if (double.IsNaN(pre.X) && !double.IsNaN(a.X)) + pre.X = a.X; + if (double.IsNaN(post.X) && !double.IsNaN(b.X)) + post.X = b.X; + if (!double.IsNaN(a.X) && !double.IsNaN(b.X)) + { + Vector.HueSort(ref pre.X, ref a.X, ref b.X, ref post.X); + a.X = Vector.cubic(pre.X, a.X, b.X, post.X, x, catmullRom); + a.X -= Math.Floor(a.X); + } + if (double.IsNaN(a.Y) && !double.IsNaN(b.Y)) + a.Y = b.Y; + else if (double.IsNaN(b.Y) && !double.IsNaN(a.Y)) + b.Y = a.Y; + if (double.IsNaN(pre.Y) && !double.IsNaN(a.Y)) + pre.Y = a.Y; + if (double.IsNaN(post.Y) && !double.IsNaN(b.Y)) + post.Y = b.Y; + if (!double.IsNaN(a.Y) && !double.IsNaN(b.Y)) + vector.Y = Vector.cubic(pre.Y, a.Y, b.Y, post.Y, x, catmullRom); + vector.X = a.X; + vector.Z = Vector.cubic(pre.Z, a.Z, b.Z, post.Z, x, catmullRom); + return vector; + } + + private static double hermite(double y0, double y1, double y2, double y3, double x) + { + double num1 = x * x; + double num2 = num1 * x; + double num3 = (y1 - y0) * (1.0 + HermiteSettings.Bias) * (1.0 - HermiteSettings.Tension) / 2.0 + (y2 - y1) * (1.0 - HermiteSettings.Bias) * (1.0 - HermiteSettings.Tension) / 2.0; + double num4 = (y2 - y1) * (1.0 + HermiteSettings.Bias) * (1.0 - HermiteSettings.Tension) / 2.0 + (y3 - y2) * (1.0 - HermiteSettings.Bias) * (1.0 - HermiteSettings.Tension) / 2.0; + double num5 = 2.0 * num2 - 3.0 * num1 + 1.0; + double num6 = num2 - 2.0 * num1 + x; + double num7 = num2 - num1; + double num8 = -2.0 * num2 + 3.0 * num1; + return num5 * y1 + num6 * num3 + num7 * num4 + num8 * y2; + } + + public static Vector HermiteRGB( + Vector pre, + Vector a, + Vector b, + Vector post, + double x, + GradientColourspace gamma) + { + if (x < 0.0) + x = 0.0; + else if (x > 1.0) + x = 1.0; + Vector vector = new Vector() + { + X = Vector.hermite(pre.X, a.X, b.X, post.X, x), + Y = Vector.hermite(pre.Y, a.Y, b.Y, post.Y, x), + Z = Vector.hermite(pre.Z, a.Z, b.Z, post.Z, x) + }; + switch (gamma) + { + case GradientColourspace.RGBV: + vector = vector.Adjust(vector.GetRGBValue(), Vector.hermite(pre.GetRGBValue(), a.GetRGBValue(), b.GetRGBValue(), post.GetRGBValue(), x)); + break; + case GradientColourspace.RGBL: + vector = vector.Adjust(vector.GetRGBLightness(), Vector.hermite(pre.GetRGBLightness(), a.GetRGBLightness(), b.GetRGBLightness(), post.GetRGBLightness(), x)); + break; + } + return vector; + } + + public static Vector HermiteH(Vector pre, Vector a, Vector b, Vector post, double x) + { + if (x < 0.0) + x = 0.0; + else if (x > 1.0) + x = 1.0; + Vector vector = new Vector(); + vector.X = vector.Y = double.NaN; + if (double.IsNaN(a.X) && !double.IsNaN(b.X)) + a.X = b.X; + else if (double.IsNaN(b.X) && !double.IsNaN(a.X)) + b.X = a.X; + if (double.IsNaN(pre.X) && !double.IsNaN(a.X)) + pre.X = a.X; + if (double.IsNaN(post.X) && !double.IsNaN(b.X)) + post.X = b.X; + if (!double.IsNaN(a.X) && !double.IsNaN(b.X)) + { + Vector.HueSort(ref pre.X, ref a.X, ref b.X, ref post.X); + a.X = Vector.hermite(pre.X, a.X, b.X, post.X, x); + a.X -= Math.Floor(a.X); + } + if (double.IsNaN(a.Y) && !double.IsNaN(b.Y)) + a.Y = b.Y; + else if (double.IsNaN(b.Y) && !double.IsNaN(a.Y)) + b.Y = a.Y; + if (double.IsNaN(pre.Y) && !double.IsNaN(a.Y)) + pre.Y = a.Y; + if (double.IsNaN(post.Y) && !double.IsNaN(b.Y)) + post.Y = b.Y; + if (!double.IsNaN(a.Y) && !double.IsNaN(b.Y)) + vector.Y = Vector.hermite(pre.Y, a.Y, b.Y, post.Y, x); + vector.X = a.X; + vector.Z = Vector.hermite(pre.Z, a.Z, b.Z, post.Z, x); + return vector; + } + + public bool IsValid() => !double.IsNaN(this.X) && !double.IsNaN(this.Y) && !double.IsNaN(this.Z); + + private static void HueSort(ref double v0, ref double v1, ref double v2, ref double v3) + { + v0 -= Math.Floor(v0); + v1 -= Math.Floor(v1); + v2 -= Math.Floor(v2); + v3 -= Math.Floor(v3); + if (v0 - v1 > 0.5) + { + ++v1; + ++v2; + ++v3; + } + else if (v1 - v0 > 0.5) + { + --v1; + --v2; + --v3; + } + if (v1 - v2 > 0.5) + { + ++v2; + ++v3; + } + else if (v2 - v1 > 0.5) + { + --v2; + --v3; + } + if (v2 - v3 > 0.5) + { + ++v3; + } + else + { + if (v3 - v2 <= 0.5) + return; + --v3; + } + } +}