From 1ef84fd1329f0a8dd5fd47da25365ac88b109b2b Mon Sep 17 00:00:00 2001 From: Alessio Date: Tue, 21 Apr 2026 10:40:12 +0200 Subject: [PATCH] Add disassembly of GradientTool --- .gitignore | 4 + AboutBox.cs | 197 +++ AboutBox.resx | 120 ++ AssemblyInfo.cs | 9 + BitmapCalc.cs | 281 ++++ CodeGen.cs | 312 ++++ ColourSelector.cs | 825 +++++++++++ ColourSelector.resx | 120 ++ Combiner.cs | 16 + Config2.cs | 253 ++++ Config2.resx | 120 ++ DoubleBufferedPanel.cs | 26 + Eyedropper.cs | 433 ++++++ Gradient.cs | 165 +++ GradientColourspace.cs | 19 + GradientControl.cs | 511 +++++++ GradientStop.cs | 45 + GradientTool.csproj | 80 ++ GradientTool.csproj.user | 42 + GradientTool.sln | 24 + GradientType.cs | 17 + HDMA/Channel.cs | 80 ++ HDMA/ChannelType.cs | 23 + HDMA/CombinedChannel.cs | 73 + HDMA/CompressedDataPoint.cs | 19 + HDMA/Configuration/ColourChannelsRef.cs | 43 + HDMA/Configuration/Mode0ChannelPropertyTab.cs | 159 +++ .../Mode0ChannelPropertyTab.resx | 120 ++ HDMA/Configuration/Mode2ChannelPropertyTab.cs | 208 +++ .../Mode2ChannelPropertyTab.resx | 120 ++ HDMA/Configuration/Mode3ChannelPropertyTab.cs | 188 +++ .../Mode3ChannelPropertyTab.resx | 120 ++ .../UnconfigurablePropertyTab.cs | 34 + HDMA/DataPoint.cs | 42 + HDMA/Generator2.cs | 500 +++++++ HDMA/GradientChannels.cs | 27 + HDMA/GradientChannelsHelper.cs | 35 + HDMA/Mode0Channel.cs | 84 ++ HDMA/Mode2Channel.cs | 89 ++ HDMA/Mode3Channel.cs | 100 ++ HDMA/Settings2.cs | 253 ++++ HermiteConfiguration.cs | 178 +++ HermiteConfiguration.resx | 120 ++ HermiteSettings.cs | 14 + Program.cs | 1257 +++++++++++++++++ Program.resx | 123 ++ Properties/Resources.cs | 141 ++ Properties/Resources.resx | 162 +++ Properties/Settings.cs | 21 + Resources/InvertedCrosshair.cur | Bin 0 -> 326 bytes Resources/blank.cur | Bin 0 -> 78 bytes SilentException.cs | 14 + UpgradeLog.htm | 329 +++++ Utils.cs | 393 ++++++ Vector.cs | 306 ++++ 55 files changed, 8994 insertions(+) create mode 100644 .gitignore create mode 100644 AboutBox.cs create mode 100644 AboutBox.resx create mode 100644 AssemblyInfo.cs create mode 100644 BitmapCalc.cs create mode 100644 CodeGen.cs create mode 100644 ColourSelector.cs create mode 100644 ColourSelector.resx create mode 100644 Combiner.cs create mode 100644 Config2.cs create mode 100644 Config2.resx create mode 100644 DoubleBufferedPanel.cs create mode 100644 Eyedropper.cs create mode 100644 Gradient.cs create mode 100644 GradientColourspace.cs create mode 100644 GradientControl.cs create mode 100644 GradientStop.cs create mode 100644 GradientTool.csproj create mode 100644 GradientTool.csproj.user create mode 100644 GradientTool.sln create mode 100644 GradientType.cs create mode 100644 HDMA/Channel.cs create mode 100644 HDMA/ChannelType.cs create mode 100644 HDMA/CombinedChannel.cs create mode 100644 HDMA/CompressedDataPoint.cs create mode 100644 HDMA/Configuration/ColourChannelsRef.cs create mode 100644 HDMA/Configuration/Mode0ChannelPropertyTab.cs create mode 100644 HDMA/Configuration/Mode0ChannelPropertyTab.resx create mode 100644 HDMA/Configuration/Mode2ChannelPropertyTab.cs create mode 100644 HDMA/Configuration/Mode2ChannelPropertyTab.resx create mode 100644 HDMA/Configuration/Mode3ChannelPropertyTab.cs create mode 100644 HDMA/Configuration/Mode3ChannelPropertyTab.resx create mode 100644 HDMA/Configuration/UnconfigurablePropertyTab.cs create mode 100644 HDMA/DataPoint.cs create mode 100644 HDMA/Generator2.cs create mode 100644 HDMA/GradientChannels.cs create mode 100644 HDMA/GradientChannelsHelper.cs create mode 100644 HDMA/Mode0Channel.cs create mode 100644 HDMA/Mode2Channel.cs create mode 100644 HDMA/Mode3Channel.cs create mode 100644 HDMA/Settings2.cs create mode 100644 HermiteConfiguration.cs create mode 100644 HermiteConfiguration.resx create mode 100644 HermiteSettings.cs create mode 100644 Program.cs create mode 100644 Program.resx create mode 100644 Properties/Resources.cs create mode 100644 Properties/Resources.resx create mode 100644 Properties/Settings.cs create mode 100644 Resources/InvertedCrosshair.cur create mode 100644 Resources/blank.cur create mode 100644 SilentException.cs create mode 100644 UpgradeLog.htm create mode 100644 Utils.cs create mode 100644 Vector.cs 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} + + + 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 + + \ 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 0000000000000000000000000000000000000000..a9d4349087202bf432e7a7a7d07e4915b1fc451b GIT binary patch literal 326 zcmZQzU}9ioP*7lCUl3IG5A literal 0 HcmV?d00001 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; + } + } +}