Add disassembly of GradientTool

This commit is contained in:
2026-04-21 10:40:12 +02:00
commit 1ef84fd132
55 changed files with 8994 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
.vs
bin/
obj/
Backup/

197
AboutBox.cs Normal file
View File

@@ -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/");
}
}

120
AboutBox.resx Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

9
AssemblyInfo.cs Normal file
View File

@@ -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)]

281
BitmapCalc.cs Normal file
View File

@@ -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);
}
}
}

312
CodeGen.cs Normal file
View File

@@ -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;
}

825
ColourSelector.cs Normal file
View File

@@ -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<Color>) (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);
}
}

120
ColourSelector.resx Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

16
Combiner.cs Normal file
View File

@@ -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,
}

253
Config2.cs Normal file
View File

@@ -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);
}
}

120
Config2.resx Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

26
DoubleBufferedPanel.cs Normal file
View File

@@ -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);
}
}

433
Eyedropper.cs Normal file
View File

@@ -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<Color> 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);
}
}
}

165
Gradient.cs Normal file
View File

@@ -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<GradientStop> m_stops;
public Gradient()
{
this.m_stops = new List<GradientStop>(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<GradientStop> 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.");
}
}
}

19
GradientColourspace.cs Normal file
View File

@@ -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,
}

511
GradientControl.cs Normal file
View File

@@ -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;
}
}

45
GradientStop.cs Normal file
View File

@@ -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<GradientStop>
{
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();
}
}

80
GradientTool.csproj Normal file
View File

@@ -0,0 +1,80 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0-windows</TargetFramework>
<OutputType>WinExe</OutputType>
<ApplicationVersion>0.8.2.1</ApplicationVersion>
<RootNamespace>SFXProductions.GradientTool</RootNamespace>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<UseWindowsForms>true</UseWindowsForms>
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NeutralLanguage>en-CA</NeutralLanguage>
<AssemblyTitle>HDMA Gradient Generator</AssemblyTitle>
<Company>ExoticMatter Productions</Company>
<Product>GradientTool</Product>
<Copyright>Copyright © 2015 ExoticMatter</Copyright>
<AssemblyVersion>0.8.2.1</AssemblyVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<Configuration>Release</Configuration>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<Configuration>Release</Configuration>
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\blank.cur" />
<EmbeddedResource Include="Resources\InvertedCrosshair.cur" />
</ItemGroup>
<ItemGroup Label="Compile items now included by globbing that were not in the original project file">
<Compile Remove="Backup\Vector.cs" />
<Compile Remove="Backup\Utils.cs" />
<Compile Remove="Backup\SilentException.cs" />
<Compile Remove="Backup\Properties\Settings.cs" />
<Compile Remove="Backup\Properties\Resources.cs" />
<Compile Remove="Backup\Program.cs" />
<Compile Remove="Backup\HermiteSettings.cs" />
<Compile Remove="Backup\HermiteConfiguration.cs" />
<Compile Remove="Backup\HDMA\Settings2.cs" />
<Compile Remove="Backup\HDMA\Mode3Channel.cs" />
<Compile Remove="Backup\HDMA\Mode2Channel.cs" />
<Compile Remove="Backup\HDMA\Mode0Channel.cs" />
<Compile Remove="Backup\HDMA\GradientChannelsHelper.cs" />
<Compile Remove="Backup\HDMA\GradientChannels.cs" />
<Compile Remove="Backup\HDMA\Generator2.cs" />
<Compile Remove="Backup\HDMA\DataPoint.cs" />
<Compile Remove="Backup\HDMA\Configuration\UnconfigurablePropertyTab.cs" />
<Compile Remove="Backup\HDMA\Configuration\Mode3ChannelPropertyTab.cs" />
<Compile Remove="Backup\HDMA\Configuration\Mode2ChannelPropertyTab.cs" />
<Compile Remove="Backup\HDMA\Configuration\Mode0ChannelPropertyTab.cs" />
<Compile Remove="Backup\HDMA\Configuration\ColourChannelsRef.cs" />
<Compile Remove="Backup\HDMA\CompressedDataPoint.cs" />
<Compile Remove="Backup\HDMA\CombinedChannel.cs" />
<Compile Remove="Backup\HDMA\ChannelType.cs" />
<Compile Remove="Backup\HDMA\Channel.cs" />
<Compile Remove="Backup\GradientType.cs" />
<Compile Remove="Backup\GradientStop.cs" />
<Compile Remove="Backup\GradientControl.cs" />
<Compile Remove="Backup\GradientColourspace.cs" />
<Compile Remove="Backup\Gradient.cs" />
<Compile Remove="Backup\Eyedropper.cs" />
<Compile Remove="Backup\DoubleBufferedPanel.cs" />
<Compile Remove="Backup\Config2.cs" />
<Compile Remove="Backup\Combiner.cs" />
<Compile Remove="Backup\ColourSelector.cs" />
<Compile Remove="Backup\CodeGen.cs" />
<Compile Remove="Backup\BitmapCalc.cs" />
<Compile Remove="Backup\AssemblyInfo.cs" />
<Compile Remove="Backup\AboutBox.cs" />
</ItemGroup>
<ItemGroup Label="EmbeddedResource items now included by globbing that were not in the original project file">
<EmbeddedResource Remove="Backup\Properties\Resources.resx" />
<EmbeddedResource Remove="Backup\Program.resx" />
<EmbeddedResource Remove="Backup\HermiteConfiguration.resx" />
<EmbeddedResource Remove="Backup\HDMA\Configuration\Mode3ChannelPropertyTab.resx" />
<EmbeddedResource Remove="Backup\HDMA\Configuration\Mode2ChannelPropertyTab.resx" />
<EmbeddedResource Remove="Backup\HDMA\Configuration\Mode0ChannelPropertyTab.resx" />
<EmbeddedResource Remove="Backup\Config2.resx" />
<EmbeddedResource Remove="Backup\ColourSelector.resx" />
<EmbeddedResource Remove="Backup\AboutBox.resx" />
</ItemGroup>
</Project>

42
GradientTool.csproj.user Normal file
View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
<ItemGroup>
<Compile Update="AboutBox.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="ColourSelector.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Config2.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="DoubleBufferedPanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="Eyedropper.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="GradientControl.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="HDMA\Configuration\Mode0ChannelPropertyTab.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="HDMA\Configuration\Mode2ChannelPropertyTab.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="HDMA\Configuration\Mode3ChannelPropertyTab.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="HDMA\Configuration\UnconfigurablePropertyTab.cs">
<SubType>Component</SubType>
</Compile>
<Compile Update="HermiteConfiguration.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="Program.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project>

24
GradientTool.sln Normal file
View File

@@ -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

17
GradientType.cs Normal file
View File

@@ -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,
}

80
HDMA/Channel.cs Normal file
View File

@@ -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<CompressedDataPoint> 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<CompressedDataPoint> hdmaTable, CodeGen cGen);
public void WriteData(IList<CompressedDataPoint> 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();
}
}

23
HDMA/ChannelType.cs Normal file
View File

@@ -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
}

73
HDMA/CombinedChannel.cs Normal file
View File

@@ -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<CompressedDataPoint> 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 doesnt 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<CompressedDataPoint> 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();
}
}
}
}

View File

@@ -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<DataPoint> Data = new List<DataPoint>()
{
dataPoint
};
}

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -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;
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -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);
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -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;
}
}

42
HDMA/DataPoint.cs Normal file
View File

@@ -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<DataPoint>
{
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;
}

500
HDMA/Generator2.cs Normal file
View File

@@ -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<CompressedDataPoint> 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<CompressedDataPoint> 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<CompressedDataPoint> CompressTable(
DataPoint[] dataPoints,
bool canUseContinuousMode)
{
List<CompressedDataPoint> dst = new List<CompressedDataPoint>();
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<CompressedDataPoint> outTable1 = (List<CompressedDataPoint>) null;
List<CompressedDataPoint> outTable2 = (List<CompressedDataPoint>) null;
List<CompressedDataPoint> outTable3 = (List<CompressedDataPoint>) 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<CompressedDataPoint> outTable)
{
if (chan == null)
return;
chan.GetRawData(rBuffer, gBuffer, bBuffer, tmpBuffer);
outTable = Generator2.CompressTable(tmpBuffer, chan.CanUseContinuousMode);
size += chan.CalculateTableSize((IList<CompressedDataPoint>) outTable) + 1U;
}
private static void WriteChan(
Channel chan,
List<CompressedDataPoint> table,
CodeGen code,
string gradientName)
{
if (chan == null)
return;
code.AppendLine();
chan.WriteData((IList<CompressedDataPoint>) 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 doesnt 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 couldnt");
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);
}
}

27
HDMA/GradientChannels.cs Normal file
View File

@@ -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,
}

View File

@@ -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];
}
}

84
HDMA/Mode0Channel.cs Normal file
View File

@@ -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<CompressedDataPoint> 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<CompressedDataPoint> 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();
}
}
}
}

89
HDMA/Mode2Channel.cs Normal file
View File

@@ -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<CompressedDataPoint> 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<CompressedDataPoint> 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();
}
}
}
}

100
HDMA/Mode3Channel.cs Normal file
View File

@@ -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<CompressedDataPoint> 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<CompressedDataPoint> 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();
}
}
}
}

253
HDMA/Settings2.cs Normal file
View File

@@ -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;
}
}

178
HermiteConfiguration.cs Normal file
View File

@@ -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();
}
}

120
HermiteConfiguration.resx Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

14
HermiteSettings.cs Normal file
View File

@@ -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;
}

1257
Program.cs Normal file

File diff suppressed because it is too large Load Diff

123
Program.resx Normal file

File diff suppressed because one or more lines are too long

141
Properties/Resources.cs Normal file
View File

@@ -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);
}
}
}

162
Properties/Resources.resx Normal file
View File

@@ -0,0 +1,162 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="NoCodeGeneratedMessage" xml:space="preserve">
<value>{\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}</value>
</data>
<data name="pipette" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAXgIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAB3ElEQVQ4T2P8//8/A9WAFSMjwxogfoqEHwHZ96H4HiOj3XVGxo1nGBm37WdkdNoFsxmbRpghMANgmv9MmPD/XWnp/00MDAfXggxAtxHZdhAbZACy5of+/v/vhoX9X8TAcHweyAB0DUh8GyB79UNGxgyQs0E2I2uewcDgPg1kwH4ceB8Dw5n/K1b8v8PIuB6XZrABi11dwXipuzvDMg8POF7i5hazHWjIn8mTsdoM0gw2oLOzE4x7e3sZJkyYAMZ9fX0qdXV1aWVLLlUDA+rMnZCQ/7MYGE5NZ2CogmnEaQBM8+uPP64vP/JoM8iQxUBD3gMDbiqQBmIGZIziAnTNOy+8mKOrq5sWJyAQA3QBSLMHsuYCZC8AvaFcXV2dCrMZpFlbWztVVlZWJZqXl2Emks0gjWqwRBQREcEQExPDkJycnICsWVlZOUFCQkJZSkqKAWYAikaYAfb29gyOjo5K0YnpOSA/g2wGaowRFBRUEhAQYGBnZ8efVTg5ORmkpaVjQbZb2rvm8vDwxHJwcCiysLAQncfkgLaEsrGxJTMzMzsAdekBsRbUm0pAWg6IJYFYFIgFgJgHiDmAmBWImUC28EMVSEFpcahiYSAtCJXnBdLcUI1sQBrkPGYgZgQAVsH8nb4cZMMAAAAASUVORK5CYIIL</value>
</data>
<data name="magnifier-zoom-actual" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAALQMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACq0lEQVQ4T5WTXUiTYRTHzz4KhxZ9bNKHKBuWo8TKUZNtTltjFZU09CL7wsiLclCB2kXURSUimCAE0s1ruyiCIuiDcunQoSZzbc4Nv1rp62I2ff3A5qZukm/nkS2S7aYHfhzO/zn/85z34X04EF3CtCOQlVcB29MOrynJySkgEAikXC63GlMNshuZQNpXV1frl5aWRkKhIKDJAMoSIxTdGlzHuTu0/sI9L/3AOGH90Dvb+t0ftH4eCFgaXkzZiE72iQd01xxxnKhwSk/fcNFNb72m7pHpzvlQ5GdgccU/HQh/+zGz6Hja4ms9g/ukDhQXLYmgbja4rG3uSYtvdtFrqHGyWMeSJpj3DfkC1qpGtw01CrKL3iWCpj6OtpAG9rG5/rlgZB7r2NGp4DjRCM/NtBk1GjJ1rxIR+eT0rxUSyMlY93cCMkXX0HQPahGQaF8ngja2jLURM/Nr2RNe+b2AdSyJ5B5Ig5ft3k7UaMg6aUoEZah1OjoGma6ZQNh36baNxTqWRDINXmRfZb3LjRoFGo0GCgsLQa1WQ35+PqhUKpBrrityi7smm9+PO8aZ0DAxxZhdCI+96WBsspJeOudsjzSugVKpzMAmlXWPzayitJ+5/8Tv7h0IfvHPLQ/bBoP2OmpqSHXZQ8tLh/WHiu34i/0zARr36XTH75pMZlYkSn24V1GjPnrVTyE0EolGquCKT5p3/iusa4Dj5+n1xbXd3XZWLJY84vP5eySyKtCUM3FgA9ivfQabRDKIff+psrLyRpdrlM3JOdiEZhmPxwMOhwPi3Oo4Yu9nLaanp4NcLq/yeBi2oOBYM5q1xPg/K0kkEmmFQmENmg1oPIBkI1IkE8mIvsRUjFuRFCQJ2YBwyUF8hGzuQnYiO6K5EOM2ZAuyGUlGBMjGqIeHkfMHu+afpal2Z7IAAAAASUVORK5CYIIL</value>
</data>
<data name="magnifier-zoom" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAA5AIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACYklEQVQ4T2P0K7jKgA1wc/MwcHJyajAxMZUC5Z2AWBqInwLxvn///nV///79xtevXxgYQAZgwxFV9wOjax/eb1rw9MTWk2933Xn+5cTRK58O9C5/eQokDpIHW+6WcRYDe2Sd1/DJu3R/2saHO47ceH3o0ZtvZ5+8/XYOhEHs+duf7PIFyoPUMVjFHMCG5xb0Xjyx+9KLA1cffzoO0wyjrz35dKJkwqXTQL1zGXT8NmHD9+duu7sDZAAuvHT3gz1AvfcZVNxWY8O/dp5/DteM7gIg/+zha6+PAfX+YlByWYsN31+w495ukO0gxdgMWLXv4SGg3vsM6p47sOG52e3nz+678urw/ZdfTqMb8Oj113PF3RcvAfXOZXBycmJwcHBgsLOzY7C1tWWwsbFhMHfKtDIKOvRi/uYHZ28++4xiwPP33y9t2P/qlHHIyft6Acc0MAywtraWBxpS3DF5z3+ryAuvGmc8u3TyyufTz9/9uH7q6pczHfNeXrOJu3XfPPJ6oGHwGWASQ3IBUKOWm5t7zY4de/6Lioo2q1m22DkmP58LxPeB+BeUnmuf+ETDIuomA4oBQOdbBAYGtx05cua/oqJSDwsLi6qScQmDU8orDAw0gEHbZQmDnXcRA8z/PgkJKRMuXrz7X0/PYCpQszEzMzMDIyMjg6JRKQZGyTtycnIM5ubmJbduvfpvb+88D6jZBaSRFMAB9K+LiIhIC1BzNlCjPhDrALEGEKsAsTw0J4oBaUEg5gFiDiBmBWImkEUsQCwOxFJALAnEElC+KJAWBmIBIOYDYm4g5gRidqhmZiDNCABROqZrx6hIBgAAAABJRU5ErkJgggs=</value>
</data>
<data name="wrench-screwdriver" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAfwMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAC/UlEQVQ4T22TX0iTURTAz5X9808up7M5UVEnGmJIujlxbnPawGTiNqe+9Eey2WaYg/woKyhB0qiHxIcQJcqKyocZGos5QyjXaFJOA03sTS0YPiRSEMTt3GGW2Qc/7na+e373nHP5iM1mg3+fcDgMEolkJxwVFSUhhKgwIGPB0dFRLy7rVqsVQKfTmfCHHWErMCwWC9TV1UUwm82S5ubmVp9vcmptbe2rVCptxWR5aWlpZC977BsbG7SlpYWrqqoC9kKlUoHJZPrN0YmJ8ZfLyx+pWl1yiyUrlUqoqalJRYGcCUw5OTlcIBAINTU1cSw5Pz8f9Ho9VFdXM07Pzb3bdDod47i3iCUYjcZUjJ/FQ07t9KlQKLjp6ekQmrnc3FzIy8sDg8EAWFV7MPiWMpTKYlZBUVubs391dXUT23fsml92djbn8XhC5eXlXEpKCqjVaqLVal1+/wz1el9EJA6HY5y1g4OcKSgoqN9zA1lZWZzb7Q4VFhZyiEWj0XROTnopk8zORirZGhoaCmDy5bS0tOQ9AhbIzMzk7rpci69jYxcWOs5RbO9aXFzc9W2u4HpMLBYfSE7GfKFQCImJicBKzsjIABwo4AxsY0LhOu3tpW4+f+2iTNbu4vMhOjp6BxRARBAfH79LgKeZcQZ90ydO0hsCwecvtbXflgh5tkjI+TlC4My26L+C9PR0q15f0e/3B2lJifqmLSHB9Rxgdstup5g88Z4Q7g1KppAeHg+Ox8b+qUAmk9UbDFWDweAHWlamGZDL5fWtWOYYQI8bJd87Oigme/yEXGCCpzirh2xg2y00VFYa783Pf6JarX44KSmpgc2kWCQCTGabe56g5EdXF8Vkn4+QS38LGisqjjxYWlqnOp1hBHtrjImJ2XU77HMbQcl9lPzs7qaY/OoxwNVIBbi5d2UljCcbHolEIjuGpIiYvUKEiAjZh0g6AW4Po4TdziBAEAHg8XiNAoGgj8/nO/HvYeQgko4ksg6R/UgKokAOuQAG7qCkGeC8BgO/APJtDfDgdBQUAAAAAElFTkSuQmCCCw==</value>
</data>
<data name="image-export" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAngIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACHElEQVQ4T6WTXUhTYRjH366CCPIu86YgkfRmu8jk+IFNadTo7CLa0Allk/C4UnMaU4ezBDtbJzDpY0MwR5YtqrVcWPax6sYQVlchjKiLwsGkCLXz6nFt/857uuzGsQd+L88L7+/PwwvPFgAkr2IB+UAsg4O8SmuO8Mc9HsIgx9xuQZ0gp2KOCnMJMbtcjkw2C26YolqkqJMoDl6mqFH7o1cpGvwy7OMybr6SEXz2HqHZWZiczrN1bW2kpqWFEFN39xklk0Hn1Br6H1H4ZiiGn1J4VSTWT8sQozJef5IxEYlok5bbbOf3NzaWl5nNhBzq6GiX02mcvD4C8UkM4ThFJL6GtwsUj+d/4G7sM+48n8N4OAp/KITFVEoLUeW+Up6vIAZBOLe8sYEyBw+u9wSuTL/AXGIF7xZ+I/6FIpFUsLT8B0o6+98/7amv95Aqu935c30dBeZa7LIexr7TDeB6HLD6fOgaC+LiZAjeyXuQbgUhBgL4lkxqQTs5bqiwsrKKHGhq6klRilLbCHTNfnCO2zC6wrB6YxDGPqLv4Vd4Xy7hxvwKLoyOavIOne5SgV5frYYQordYXElZhv5UABXCBGq77uOIOwqL+AbN1z6gPZhA74NFDM38woB/Cv2ShBKTyb3bYCB7jUbCjoGUouD76uqmYG+Zw2QtYHtxcSsbKRdUR9hWVEQYrLaqFKqw22Zgb5nzr/JZJG2T8w34C5B1S24sW0XcAAAAAElFTkSuQmCCCw==</value>
</data>
<data name="block" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAfgIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAB/ElEQVQ4T4WST0hUQRzHv3P1EEGEKIt0kU1eS1JpgWW7/mOxkq3cQwuGCHssOrSCGokS/aEOCYkQuhGKsR4WEg/92dpD0CEHImIz2y2ISolahLrvr/mN74277wkNfJj5zvzmM/OGJ0R7P9A5ANOE6FHju1sTZnQJRIsmPU+ilHkAiGtZN5nmxfW/vcslcuCs6jLuWiIC+oN9EFefllMIPflFBxc+GzirmoKrTl1ICbJ837oAxOBjh/yxpXVqfPTJwFmt58tqYE3EtgRa4rMgLqaY1SPpr7Rv9oOBM8/b6whOW4guoFKgJbUNEPGHKwdSBfIn3xk487wCwfsNerMRvATCCukQa4ys8YbA3IpBC2JTueCU32w2gmdAeu3EyWIpMUjM7MAQRSMjmr2d5zZq+jaxLh//0ZuCLCOsH3FJnf6nqYt+Yo+H8TOQN2UHpYrxCm69DxUjc0hrQVoJfgda6Rt8Hq70QF5/00aTq6eJewfO3dOQWjCvBN/rmymPGg+Jbsjx1600kTtF3Dtw7rhnC5JK8MUXoBx2e7jQBTn6qoXuvA0T9w6cj962BZNKUKjbTx931XuIhyBHsof11bl34HxozBacB2aGlWQ7zrZADr1oohvL7RWfwNlK2AL1/1QpqhW1Lvw72jC/Mwq5HWptRj/if5pb6mQ+sIoF/wB1k7lyQifSuAAAAABJRU5ErkJgggs=</value>
</data>
<data name="color" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAZQMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAC40lEQVQ4T6XTbUhTYRQH8KOuZRBBgZrFKogIe8E+VhRl9ELQt4RhVJjYC5ahg0Q0i+bMZsveQAhz5HxpoaaJTp2ao7KGL5mbXbdiFLjMzDGuounm7r+jH2ZC0IcuHB6ey3N+zznPvU8IAPqvZw6oKCPqf070MZ/ImkAR/QdJ6dgRlueIlJc45CtLHLJteQMUp+yjExECachONWQhM81vvgi4TXHO66sMoyVn+6ZfGj3SW4tfan/lnzY0eUYTi/qcq7INAt2K+ztQT4ecVYqWmc9PRdjKAeM1IFcFqHjMKQOKuzDzwCY61z5tsVPdoUUVlFdTtK17hWna82QC7kLAyomNakCvA3SPAE09cKWTxy+YVn+fsC23msxkiQ62oLdQquCOH5qVioGJdGCoALDrgfYqoLoFKP0AFH4FMkTM5gYg7HMPGcmaGgS0Vqr7NKn95UYmvLiB2VlO9jYDri6gxwm0jiFg8GH8JvCNi/uQNPlLR9a6IHD+NTlsgSKpE5dhhxZDeIYJWBGYcUMamcJULzBcCwh3gXdpQMeFgJRCrx1B4GAHuZoDt6RKpKKRgTcMDDAwjJ/4IQKD7zmRgSYGjAzoTwakI9ThCgLrzNSWN57sK+AK7nELpTCgmYEujKGHgVYGKozAQ24hLwW4eGDct4HMbUEgpIKydg7GiukMpCMHBaiEHt2oYqB6nM+wn8+wms9QAySeBmLWD4qhVJsVBEhNCrlJLhwTT/mSuQUVt6BGD3TwQMeAxsZfkVtI1AJ7j4s+2RKTQPRYsQCk8W2oJOWyhij3fu9VfwJqkIxeXGLgEgPnGEh4AezJ8frDFQ1uoiol0f2FX3n+MsVwpIUpZfoYQdGpEneNNvuO+kekox6/tLt91Lcus1OUxeoFkqs4ect8ykIFRDKeR3FspY1LD9OZzXdIE2+h/AwXZee7KEFjoa1Jdyh802Fes51jNYfsTyCUXyzniORY84+Y22hubegc8Bv+OkVzATHVkQAAAABJRU5ErkJgggs=</value>
</data>
<data name="magnifier-zoom-fit" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAGwMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACmUlEQVQ4T5WTX0hTcRTHz/4UDi36s0l/RJlYjhIrR21sc9oaq8ikMR+yIox8KIUK1Jeoh0pEMEEIopcbPhSC4UtgWg2RNJmmrY2pZdlVUa+bTk3vnG7k7ZwxI9le+sGH7zm/8/ueey73/kQQXfKUE5CpLYPdKccjO4mJSSCTyVRisbgKUxOyH5lCOtbX1+uCweDXQIAHNJWDvqgRCu8MbuLiXdZ6+f44+7BxytHa63/3g+MdHz1LnfVN3j7apzp5wHJjIIYzZU5VwS0X22TnHGO+wNhiIDS9tBLmCIqbO2Yc57FO50B3pTMezO16l2PUy49hXSDmFtYiSkz6gxOVDe4+jBnIKnwdD5Z5M9pGDbAuzPOhRYpJKaf4pZ21Y8xChuVVPEJvnVwnHfT6gwKNPulf+UxK+a+V8HTX0GwPekOQbm6JB9vY9vM9NcC6sBb+vUxmUsqpQXPH+AeMWcg82x4PprzGOTA+G5jAukD4/KsRJRYCIa6izuXGmAGTyQT5+flgNBohNzcXDAYDaEw3dTm2rpkW+9T3ueW1v1+ApuBXw77WrjmPuqiXzb7Qo4ppoNfr07BJRe0Tu6Ar/uJ78Ixz93r4T9z86nDfIN9fy3iHDFdHWE3xsPWYrR9/sX8mQOMhi+X0vfZ2u6BQJD86qKs2nrzOMQiLhKLK5F2bVGkvfYNNDXB8rdVqq+nu7heUyvTHUqn0QLq6EkylvhiwARw2v4BtCjVsvP+5kpLSBpdrVMjOPvoUzWqJRAIikQiUOVUxbNyfiKampoJGo6kcGfEJeXmnnqPZTMb/WQkKhcIsl8ur0VyOxiNIFqJCMpC06E1MRt2JJCEJyBZETA+SIlTch+xF9kRzOeouZAeyHUlEZMjWqEeCKvoDhfKfBbfK0SIAAAAASUVORK5CYIIL</value>
</data>
<data name="gear--arrow" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAAgMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACgElEQVQ4T6WQXUiTURjHz3JLhhl6M/uaRCkSbmEbuK0uBpZYc9H8uIjQZFBIVlfSwKgIQUQQam1hEJRSGdRNyiLITPDjFfa+sU9Tc9myTYf3I/Lm6fzfV2tBdNOBH8/D8/z/f845KiJi/3UQ4HA4mNPpZA0NDayxsVGuzc3NNk77JrbcHbTwAJYb4HK5jnLhJV73om5sbFA2m6XcGTR/Daivrz/m8Xjurq+vk9vtvs5Fl1dX0wTQY4YdNND+cYO6ujrGuZpMJkkUg5ROpygQCCylUikC6BOJhLyDBtpNj/IEm83G7Hb7vqampluRSJjC4RAtL3+mlZWvMugxww4aaOGxWCxKgNVqtfNBJxgaGkzE4zEaHn42bzAY7gP0mGG3pYPnV4DJZPJIkkgTE+9pdlagaDRKRuPh3ry8PAbQY4YdNNDCw1FuUFlZ2TU9PU1jY2OEGot9pKoqU7dKpWIAPWa5Gng4SkB5eXltWVnZDeDz+b+EQnEaHX0XMpurbwL0mGFXfe25eKT19kt4OEpAaWkp0+v1+00mc78gSDQ+PkWLiynKZL7LoMcMO2ufmLF4P8UsvuUW/jAlQKfTgW5BCNPIyFuanJTI73+YDAbj1PE4TMf7xR9OX4RO3vlAp/1RGkgTcbNk7Am3yAHFxcXgVE1N7VNRXKCKikPeoqKiHkGI0Ym+Wbr3jahjjqg18pvOBaKDXVOSHICjVquZVqt1FBQU9Obn5x9AnZ9fo4sDQdK1Da2VtL+KyfXCiyXrDNGujtfS7itvlBvAzynh8G9lZqDRaNp4UB9AvzUvPDs4V3juSWRny/B5HqL8AT/bODs4Os6ef7H9zINHGqfXvelhPwFdc8W1rfrU+wAAAABJRU5ErkJgggs=</value>
</data>
<data name="information-frame" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAdgMAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAC9ElEQVQ4T02PbUhTYRiGXxUZJvQjiREUIdUsyVwqCCtXjJaT5dycZX6naCUMIz/AybIvEI2IoDT8IcMF/pCZphAI2ZZSbuk8anocaiynCSn6I/rt3fu8WvTCxbnP897XwzkROTk5LCIigkVGRoon5yDnFGNMydnPofOL8xPAAmeTw3Z2dhg9GS0wm80sNzdXYbVaM+rq6hp9Pt/sxsYG1tfXBZTHx8dna2trG6lDXXLI/btAYbFYsp1OZzcJrwcW0PB0GkZbQEDZ1S9jbW0VXV1d3dTlCxRigclkIi7wC1coFEKpfQLXm5ZQ83wb9R2/Udf+G7ZnW7jWuCjulpeX0NnZ6SKHXGY0GpU2m83x/XsIhQ0+lD8O4/aTTWTfmee/uHso32zdQHHzbicYDKK6utpBLjMYDDqP58Ncu8uP3Pp5lD0Mw1wbhP5W4N8CyjQrdIRwpWYGL7vHMTQ0OEcu0+v1xfRZVQ4vSh+EkFktCXSVX6AyvMExvRsJWQM4frlPoL0xJrqTkxMgl+l0OpskSThX9B5F977hYoUfausITmQN8tIkAoEAjhve8vchQcrVEdEdGxsDuUyr1dZQMT1/GNl355Fo9iDBNAKVcVjIsiyLTDPiTN5H0fV6vSCXaTSackmaRkn9MLSVEhLz/IKT5lEhh8Nhkf/OT+d9El2vdxTksvT09MzeXvdC2ysvzl7zILUsiKRC/iV5E0Le2toSmWbEqZz3aG33wOl0LZDL0tLSDlks1papqTlcKhtCcr4fKeUrSCr4KuTt7W2R1WUrSLT6RMfvn4bZbGkhl6nVapacnGxobn7knplZwvl8N45efofEAhnqih8CyjSjO0lahMPx0E0OuUypVLL4+PgYlUpVbLc/6JflNbR1fIapsg8HUl8KKNNMlldht9/vpy455NKJ5OxTKBSH4+LiSjSajBc9PYPLi4ub+B+a0R11ePcIOXsui+IhjqPipERHR+tiYmKqYmNjmzitezTRjO6ow0nYc6L+AHuNFJyvBvpKAAAAAElFTkSuQmCCCw==</value>
</data>
<data name="layer-shape-curve" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAALAIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABqklEQVQ4T6WTyS9DURTGT/MIUqlGtdGmUhUxVSkSLBALC4mFUkNL2BgiaI1F7LFiaYMEGyJinu0sxYo/gaUl6/rO7btNX4ghXvJ755537/fdc4enq5i9rSQi5l4FIfq8PT/Sy90mvb88xb5xI927TLokA73u9hOVz9wEI5HIA0fAeYySyQsqHj8j19ipwNm2ROaqgDAwda4RdERl4etqEFIj5wIpjjdgk6LQCeUO7ZO1ZytmQJ7pKz8wAm5rxF8ZFAaPiREVlE5dMo2giGd1T5yLclkokUuQFWgMWAQcoANivRz8awOekYGgDrTCwA4UtGtAmOO3FcR1Kmh7gB/0gTk+HY5qzt892ERFs4R4d7lG3mkMqgXzHJEnIGaBdlBfMHpEjNhES3WXOF9pxGLVQAzi2eLy1PyRw27gzBs+iBrIR293CzO+KAwLpUG2b1G0WQRKgfeTgeaufpGk2FziAgETGMgZ3NNW8JMB96eV+cjRt9OQ3b+7wFEuQYc+BSSCZKAHBmDk/wZkAAvIBFZb7/YKn44axbx/MjC1rDRn+NdXzYGNJlEBv/7DBwSbST67PPGnAAAAAElFTkSuQmCCCw==</value>
</data>
<data name="disk" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAARwIAAAKJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAABc1JHQgCuzhzpAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABxUlEQVQ4T6XOT0iTcRzH8e+eZ3cPHYSILt27SOBVvFR4CGSJovkvpUN0CjwoOoiazq1N2Jgomkq1mQhNCN2mOLdoI+hQmqioKYlhDNQwGQz26fd5dFAgT0aD1zZ+v8/72SwA5L9eTbpHmnTvPaXX1tXVeh7cnjQekUb1prhXX/5QfwbI/wU33LJhKw26mzyLIxnk8nlkczlT3HDLhq3U6y7q+zj8HT9VfHB8bIobbtmwlTu6k3wfBnaxn83i2+GhKW64ZcNWajUHBd4HvmJP/fqXTMYUN9yyYSs12mMaSPm2sLlxgJ2jI1PccMuGrVRrj2go6V1H1LF4LtyyYStVmp1G4u5V9NweQ7dt9Ey8K0j7t8GGrdi0Tno+2/MZruoXSKXSSCSSf+AZ7161JeGpDeFt3wbYsJVKrZ1CkSef4K0bRywWR8cNv2FqatrAM97xAYG7r7HwdA1s2MotrY0mY91L8DVOIhyOGp8UCoUNhTM+4Nn9Gcy7VsCGrVywXJJSS2XZTcuDqP364P7ERAT9LWFDMPjGUDjjA4IP45hzLoN7tnxdVq5ekWvN5dLyzmq1Os/Cu9+VSMXwaStF6kuxcvEfsSn6Bb/OPjvwg4uNAAAAAElFTkSuQmCCCw==</value>
</data>
<data name="hues" mimetype="application/x-microsoft.net.object.binary.base64">
<value>AAEAAAD/////AQAAAAAAAAAMAgAAAFFTeXN0ZW0uRHJhd2luZywgVmVyc2lvbj0yLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWIwM2Y1ZjdmMTFkNTBhM2EFAQAAABVTeXN0ZW0uRHJhd2luZy5CaXRtYXABAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAegAAAAJCTXoAAAAAAAAAdgAAACgAAAAHAAAAAQAAAAEABAAAAAAAAAAAAMQOAADEDgAAEAAAABAAAAAAAAD/AACA/wCAAP8AgID/gAAA/4AAgP+AgAD/gICA/8DAwP8AAP//AP8A/wD/////AAD//wD/////AP//////m67NkAs=</value>
</data>
</root>

21
Properties/Settings.cs Normal file
View File

@@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

BIN
Resources/blank.cur Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 B

14
SilentException.cs Normal file
View File

@@ -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
{
}

329
UpgradeLog.htm Normal file
View File

@@ -0,0 +1,329 @@
<!DOCTYPE html>
<!-- saved from url=(0014)about:internet -->
<html xmlns:msxsl="urn:schemas-microsoft-com:xslt"><head><meta content="en-us" http-equiv="Content-Language" /><meta content="text/html; charset=utf-16" http-equiv="Content-Type" /><title _locID="ConversionReport0">
Migration Report
</title><style>
/* Body style, for the entire document */
body
{
background: #F3F3F4;
color: #1E1E1F;
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
padding: 0;
margin: 0;
}
/* Header1 style, used for the main title */
h1
{
padding: 10px 0px 10px 10px;
font-size: 21pt;
background-color: #E2E2E2;
border-bottom: 1px #C1C1C2 solid;
color: #201F20;
margin: 0;
font-weight: normal;
}
/* Header2 style, used for "Overview" and other sections */
h2
{
font-size: 18pt;
font-weight: normal;
padding: 15px 0 5px 0;
margin: 0;
}
/* Header3 style, used for sub-sections, such as project name */
h3
{
font-weight: normal;
font-size: 15pt;
margin: 0;
padding: 15px 0 5px 0;
background-color: transparent;
}
/* Color all hyperlinks one color */
a
{
color: #1382CE;
}
/* Table styles */
table
{
border-spacing: 0 0;
border-collapse: collapse;
font-size: 10pt;
}
table th
{
background: #E7E7E8;
text-align: left;
text-decoration: none;
font-weight: normal;
padding: 3px 6px 3px 6px;
}
table td
{
vertical-align: top;
padding: 3px 6px 5px 5px;
margin: 0px;
border: 1px solid #E7E7E8;
background: #F7F7F8;
}
/* Local link is a style for hyperlinks that link to file:/// content, there are lots so color them as 'normal' text until the user mouse overs */
.localLink
{
color: #1E1E1F;
background: #EEEEED;
text-decoration: none;
}
.localLink:hover
{
color: #1382CE;
background: #FFFF99;
text-decoration: none;
}
/* Center text, used in the over views cells that contain message level counts */
.textCentered
{
text-align: center;
}
/* The message cells in message tables should take up all avaliable space */
.messageCell
{
width: 100%;
}
/* Padding around the content after the h1 */
#content
{
padding: 0px 12px 12px 12px;
}
/* The overview table expands to width, with a max width of 97% */
#overview table
{
width: auto;
max-width: 75%;
}
/* The messages tables are always 97% width */
#messages table
{
width: 97%;
}
/* All Icons */
.IconSuccessEncoded, .IconInfoEncoded, .IconWarningEncoded, .IconErrorEncoded
{
min-width:18px;
min-height:18px;
background-repeat:no-repeat;
background-position:center;
}
/* Success icon encoded */
.IconSuccessEncoded
{
/* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
/* [---XsltValidateInternal-Base64EncodedImage:IconSuccess#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABcElEQVR4Xq2TsUsCURzHv15g8ZJcBWlyiYYgCIWcb9DFRRwMW5TA2c0/QEFwFkxxUQdxVlBwCYWOi6IhWgQhBLHJUCkhLr/BW8S7gvrAg+N+v8/v+x68Z8MGy+XSCyABQAXgBgHGALoASkIIDWSLeLBetdHryMjd5IxQPWT4rn1c/P7+xxp72Cs9m5SZ0Bq2vPnbPFafK2zDvmNHypdC0BPkLlQhxJsCAhQoZwdZU5mwxh720qGo8MzTxTTKZDPCx2HoVzp6lz0Q9tKhyx0kGs8Ny+TkWRKk8lCROwEduhyg9l/6lunOPSfmH3NUH6uQ0KHLAe7JYvJjevm+DAMGJHToKtigE+vwvIidxLamb8IBY9e+C5LiXREkfho3TSd06HJA13/oh6T51MTsfQbHrsMynQ5dDihFjiK8JJAU9AKIWTp76dCVN7HWHrajmUEGvyF9nkbAE6gLIS7kTUyuf2gscLoJrElZo/Mvj+nPz/kLTmfnEwP3tB0AAAAASUVORK5CYII=);
}
/* Information icon encoded */
.IconInfoEncoded
{
/* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
/* [---XsltValidateInternal-Base64EncodedImage:IconInformation#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABHElEQVR4Xs2TsUoDQRRF7wwoziokjZUKadInhdhukR9YP8DMX1hYW+QvdsXa/QHBbcXC7W0CamWTQnclFutceIQJwwaWNLlwm5k5d94M76mmaeCrrmsLYOocY12FcxZFUeozCqKqqgYA8uevv1H6VuPxcwlfk5N92KHBxfFeCSAxxswlYAW/Xr989x/mv9gkhtyMDhcAxgzRsp7flj8B/HF1RsMXq+NZMkopaHe7lbKxQUEIGbKsYNoGn969060hZBkQex/W8oRQwsQaW2o3Ago2SVcJUzAgY3N0lTCZZm+zPS8HB51gMmS1DEYyOz9acKO1D8JWTlafKIMxdhvlfdyT94Vv5h7P8Ky7nQzACmhvKq3zk3PjW9asz9D/1oigecsioooAAAAASUVORK5CYII=);
}
/* Warning icon encoded */
.IconWarningEncoded
{
/* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
/* [---XsltValidateInternal-Base64EncodedImage:IconWarning#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAx0lEQVR4XpWSMQ7CMAxFf4xAyBMLCxMrO8dhaBcuwdCJS3RJBw7SA/QGTCxdWJgiQYWKXJWKIXHIlyw5lqr34tQgEOdcBsCOx5yZK3hCCKdYXneQkh4pEfqzLfu+wVDSyyzFoJjfz9NB+pAF+eizx2Vruts0k15mPgvS6GYvpVtQhB61IB/dk6AF6fS4Ben0uIX5odtFe8Q/eW1KvFeH4e8khT6+gm5B+t3juyDt7n0jpe+CANTd+oTUjN/U3yVaABnSUjFz/gFq44JaVSCXeQAAAABJRU5ErkJggg==);
}
/* Error icon encoded */
.IconErrorEncoded
{
/* Note: Do not delete the comment below. It is used to verify the correctness of the encoded image resource below before the product is released */
/* [---XsltValidateInternal-Base64EncodedImage:IconError#Begin#background-image: url(data:image/png;base64,#Separator#);#End#] */
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABQElEQVR4XqWTvUoEQRCE6wYPZUA80AfwAQz23uCMjA7MDRQEIzPBVEyNTQUFIw00vcQTTMzuAh/AxEQQT8HF/3G/oGGnEUGuoNnd6qoZuqltyKEsyzVJq5I6rnUp6SjGeGhESikzzlc1eL7opfuVbrqbU1Zw9NCgtQMaZpY0eNnaaL2fHusvTK5vKu7sjSS1Y4y3QUA6K3e3Mau5UFDyMP7tYF9o8cAHZv68vipoIJg971PZIZ5HiwdvYGGvFVFHmGmZ2MxwmQYPXubPl9Up0tfoMQGetXd6mRbvhBw+boZ6WF7Mbv1+GsHRk0fQmPAH1GfmZirbCfDJ61tw3Px8/8pZsPAG4jlVhcPgZ7adwNWBB68lkRQWFiTgFlbnLY3DGGM7izIJIyT/jjIvEJw6fdJTc6krDzh6aMwMP9bvDH4ADSsa9uSWVJkAAAAASUVORK5CYII=);
}
</style><script type="text/javascript" language="javascript">
// Startup
// Hook up the the loaded event for the document/window, to linkify the document content
var startupFunction = function() { linkifyElement("messages"); };
if(window.attachEvent)
{
window.attachEvent('onload', startupFunction);
}
else if (window.addEventListener)
{
window.addEventListener('load', startupFunction, false);
}
else
{
document.addEventListener('load', startupFunction, false);
}
// Toggles the visibility of table rows with the specified name
function toggleTableRowsByName(name)
{
var allRows = document.getElementsByTagName('tr');
for (i=0; i < allRows.length; i++)
{
var currentName = allRows[i].getAttribute('name');
if(!!currentName && currentName.indexOf(name) == 0)
{
var isVisible = allRows[i].style.display == '';
isVisible ? allRows[i].style.display = 'none' : allRows[i].style.display = '';
}
}
}
function scrollToFirstVisibleRow(name)
{
var allRows = document.getElementsByTagName('tr');
for (i=0; i < allRows.length; i++)
{
var currentName = allRows[i].getAttribute('name');
var isVisible = allRows[i].style.display == '';
if(!!currentName && currentName.indexOf(name) == 0 && isVisible)
{
allRows[i].scrollIntoView(true);
return true;
}
}
return false;
}
// Linkifies the specified text content, replaces candidate links with html links
function linkify(text)
{
if(!text || 0 === text.length)
{
return text;
}
// Find http, https and ftp links and replace them with hyper links
var urlLink = /(http|https|ftp)\:\/\/[a-zA-Z0-9\-\.]+(:[a-zA-Z0-9]*)?\/?([a-zA-Z0-9\-\._\?\,\/\\\+&%\$#\=~;\{\}])*/gi;
return text.replace(urlLink, '<a href="$&">$&</a>') ;
}
// Linkifies the specified element by ID
function linkifyElement(id)
{
var element = document.getElementById(id);
if(!!element)
{
element.innerHTML = linkify(element.innerHTML);
}
}
function ToggleMessageVisibility(projectName)
{
if(!projectName || 0 === projectName.length)
{
return;
}
toggleTableRowsByName("MessageRowClass" + projectName);
toggleTableRowsByName('MessageRowHeaderShow' + projectName);
toggleTableRowsByName('MessageRowHeaderHide' + projectName);
}
function ScrollToFirstVisibleMessage(projectName)
{
if(!projectName || 0 === projectName.length)
{
return;
}
// First try the 'Show messages' row
if(!scrollToFirstVisibleRow('MessageRowHeaderShow' + projectName))
{
// Failed to find a visible row for 'Show messages', try an actual message row
scrollToFirstVisibleRow('MessageRowClass' + projectName);
}
}
</script></head><body><h1 _locID="ConversionReport">
Migration Report - GradientTool</h1><div id="content"><h2 _locID="OverviewTitle">Overview</h2><div id="overview"><table><tr><th></th><th _locID="ProjectTableHeader">Project</th><th _locID="PathTableHeader">Path</th><th _locID="ErrorsTableHeader">Errors</th><th _locID="WarningsTableHeader">Warnings</th><th _locID="MessagesTableHeader">Messages</th></tr><tr><td class="IconWarningEncoded" /><td><strong><a href="#Solution"><span _locID="OverviewSolutionSpan">Solution</span></a></strong></td><td>GradientTool.sln</td><td class="textCentered"><a>0</a></td><td class="textCentered"><a href="#SolutionWarning">1</a></td><td class="textCentered"><a href="#" onclick="ScrollToFirstVisibleMessage('Solution'); return false;">2</a></td></tr><tr><td class="IconSuccessEncoded" /><td><strong><a href="#GradientTool">GradientTool</a></strong></td><td>GradientTool.csproj</td><td class="textCentered"><a>0</a></td><td class="textCentered"><a>0</a></td><td class="textCentered"><a href="#" onclick="ScrollToFirstVisibleMessage('GradientTool'); return false;">51</a></td></tr></table></div><h2 _locID="SolutionAndProjectsTitle">Solution and projects</h2><div id="messages"><a name="Solution" /><h3 _locID="ProjectDisplayNameHeader">Solution</h3><table><tr id="SolutionHeaderRow"><th></th><th class="messageCell" _locID="MessageTableHeader">Message</th></tr><tr name="WarningRowClassSolution"><td class="IconWarningEncoded"><a name="SolutionWarning" /></td><td class="messageCell"><strong>GradientTool.sln:
</strong><span>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.</span></td></tr><tr name="MessageRowHeaderShowSolution"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="ShowAdditionalMessages" href="#" name="SolutionMessage" onclick="ToggleMessageVisibility('Solution'); return false;">
Show 2 additional messages
</a></td></tr><tr name="MessageRowClassSolution" style="display: none"><td class="IconInfoEncoded"><a name="SolutionMessage" /></td><td class="messageCell"><strong>GradientTool.sln:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientTool.sln</span></td></tr><tr name="MessageRowClassSolution" style="display: none"><td class="IconInfoEncoded"><a name="SolutionMessage" /></td><td class="messageCell"><strong>GradientTool.sln:
</strong><span>Solution migrated successfully</span></td></tr><tr style="display: none" name="MessageRowHeaderHideSolution"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="HideAdditionalMessages" href="#" name="SolutionMessage" onclick="ToggleMessageVisibility('Solution'); return false;">
Hide 2 additional messages
</a></td></tr></table><a name="GradientTool" /><h3>GradientTool</h3><table><tr id="GradientToolHeaderRow"><th></th><th class="messageCell" _locID="MessageTableHeader">Message</th></tr><tr name="MessageRowHeaderShowGradientTool"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="ShowAdditionalMessages" href="#" name="GradientToolMessage" onclick="ToggleMessageVisibility('GradientTool'); return false;">
Show 51 additional messages
</a></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>GradientTool.csproj:
</strong><span>Project file successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientTool.csproj</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Gradient.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Gradient.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>GradientType.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientType.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>GradientColourspace.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientColourspace.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HermiteConfiguration.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HermiteConfiguration.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>CodeGen.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\CodeGen.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>BitmapCalc.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\BitmapCalc.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Combiner.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Combiner.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Config2.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Config2.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Utils.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Utils.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>DoubleBufferedPanel.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\DoubleBufferedPanel.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Program.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Program.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Vector.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Vector.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>GradientStop.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientStop.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Eyedropper.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Eyedropper.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>AboutBox.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\AboutBox.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>GradientControl.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\GradientControl.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>SilentException.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\SilentException.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HermiteSettings.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HermiteSettings.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>ColourSelector.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\ColourSelector.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Channel.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Channel.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\CombinedChannel.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\CombinedChannel.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Settings2.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Settings2.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Mode0Channel.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Mode0Channel.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\DataPoint.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\DataPoint.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\CompressedDataPoint.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\CompressedDataPoint.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Mode3Channel.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Mode3Channel.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Generator2.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Generator2.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\GradientChannels.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\GradientChannels.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\GradientChannelsHelper.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\GradientChannelsHelper.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Mode2Channel.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Mode2Channel.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\ChannelType.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\ChannelType.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Configuration\Mode3ChannelPropertyTab.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode3ChannelPropertyTab.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Configuration\Mode0ChannelPropertyTab.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode0ChannelPropertyTab.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Configuration\Mode2ChannelPropertyTab.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode2ChannelPropertyTab.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Configuration\UnconfigurablePropertyTab.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\UnconfigurablePropertyTab.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Configuration\ColourChannelsRef.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\ColourChannelsRef.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Properties\Settings.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Properties\Settings.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Properties\Resources.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Properties\Resources.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>AssemblyInfo.cs:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\AssemblyInfo.cs</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>AboutBox.resx:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\AboutBox.resx</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>ColourSelector.resx:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\ColourSelector.resx</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Config2.resx:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Config2.resx</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Configuration\Mode0ChannelPropertyTab.resx:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode0ChannelPropertyTab.resx</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Configuration\Mode2ChannelPropertyTab.resx:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode2ChannelPropertyTab.resx</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HDMA\Configuration\Mode3ChannelPropertyTab.resx:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HDMA\Configuration\Mode3ChannelPropertyTab.resx</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>HermiteConfiguration.resx:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\HermiteConfiguration.resx</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Program.resx:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Program.resx</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Properties\Resources.resx:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Properties\Resources.resx</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Resources\blank.cur:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Resources\blank.cur</span></td></tr><tr name="MessageRowClassGradientTool" style="display: none"><td class="IconInfoEncoded"><a name="GradientToolMessage" /></td><td class="messageCell"><strong>Resources\InvertedCrosshair.cur:
</strong><span>File successfully backed up as C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\Disassembly\GradientTool\Backup\Resources\InvertedCrosshair.cur</span></td></tr><tr style="display: none" name="MessageRowHeaderHideGradientTool"><td class="IconInfoEncoded" /><td class="messageCell"><a _locID="HideAdditionalMessages" href="#" name="GradientToolMessage" onclick="ToggleMessageVisibility('GradientTool'); return false;">
Hide 51 additional messages
</a></td></tr></table></div></div></body></html>

393
Utils.cs Normal file
View File

@@ -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<string, string> s_records = new Dictionary<string, string>();
private static SaveFileDialog s_saveDialog = new SaveFileDialog();
internal static int IndexOfGradientStop(this IList<GradientStop> 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.");
}
}
}

306
Vector.cs Normal file
View File

@@ -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;
}
}
}