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

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