Upcoming support for wii u BFLIM, more nkm stuff

This commit is contained in:
Gericom 2015-02-07 12:28:53 +01:00
parent daeb0ee25e
commit 449e36d29b
13 changed files with 1917 additions and 6 deletions

View File

@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace LibEveryFileExplorer.GFX
{
public class DTX
{
public static uint[] DecodeDTX1(ushort Color0, ushort Color1, uint Data)
{
uint[] Palette = new uint[4];
Palette[0] = GFXUtil.ConvertColorFormat(Color0, ColorFormat.RGB565, ColorFormat.ARGB8888);
Palette[1] = GFXUtil.ConvertColorFormat(Color1, ColorFormat.RGB565, ColorFormat.ARGB8888);
Color a = Color.FromArgb((int)Palette[0]);
Color b = Color.FromArgb((int)Palette[1]);
if (Color0 > Color1)//1/3 and 2/3
{
Palette[2] = GFXUtil.ToColorFormat((a.R * 2 + b.R * 1) / 3, (a.G * 2 + b.G * 1) / 3, (a.B * 2 + b.B * 1) / 3, ColorFormat.ARGB8888);
Palette[3] = GFXUtil.ToColorFormat((a.R * 1 + b.R * 2) / 3, (a.G * 1 + b.G * 2) / 3, (a.B * 1 + b.B * 2) / 3, ColorFormat.ARGB8888);
}
else//1/2 and transparent
{
Palette[2] = GFXUtil.ToColorFormat((a.R + b.R) / 2, (a.G + b.G) / 2, (a.B + b.B) / 2, ColorFormat.ARGB8888);
Palette[3] = 0;
}
uint[] Result = new uint[4 * 4];
int q = 30;
for (int y = 0; y < 4; y++)
{
for (int x = 0; x < 4; x++)
{
Result[y * 4 + x] = Palette[(Data >> q) & 3];
q -= 2;
}
}
return Result;
}
public static uint[] DecodeDTX5(ushort Color0, ushort Color1, uint Data, ulong AData)
{
uint[] Result = DecodeDTX1(Color0, Color1, Data);
byte[] AlphaPalette = new byte[8];
AlphaPalette[0] = (byte)(AData & 0xFF);
AlphaPalette[1] = (byte)((AData >> 8) & 0xFF);
AData >>= 16;
if (AlphaPalette[0] > AlphaPalette[1])
{
AlphaPalette[2] = (byte)((6 * AlphaPalette[0] + 1 * AlphaPalette[1]) / 7);
AlphaPalette[3] = (byte)((5 * AlphaPalette[0] + 2 * AlphaPalette[1]) / 7);
AlphaPalette[4] = (byte)((4 * AlphaPalette[0] + 3 * AlphaPalette[1]) / 7);
AlphaPalette[5] = (byte)((3 * AlphaPalette[0] + 4 * AlphaPalette[1]) / 7);
AlphaPalette[6] = (byte)((2 * AlphaPalette[0] + 5 * AlphaPalette[1]) / 7);
AlphaPalette[7] = (byte)((1 * AlphaPalette[0] + 6 * AlphaPalette[1]) / 7);
}
else
{
AlphaPalette[2] = (byte)((4 * AlphaPalette[0] + 1 * AlphaPalette[1]) / 5);
AlphaPalette[3] = (byte)((3 * AlphaPalette[0] + 2 * AlphaPalette[1]) / 5);
AlphaPalette[4] = (byte)((2 * AlphaPalette[0] + 3 * AlphaPalette[1]) / 5);
AlphaPalette[5] = (byte)((1 * AlphaPalette[0] + 4 * AlphaPalette[1]) / 5);
AlphaPalette[6] = 0;
AlphaPalette[7] = 255;
}
int aq = 45;
for (int i = 0; i < 16; i++)
{
Result[i] = (Result[i] & 0xFFFFFF) | ((uint)AlphaPalette[(AData >> aq) & 7] << 24);
aq -= 3;
}
return Result;
}
}
}

View File

@ -82,6 +82,11 @@ namespace LibEveryFileExplorer.IO
return (ulong)Data[Offset] | ((ulong)Data[Offset + 1] << 8) | ((ulong)Data[Offset + 2] << 16) | ((ulong)Data[Offset + 3] << 24) | ((ulong)Data[Offset + 4] << 32) | ((ulong)Data[Offset + 5] << 40) | ((ulong)Data[Offset + 6] << 48) | ((ulong)Data[Offset + 7] << 56);
}
public static ulong ReadU64BE(byte[] Data, int Offset)
{
return ((ulong)Data[Offset] << 56) | ((ulong)Data[Offset + 1] << 48) | ((ulong)Data[Offset + 2] << 40) | ((ulong)Data[Offset + 3] << 32) | ((ulong)Data[Offset + 4] << 24) | ((ulong)Data[Offset + 5] << 16) | ((ulong)Data[Offset + 6] << 8) | ((ulong)Data[Offset + 7] << 0);
}
public static void WriteU64LE(byte[] Data, int Offset, ulong Value)
{
Data[Offset] = (byte)(Value & 0xFF);

View File

@ -58,6 +58,7 @@
<Compile Include="Files\IChildReactive.cs" />
<Compile Include="GFX\BitmapFont.cs" />
<Compile Include="GFX\ColorFormat.cs" />
<Compile Include="GFX\DTX.cs" />
<Compile Include="GFX\ETC1.cs" />
<Compile Include="GFX\PaletteUtil.cs" />
<Compile Include="Collections\Vector3.cs" />

View File

@ -48,14 +48,15 @@ namespace LibEveryFileExplorer.UI
}
if (listViewNF1.SelectedIndices.Count != 0) buttonRemove.Enabled = buttonUp.Enabled = buttonDown.Enabled = true;
else buttonRemove.Enabled = buttonUp.Enabled = buttonDown.Enabled = false;
if (!RemovingSelection && listViewNF1.SelectedIndices.Count == 0 && OnSelected != null) OnSelected(null, null);
//if (!RemovingSelection && listViewNF1.SelectedIndices.Count == 0 && OnSelected != null) OnSelected(null, null);
}
Timer t;
void listViewNF1_SelectedIndexChanged(object sender, EventArgs e)
{
t.Interval = 100;
if (!RemovingSelection && listViewNF1.SelectedIndices.Count == 0 && OnSelected != null) OnSelected(null, null);
t.Interval = 10;//100;
t.Enabled = true;
}
@ -164,6 +165,7 @@ namespace LibEveryFileExplorer.UI
bool RemovingSelection = false;
public void RemoveSelection()
{
if (listViewNF1.SelectedIndices.Count == 0) return;
RemovingSelection = true;
listViewNF1.SelectedItems.Clear();
RemovingSelection = false;

View File

@ -124,6 +124,12 @@
<Compile Include="UI\MapViewer\MKDSCheckPointPoint2RenderGroup.cs" />
<Compile Include="UI\MapViewer\MKDSCheckPointPoint1RenderGroup.cs" />
<Compile Include="UI\MapViewer\MKDSItemPointLineRenderGroup.cs" />
<Compile Include="UI\MKDSRouteViewer.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="UI\MKDSRouteViewer.Designer.cs">
<DependentUpon>MKDSRouteViewer.cs</DependentUpon>
</Compile>
<Compile Include="UI\NKMDViewer2.cs">
<SubType>Form</SubType>
</Compile>
@ -178,6 +184,9 @@
<EmbeddedResource Include="UI\CDMDViewer.resx">
<DependentUpon>CDMDViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\MKDSRouteViewer.resx">
<DependentUpon>MKDSRouteViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="UI\NKMDViewer2.resx">
<DependentUpon>NKMDViewer2.cs</DependentUpon>
</EmbeddedResource>

252
MarioKart/UI/MKDSRouteViewer.Designer.cs generated Normal file
View File

@ -0,0 +1,252 @@
namespace MarioKart.UI
{
partial class MKDSRouteViewer
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MKDSRouteViewer));
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.listViewNF1 = new LibEveryFileExplorer.UI.ListViewNF();
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.toolStrip2 = new System.Windows.Forms.ToolStrip();
this.listViewNF2 = new LibEveryFileExplorer.UI.ListViewNF();
this.buttonAdd = new System.Windows.Forms.ToolStripButton();
this.buttonRemove = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.buttonUp = new System.Windows.Forms.ToolStripButton();
this.buttonDown = new System.Windows.Forms.ToolStripButton();
this.buttonRouteAdd = new System.Windows.Forms.ToolStripButton();
this.buttonRouteRemove = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.buttonRouteUp = new System.Windows.Forms.ToolStripButton();
this.buttonRouteDown = new System.Windows.Forms.ToolStripButton();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.toolStrip1.SuspendLayout();
this.toolStrip2.SuspendLayout();
this.SuspendLayout();
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.listViewNF2);
this.splitContainer1.Panel1.Controls.Add(this.toolStrip1);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.listViewNF1);
this.splitContainer1.Panel2.Controls.Add(this.toolStrip2);
this.splitContainer1.Size = new System.Drawing.Size(474, 369);
this.splitContainer1.SplitterDistance = 173;
this.splitContainer1.TabIndex = 0;
//
// listViewNF1
//
this.listViewNF1.Dock = System.Windows.Forms.DockStyle.Fill;
this.listViewNF1.FullRowSelect = true;
this.listViewNF1.GridLines = true;
this.listViewNF1.HideSelection = false;
this.listViewNF1.Location = new System.Drawing.Point(0, 25);
this.listViewNF1.Name = "listViewNF1";
this.listViewNF1.Size = new System.Drawing.Size(297, 344);
this.listViewNF1.TabIndex = 0;
this.listViewNF1.UseCompatibleStateImageBehavior = false;
this.listViewNF1.View = System.Windows.Forms.View.Details;
//
// toolStrip1
//
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.buttonRouteAdd,
this.buttonRouteRemove,
this.toolStripSeparator2,
this.buttonRouteUp,
this.buttonRouteDown});
this.toolStrip1.Location = new System.Drawing.Point(0, 0);
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.Size = new System.Drawing.Size(173, 25);
this.toolStrip1.TabIndex = 0;
this.toolStrip1.Text = "toolStrip1";
//
// toolStrip2
//
this.toolStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.buttonAdd,
this.buttonRemove,
this.toolStripSeparator1,
this.buttonUp,
this.buttonDown});
this.toolStrip2.Location = new System.Drawing.Point(0, 0);
this.toolStrip2.Name = "toolStrip2";
this.toolStrip2.Size = new System.Drawing.Size(297, 25);
this.toolStrip2.TabIndex = 1;
this.toolStrip2.Text = "toolStrip2";
//
// listViewNF2
//
this.listViewNF2.Dock = System.Windows.Forms.DockStyle.Fill;
this.listViewNF2.FullRowSelect = true;
this.listViewNF2.GridLines = true;
this.listViewNF2.HideSelection = false;
this.listViewNF2.Location = new System.Drawing.Point(0, 25);
this.listViewNF2.MultiSelect = false;
this.listViewNF2.Name = "listViewNF2";
this.listViewNF2.Size = new System.Drawing.Size(173, 344);
this.listViewNF2.TabIndex = 1;
this.listViewNF2.UseCompatibleStateImageBehavior = false;
this.listViewNF2.View = System.Windows.Forms.View.Details;
this.listViewNF2.SelectedIndexChanged += new System.EventHandler(this.listViewNF2_SelectedIndexChanged);
//
// buttonAdd
//
this.buttonAdd.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.buttonAdd.Image = ((System.Drawing.Image)(resources.GetObject("buttonAdd.Image")));
this.buttonAdd.ImageTransparentColor = System.Drawing.Color.Magenta;
this.buttonAdd.Name = "buttonAdd";
this.buttonAdd.Size = new System.Drawing.Size(23, 22);
this.buttonAdd.Text = "Add";
//
// buttonRemove
//
this.buttonRemove.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.buttonRemove.Image = ((System.Drawing.Image)(resources.GetObject("buttonRemove.Image")));
this.buttonRemove.ImageTransparentColor = System.Drawing.Color.Magenta;
this.buttonRemove.Name = "buttonRemove";
this.buttonRemove.Size = new System.Drawing.Size(23, 22);
this.buttonRemove.Text = "Remove";
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
//
// buttonUp
//
this.buttonUp.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.buttonUp.Image = ((System.Drawing.Image)(resources.GetObject("buttonUp.Image")));
this.buttonUp.ImageTransparentColor = System.Drawing.Color.Magenta;
this.buttonUp.Name = "buttonUp";
this.buttonUp.Size = new System.Drawing.Size(23, 22);
this.buttonUp.Text = "Up";
//
// buttonDown
//
this.buttonDown.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.buttonDown.Image = ((System.Drawing.Image)(resources.GetObject("buttonDown.Image")));
this.buttonDown.ImageTransparentColor = System.Drawing.Color.Magenta;
this.buttonDown.Name = "buttonDown";
this.buttonDown.Size = new System.Drawing.Size(23, 22);
this.buttonDown.Text = "Down";
//
// buttonRouteAdd
//
this.buttonRouteAdd.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.buttonRouteAdd.Image = ((System.Drawing.Image)(resources.GetObject("buttonRouteAdd.Image")));
this.buttonRouteAdd.ImageTransparentColor = System.Drawing.Color.Magenta;
this.buttonRouteAdd.Name = "buttonRouteAdd";
this.buttonRouteAdd.Size = new System.Drawing.Size(23, 22);
this.buttonRouteAdd.Text = "Add";
//
// buttonRouteRemove
//
this.buttonRouteRemove.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.buttonRouteRemove.Image = ((System.Drawing.Image)(resources.GetObject("buttonRouteRemove.Image")));
this.buttonRouteRemove.ImageTransparentColor = System.Drawing.Color.Magenta;
this.buttonRouteRemove.Name = "buttonRouteRemove";
this.buttonRouteRemove.Size = new System.Drawing.Size(23, 22);
this.buttonRouteRemove.Text = "Remove";
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
//
// buttonRouteUp
//
this.buttonRouteUp.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.buttonRouteUp.Image = ((System.Drawing.Image)(resources.GetObject("buttonRouteUp.Image")));
this.buttonRouteUp.ImageTransparentColor = System.Drawing.Color.Magenta;
this.buttonRouteUp.Name = "buttonRouteUp";
this.buttonRouteUp.Size = new System.Drawing.Size(23, 22);
this.buttonRouteUp.Text = "Up";
//
// buttonRouteDown
//
this.buttonRouteDown.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.buttonRouteDown.Image = ((System.Drawing.Image)(resources.GetObject("buttonRouteDown.Image")));
this.buttonRouteDown.ImageTransparentColor = System.Drawing.Color.Magenta;
this.buttonRouteDown.Name = "buttonRouteDown";
this.buttonRouteDown.Size = new System.Drawing.Size(23, 22);
this.buttonRouteDown.Text = "Down";
//
// MKDSRouteViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.splitContainer1);
this.Name = "MKDSRouteViewer";
this.Size = new System.Drawing.Size(474, 369);
this.Load += new System.EventHandler(this.MKDSRouteViewer_Load);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.Panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
this.toolStrip2.ResumeLayout(false);
this.toolStrip2.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.SplitContainer splitContainer1;
private LibEveryFileExplorer.UI.ListViewNF listViewNF2;
private System.Windows.Forms.ToolStrip toolStrip1;
private LibEveryFileExplorer.UI.ListViewNF listViewNF1;
private System.Windows.Forms.ToolStrip toolStrip2;
internal System.Windows.Forms.ToolStripButton buttonRouteAdd;
internal System.Windows.Forms.ToolStripButton buttonRouteRemove;
internal System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
internal System.Windows.Forms.ToolStripButton buttonRouteUp;
internal System.Windows.Forms.ToolStripButton buttonRouteDown;
internal System.Windows.Forms.ToolStripButton buttonAdd;
internal System.Windows.Forms.ToolStripButton buttonRemove;
internal System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
internal System.Windows.Forms.ToolStripButton buttonUp;
internal System.Windows.Forms.ToolStripButton buttonDown;
}
}

View File

@ -0,0 +1,117 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LibEveryFileExplorer.UI;
using MarioKart.MKDS.NKM;
namespace MarioKart.UI
{
public partial class MKDSRouteViewer : UserControl, IGameDataSectionViewer
{
PATH Routes;
POIT Points;
public MKDSRouteViewer(PATH Routes, POIT Points)
{
this.Routes = Routes;
this.Points = Points;
InitializeComponent();
}
private void listViewNF2_SelectedIndexChanged(object sender, EventArgs e)
{
RefreshPoints();
}
public event SelectedEventHandler OnSelected;
public void RefreshListView()
{
int[] sel = null;
if (listViewNF2.SelectedIndices.Count != 0)
{
sel = new int[listViewNF2.SelectedIndices.Count];
listViewNF2.SelectedIndices.CopyTo(sel, 0);
}
listViewNF2.BeginUpdate();
listViewNF2.Items.Clear();
listViewNF2.Items.AddRange(Routes.GetListViewItems());
listViewNF2.EndUpdate();
if (sel != null)
{
foreach (int i in sel)
{
if (i < Routes.Entries.Count) listViewNF2.SelectedIndices.Add(i);
}
}
RefreshPoints();
}
private void RefreshPoints()
{
if (listViewNF2.SelectedIndices.Count != 0)
{
listViewNF1.BeginUpdate();
listViewNF1.Items.Clear();
int idx = 0;
int q = 0;
foreach (var o in Routes.Entries)
{
if (Points.NrEntries < o.NrPoit + idx) break;
if (q == listViewNF2.SelectedIndices[0])
{
for (int i = 0; i < o.NrPoit; i++)
{
var v = Points[idx + i].GetListViewItem();
v.Text = (idx + i).ToString();
listViewNF1.Items.Add(v);
}
break;
}
idx += o.NrPoit;
q++;
}
listViewNF1.EndUpdate();
}
else
{
listViewNF1.BeginUpdate();
listViewNF1.Items.Clear();
listViewNF1.EndUpdate();
}
}
private void MKDSRouteViewer_Load(object sender, EventArgs e)
{
listViewNF1.BeginUpdate();
listViewNF1.Columns.Clear();
foreach (String s in Points.GetColumnNames()) listViewNF1.Columns.Add(s);
listViewNF1.EndUpdate();
listViewNF2.BeginUpdate();
listViewNF2.Columns.Clear();
foreach (String s in Routes.GetColumnNames()) listViewNF2.Columns.Add(s);
listViewNF2.EndUpdate();
RefreshListView();
}
public void UpdateListViewEntry(params object[] Entries)
{
//throw new NotImplementedException();
}
public void Select(params object[] Entries)
{
//throw new NotImplementedException();
}
public void RemoveSelection()
{
//throw new NotImplementedException();
}
}
}

View File

@ -0,0 +1,221 @@
<?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>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="toolStrip2.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>122, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="buttonAdd.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFVSURBVDhPtY67L8NRGIaPSzpI0R+tVNuEFBGqiaYTdYlL
xK3ULUFE1CYmdpvF0MUgOlhI3WMh5roHR8Igqc3IX/H6vpMTQ7VNfoMneZI373fe5Ij/49ARF8cOqeRs
mgO7jH6vYuFrBZx1a4KEXU5/LoHlrFsT7Bpy7GMRkVQUnHVrgh1DDrzNov91Bpx1m4W4LS626VGaPc+T
6HocR6ab2vyyZZPh93n0yinwqPtpQg1br4fQcjWIjvtRtN+NoO02jNDNsMq80Wtis1TyVzsfIkoe8LDx
PITqo4DSnWiCa88HT8IP70kQvNFrIlYcFzGrTNdz5ofr1IdMN7XJyYZVOi8bUHFRD866NcG6VdqTdShP
1oKzbk2wViTLXmpgSC8469YEyxZppLxgOes2J4Wkm2wmg6Ivb1/M5UslZ+6ECJBVpIX8Qz5ZQjpJVxYr
SRtZQBJC/ADGtKxvV2OcbwAAAABJRU5ErkJggg==
</value>
</data>
<data name="buttonRemove.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACtSURBVDhPYxgFgwUsY2CYuZyB4QwpGKQHqp2BYS5Q4F1a
2v/H0dH/74aG/r/u7///kpfX/7Ourv9POzv/P+no+P+Eg8P/4/b2/4/Z2YHZID1Q7QwMfUDO8/j4/7eC
gv5f8fH5f87NDawJpPiore3/IzY2/w9bW/8/ZGX1/6ClJZgG6YFqZ5CJZmBYVAEUIAWD9ID0ggzgA2Ih
IBYHYikiMUgtSA9I7yigDDAwAADO52St0AETFQAAAABJRU5ErkJggg==
</value>
</data>
<data name="buttonUp.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGESURBVDhPtYtNKMNhHMdneSmkSBMHciCUKCuRl4sclIOD
KH9J5CInB9luLuLgLcawixWx1hrZxsFF4/I4kJSXzctMpO2g1iT29fzyeMmG/8WnPj19f9/vo/g3qg23
UpXhltErTvKpmLuRKmc8TO8F6KUsqr8pn7qQynSXbNoDaHcfobsCKNNdTH5GPXYiqUeO2dRlCD0bDx+O
u15Ad+rFNJyiwQOpaOiQTbhf0LXqD3P46AnU0058+SR/YE8qGNhjo6fP0OwE0O8MoNvuQ5PxHC1LbnRY
LtBmcqFv+x60o734+kaudkefo3Gyr7abXagZY2hdPsP3jvbia2SyerdYs8mNqsl9NC67QFlU8kjvtrE6
sxfFs2eoXbkGZVHJI7XTwkqtfmQa71Bi8YGyqOSRKC2xnPUgkkwBZK8FQVlU8ohvWmAqRwhKawgp9hAo
i0oeMQ3zTLUJJNqAZAdAWVS/EsfN45ZElfcuKutn2LuU6c4t5CZwIxLNTeVm/GIaN5YrUCheAR5z8efG
/ZWxAAAAAElFTkSuQmCC
</value>
</data>
<data name="buttonDown.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGISURBVDhPtYtJKMRhGManYUrWlGRkqSklF+tFGAeccFC2
w5+yxAEHIcVBnLigSEY4GKUx2TPCZCscfA6KgyxDJsyF0GTUNI/vzWfJ+r/41a+v53ueV/EvpA7bdNqh
a/YqZVHJI6X/gvWeAV1HLvRYAMqikkdi3znrOHCieduB9n0nKItKHgmdh6x114GaxXu07DyCsqjkEd2x
z5q37aiYvUHTlh2URSWPqLZd1rB+hwK9BZVzVlAWlTwimjZZycQJ0rsZigzHoCyq7wmpNevC61bYRwuN
p9D27iHPcILPHe3F6QtB1SZJXWVi1Zt3yJq+QubUJVJGzxEzcIwk/RkyjFakj1uRO28D7WgvTt8JLJuU
AsqnWP7GA8L0ti+mLdyCetqJk6/4FBskb2mMadee4Gu0vxm75AD9Uy+mP+NVqJc8C0ZY5KoLyhkXNGYX
KNO/mPyNMrlRUuUMsuBlgF7KovoVFTeUG8eNV8aV1iuz+xm9lIUargf3W9y4flw1N/gH/bnuXIFC8QzC
r+rkeChKNQAAAABJRU5ErkJggg==
</value>
</data>
<data name="buttonRouteAdd.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFVSURBVDhPtY67L8NRGIaPSzpI0R+tVNuEFBGqiaYTdYlL
xK3ULUFE1CYmdpvF0MUgOlhI3WMh5roHR8Igqc3IX/H6vpMTQ7VNfoMneZI373fe5Ij/49ARF8cOqeRs
mgO7jH6vYuFrBZx1a4KEXU5/LoHlrFsT7Bpy7GMRkVQUnHVrgh1DDrzNov91Bpx1m4W4LS626VGaPc+T
6HocR6ab2vyyZZPh93n0yinwqPtpQg1br4fQcjWIjvtRtN+NoO02jNDNsMq80Wtis1TyVzsfIkoe8LDx
PITqo4DSnWiCa88HT8IP70kQvNFrIlYcFzGrTNdz5ofr1IdMN7XJyYZVOi8bUHFRD866NcG6VdqTdShP
1oKzbk2wViTLXmpgSC8469YEyxZppLxgOes2J4Wkm2wmg6Ivb1/M5UslZ+6ECJBVpIX8Qz5ZQjpJVxYr
SRtZQBJC/ADGtKxvV2OcbwAAAABJRU5ErkJggg==
</value>
</data>
<data name="buttonRouteRemove.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACtSURBVDhPYxgFgwUsY2CYuZyB4QwpGKQHqp2BYS5Q4F1a
2v/H0dH/74aG/r/u7///kpfX/7Ourv9POzv/P+no+P+Eg8P/4/b2/4/Z2YHZID1Q7QwMfUDO8/j4/7eC
gv5f8fH5f87NDawJpPiore3/IzY2/w9bW/8/ZGX1/6ClJZgG6YFqZ5CJZmBYVAEUIAWD9ID0ggzgA2Ih
IBYHYikiMUgtSA9I7yigDDAwAADO52St0AETFQAAAABJRU5ErkJggg==
</value>
</data>
<data name="buttonRouteUp.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGESURBVDhPtYtNKMNhHMdneSmkSBMHciCUKCuRl4sclIOD
KH9J5CInB9luLuLgLcawixWx1hrZxsFF4/I4kJSXzctMpO2g1iT29fzyeMmG/8WnPj19f9/vo/g3qg23
UpXhltErTvKpmLuRKmc8TO8F6KUsqr8pn7qQynSXbNoDaHcfobsCKNNdTH5GPXYiqUeO2dRlCD0bDx+O
u15Ad+rFNJyiwQOpaOiQTbhf0LXqD3P46AnU0058+SR/YE8qGNhjo6fP0OwE0O8MoNvuQ5PxHC1LbnRY
LtBmcqFv+x60o734+kaudkefo3Gyr7abXagZY2hdPsP3jvbia2SyerdYs8mNqsl9NC67QFlU8kjvtrE6
sxfFs2eoXbkGZVHJI7XTwkqtfmQa71Bi8YGyqOSRKC2xnPUgkkwBZK8FQVlU8ohvWmAqRwhKawgp9hAo
i0oeMQ3zTLUJJNqAZAdAWVS/EsfN45ZElfcuKutn2LuU6c4t5CZwIxLNTeVm/GIaN5YrUCheAR5z8efG
/ZWxAAAAAElFTkSuQmCC
</value>
</data>
<data name="buttonRouteDown.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGISURBVDhPtYtJKMRhGManYUrWlGRkqSklF+tFGAeccFC2
w5+yxAEHIcVBnLigSEY4GKUx2TPCZCscfA6KgyxDJsyF0GTUNI/vzWfJ+r/41a+v53ueV/EvpA7bdNqh
a/YqZVHJI6X/gvWeAV1HLvRYAMqikkdi3znrOHCieduB9n0nKItKHgmdh6x114GaxXu07DyCsqjkEd2x
z5q37aiYvUHTlh2URSWPqLZd1rB+hwK9BZVzVlAWlTwimjZZycQJ0rsZigzHoCyq7wmpNevC61bYRwuN
p9D27iHPcILPHe3F6QtB1SZJXWVi1Zt3yJq+QubUJVJGzxEzcIwk/RkyjFakj1uRO28D7WgvTt8JLJuU
AsqnWP7GA8L0ti+mLdyCetqJk6/4FBskb2mMadee4Gu0vxm75AD9Uy+mP+NVqJc8C0ZY5KoLyhkXNGYX
KNO/mPyNMrlRUuUMsuBlgF7KovoVFTeUG8eNV8aV1iuz+xm9lIUargf3W9y4flw1N/gH/bnuXIFC8QzC
r+rkeChKNQAAAABJRU5ErkJggg==
</value>
</data>
</root>

View File

@ -49,6 +49,15 @@ namespace MarioKart.UI
if (NKMD.ObjectInformation != null) AddTab<MKDS.NKM.OBJI.OBJIEntry>("OBJI", NKMD.ObjectInformation);
if (NKMD.Path != null) AddTab<PATH.PATHEntry>("PATH", NKMD.Path);
if (NKMD.Point != null) AddTab<POIT.POITEntry>("POIT", NKMD.Point);
if (NKMD.Path != null && NKMD.Point != null)
{
TabPage p = new TabPage("Routes");
var vv = new MKDSRouteViewer(NKMD.Path, NKMD.Point) { Dock = DockStyle.Fill };
vv.OnSelected += new SelectedEventHandler(GameDataSectionViewer_OnSelected);
SectionViewers.Add(vv);
p.Controls.Add(vv);
tabControl1.TabPages.Add(p);
}
if (NKMD.KartPointStart != null) AddTab<KTPS.KTPSEntry>("KTPS", NKMD.KartPointStart);
if (NKMD.KartPointJugem != null) AddTab<KTPJ.KTPJEntry>("KTPJ", NKMD.KartPointJugem);
if (NKMD.KartPointSecond != null) AddTab<KTP2.KTP2Entry>("KTP2", NKMD.KartPointSecond);

731
WiiU/GPU/R600Tiling.cs Normal file
View File

@ -0,0 +1,731 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WiiU.GPU
{
public class R600Tiling
{
private static readonly uint[] bankSwapOrder = { 0, 1, 3, 2, 6, 7, 5, 4 };
uint m_class = 6;
uint m_chipFamily = 0;
uint m_chipRevision = 0;
uint m_version = 502;
uint m_pElemLib = 0;
uint m_pipes = 2;//0;
uint m_banks = 8;//0;
uint m_pipeInterleaveBytes = 256;
uint m_rowSize = 2048;//0;
uint m_backendDisables = 0;
uint m_configFlags = 0;
uint m_swapSize = 256;//0;
uint m_splitSize = 2048;//0;
public struct _ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
{
public uint size; //dd ?
public uint x; // dd ?
public uint y; //dd ?
public uint slice; //dd ?
public uint sample; //dd ?
public uint bpp; //dd ?
public uint pitch; //dd ?
public uint height; //dd ?
public uint numSlices; //dd ?
public uint numSamples; //dd ?
public int tileMode; // dd ? ; enum _AddrTileMode
public bool isDepth; //dd ?
public uint tileBase; //dd ?
public uint compBits; // dd ?
public uint pipeSwizzle; //dd ?
public uint bankSwizzle; //dd ?
public uint numFrags; //dd ?
public int tileType; //dd ? ; enum _AddrTileType
public uint _bf72; //dd ?
public uint pTileInfo; //dd ? ; offset
public uint tileIndex; //dd ?
}
public struct _ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
{
public uint size; // dd ?
//byte db ? ; undefined
//byte db ? ; undefined
//byte db ? ; undefined
//byte db ? ; undefined
public ulong addr; // dq ?
public uint bitPosition; // dd ?
//byte _padding db 4 dup(?)
}
public ulong ComputeSurfaceAddrFromCoord(/*R600AddrLib *this, */ref _ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT pIn, ref _ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT pOut)
{
/* _AddrTileMode*/
int v3; // ecx@4
ulong v4 = 0; // qax@5
ulong result; // qax@9
/*_AddrTileMode*/
int v6; // [sp+4h] [bp-4Ch]@1
uint v7; // [sp+8h] [bp-48h]@2
//uint /***/pBitPosition; // [sp+Ch] [bp-44h]@4
uint bankSwizzle; // [sp+10h] [bp-40h]@4
uint pipeSwizzle; // [sp+14h] [bp-3Ch]@4
uint compBits; // [sp+18h] [bp-38h]@4
uint tileBase; // [sp+1Ch] [bp-34h]@4
bool isDepth; // [sp+20h] [bp-30h]@4
/*_AddrTileMode*/
int tileMode; // [sp+24h] [bp-2Ch]@4
uint numSamples; // [sp+28h] [bp-28h]@4
uint numSlices; // [sp+2Ch] [bp-24h]@1
uint height; // [sp+30h] [bp-20h]@1
uint pitch; // [sp+34h] [bp-1Ch]@1
uint bpp; // [sp+38h] [bp-18h]@1
uint sample; // [sp+3Ch] [bp-14h]@1
uint slice; // [sp+40h] [bp-10h]@1
uint y; // [sp+44h] [bp-Ch]@1
uint x; // [sp+48h] [bp-8h]@1
// AddrLib *thisa; // [sp+4Ch] [bp-4h]@1
//memset(&v6, -858993460, 0x4Cu);
// thisa = (AddrLib *)this;
x = pIn.x;
y = pIn.y;
slice = pIn.slice;
sample = pIn.sample;
bpp = pIn.bpp;
pitch = pIn.pitch;
height = pIn.height;
numSlices = pIn.numSlices;
if (pIn.numSamples != 0)
v7 = pIn.numSamples;
else
v7 = 1;
numSamples = v7;
tileMode = pIn.tileMode;
isDepth = pIn.isDepth;
tileBase = pIn.tileBase;
compBits = pIn.compBits;
pipeSwizzle = pIn.pipeSwizzle;
bankSwizzle = pIn.bankSwizzle;
//pBitPosition = &pOut->bitPosition;
v6 = tileMode;
v3 = tileMode;
switch (tileMode)
{
case 0:
case 1:
/*v4 = ComputeSurfaceAddrFromCoordLinear(
thisa,
x,
y,
slice,
sample,
bpp,
pitch,
height,
numSlices,
pBitPosition);*/
break;
case 2:
case 3:
/* v4 = ComputeSurfaceAddrFromCoordMicroTiled(
(R600AddrLib *)thisa,
x,
y,
slice,
bpp,
pitch,
height,
tileMode,
isDepth,
tileBase,
compBits,
pBitPosition);*/
break;
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
case 15:
v4 = ComputeSurfaceAddrFromCoordMacroTiled(
//(R600AddrLib *)thisa,
x,
y,
slice,
sample,
bpp,
pitch,
height,
numSamples,
tileMode,
isDepth,
tileBase,
compBits,
pipeSwizzle,
bankSwizzle,
out pOut.bitPosition);// pBitPosition);
break;
default:
v4 = 0;
//HIDWORD(v4) = 0;
break;
}
//LODWORD(result) = _RTC_CheckEsp(v3, HIDWORD(v4));
//return result;
return v4;
}
private static uint Log2_0(uint x)
{
uint y; // [sp+0h] [bp-4h]@1
y = 0;
while (x > 1)
{
x >>= 1;
++y;
}
return y;
}
private ulong ComputeSurfaceAddrFromCoordMacroTiled(/*R600AddrLib *this, */uint x, uint y, uint slice, uint sample, uint bpp, uint pitch, uint height, uint numSamples, /*_AddrTileMode*/int tileMode, bool isDepth, uint tileBase, uint compBits, uint pipeSwizzle, uint bankSwizzle, /*unsigned int **/out uint pBitPosition)
{
/*_AddrTileType*/
int v16; // eax@1
ulong v17; // qax@24
ulong result; // qax@24
int v19; // [sp+8h] [bp-C8h]@1
uint swapIndex; // [sp+Ch] [bp-C4h]@23
uint bankSwapWidth; // [sp+10h] [bp-C0h]@23
uint sliceIn; // [sp+14h] [bp-BCh]@12
uint bankPipe; // [sp+18h] [bp-B8h]@12
uint swizzle; // [sp+1Ch] [bp-B4h]@12
uint rotation; // [sp+20h] [bp-B0h]@12
uint tileSliceBits; // [sp+24h] [bp-ACh]@10
uint bytesPerSample; // [sp+28h] [bp-A8h]@8
uint numBanks; // [sp+2Ch] [bp-A4h]@1
uint numPipes; // [sp+30h] [bp-A0h]@1
ulong groupMask; // [sp+34h] [bp-9Ch]@24
uint elemOffset; // [sp+54h] [bp-7Ch]@8
uint pixelOffset; // [sp+58h] [bp-78h]@4
uint sampleOffset; // [sp+5Ch] [bp-74h]@4
uint pixelIndex; // [sp+60h] [bp-70h]@1
ulong macroTileOffset; // [sp+64h] [bp-6Ch]@17
uint macroTileIndexY; // [sp+6Ch] [bp-64h]@17
uint macroTileIndexX; // [sp+70h] [bp-60h]@17
long macroTileBytes; // [sp+74h] [bp-5Ch]@17
uint macroTilesPerRow; // [sp+7Ch] [bp-54h]@17
uint macroTileHeight; // [sp+80h] [bp-50h]@14
uint macroTilePitch; // [sp+84h] [bp-4Ch]@14
ulong sliceOffset; // [sp+88h] [bp-48h]@14
ulong sliceBytes; // [sp+90h] [bp-40h]@14
uint microTileThickness; // [sp+98h] [bp-38h]@1
uint bank; // [sp+9Ch] [bp-34h]@12
uint pipe; // [sp+A0h] [bp-30h]@12
uint sampleSlice; // [sp+A4h] [bp-2Ch]@10
uint numSampleSplits; // [sp+A8h] [bp-28h]@10
uint samplesPerSlice; // [sp+ACh] [bp-24h]@10
uint microTileBits; // [sp+B0h] [bp-20h]@1
uint microTileBytes; // [sp+B4h] [bp-1Ch]@1
uint numBankBits; // [sp+B8h] [bp-18h]@1
uint numPipeBits; // [sp+BCh] [bp-14h]@1
uint numGroupBits; // [sp+C0h] [bp-10h]@1
//R600AddrLib *thisa; // [sp+CCh] [bp-4h]@1
numPipes = this/*->baseclass_0*/.m_pipes;
numBanks = this/*->baseclass_0*/.m_banks;
numGroupBits = Log2_0(this/*->baseclass_0*/.m_pipeInterleaveBytes);
numPipeBits = Log2_0(this/*a->baseclass_0*/.m_pipes);
numBankBits = Log2_0(this/*a->baseclass_0*/.m_banks);
microTileThickness = ComputeSurfaceThickness(tileMode);
microTileBits = numSamples * bpp * (microTileThickness << 6);
microTileBytes = numSamples * bpp * (microTileThickness << 6) >> 3;
v16 = GetTileType(isDepth);
pixelIndex = ComputePixelIndexWithinMicroTile(/*&thisa->baseclass_0,*/ x, y, slice, bpp, tileMode, v16);
if (isDepth)
{
if (compBits != 0 && compBits != bpp)
{
sampleOffset = tileBase + compBits * sample;
pixelOffset = numSamples * compBits * pixelIndex;
}
else
{
sampleOffset = bpp * sample;
pixelOffset = numSamples * bpp * pixelIndex;
}
}
else
{
sampleOffset = sample * microTileBits / numSamples;
pixelOffset = bpp * pixelIndex;
}
elemOffset = pixelOffset + sampleOffset;
pBitPosition = (pixelOffset + sampleOffset) % 8;//*pBitPosition = (pixelOffset + sampleOffset) % 8;
bytesPerSample = microTileBytes / numSamples;
if (numSamples <= 1 || microTileBytes <= this/*a->*/.m_splitSize)
{
samplesPerSlice = numSamples;
numSampleSplits = 1;
sampleSlice = 0;
}
else
{
samplesPerSlice = this/*a->*/.m_splitSize / bytesPerSample;
numSampleSplits = numSamples / samplesPerSlice;
numSamples = samplesPerSlice;
tileSliceBits = microTileBits / numSampleSplits;
sampleSlice = elemOffset / (microTileBits / numSampleSplits);
elemOffset %= microTileBits / numSampleSplits;
}
elemOffset >>= 3;
pipe = ComputePipeFromCoordWoRotation(/*thisa, */x, y);
bank = ComputeBankFromCoordWoRotation(/*thisa, */x, y);
bankPipe = pipe + numPipes * bank;
rotation = ComputeSurfaceRotationFromTileMode(/*thisa, */tileMode);
swizzle = pipeSwizzle + numPipes * bankSwizzle;
sliceIn = slice;
if (IsThickMacroTiled(tileMode))
sliceIn >>= 2;
bankPipe ^= numPipes * sampleSlice * ((numBanks >> 1) + 1) ^ (swizzle + sliceIn * rotation);
bankPipe %= numPipes * numBanks;
pipe = bankPipe % numPipes;
bank = bankPipe / numPipes;
sliceBytes = (height * (ulong)pitch * microTileThickness * bpp * numSamples + 7) / 8;
sliceOffset = sliceBytes * (sampleSlice + numSampleSplits * slice) / microTileThickness;
macroTilePitch = 8 * this/*a->baseclass_0*/.m_banks;
macroTileHeight = 8 * this/*a->baseclass_0*/.m_pipes;
v19 = tileMode - 5;
switch (tileMode)
{
case 5:
case 9:
macroTilePitch >>= 1;
macroTileHeight *= 2;
break;
case 6:
case 10:
macroTilePitch >>= 2;
macroTileHeight *= 4;
break;
default:
break;
}
macroTilesPerRow = pitch / macroTilePitch;
macroTileBytes = (numSamples * microTileThickness * bpp * macroTileHeight * macroTilePitch + 7) >> 3;
macroTileIndexX = x / macroTilePitch;
macroTileIndexY = y / macroTileHeight;
macroTileOffset = (x / macroTilePitch + pitch / macroTilePitch * y / macroTileHeight)
* (ulong)((numSamples * microTileThickness * bpp * macroTileHeight * macroTilePitch + 7) >> 3);
if (tileMode == 8 || tileMode == 9 || tileMode == 10 || tileMode == 11 || tileMode == 14 || tileMode == 15)
{
uint nop;
bankSwapWidth = ComputeSurfaceBankSwappedWidth(/*thisa,*/ tileMode, bpp, numSamples, pitch, out nop);//0);
swapIndex = macroTilePitch * macroTileIndexX / bankSwapWidth;
bank ^= bankSwapOrder[swapIndex & (this/*a->baseclass_0*/.m_banks - 1)];
}
v17 = elemOffset + ((macroTileOffset + sliceOffset) >> ((byte)numBankBits + (byte)numPipeBits));
groupMask = (1u << (int)numGroupBits) - 1;
ulong addr = ((v17 & (ulong)~(long)((1 << (int)numGroupBits) - 1)) << ((byte)numBankBits
+ (byte)numPipeBits)) | groupMask & v17 | (pipe << (int)numGroupBits);
addr = addr | (bank << (int)(numPipeBits + numGroupBits));
return addr;
}
private static bool IsBankSwappedTileMode(/*_AddrTileMode*/ int tileMode)
{
bool bankSwapped; // [sp+4h] [bp-4h]@1
bankSwapped = false;
switch (tileMode)
{
case 8:
case 9:
case 10:
case 11:
case 14:
case 15:
bankSwapped = true;
break;
default:
return bankSwapped;
}
return bankSwapped;
}
private static uint ComputeMacroTileAspectRatio(/*_AddrTileMode*/int tileMode)
{
uint ratio; // [sp+4h] [bp-4h]@1
ratio = 1;
switch (tileMode)
{
case 8:
case 12:
case 14:
ratio = 1;
break;
case 5:
case 9:
ratio = 2;
break;
case 6:
case 10:
ratio = 4;
break;
default:
return ratio;
}
return ratio;
}
private uint ComputeSurfaceBankSwappedWidth(/*R600AddrLib *this, *//*_AddrTileMode*/int tileMode, uint bpp, uint numSamples, uint pitch, out uint /***/pSlicesPerTile)
{
uint v6; // edx@6
uint v7; // ecx@6
uint v9; // [sp+4h] [bp-54h]@1
uint v10; // [sp+8h] [bp-50h]@11
uint v11; // [sp+Ch] [bp-4Ch]@8
uint swapMin; // [sp+10h] [bp-48h]@10
uint swapMax; // [sp+14h] [bp-44h]@10
uint heightBytes; // [sp+18h] [bp-40h]@10
uint swapWidth; // [sp+1Ch] [bp-3Ch]@10
uint swapTiles; // [sp+20h] [bp-38h]@7
uint factor; // [sp+24h] [bp-34h]@7
uint bytesPerTileSlice; // [sp+28h] [bp-30h]@6
uint samplesPerTile; // [sp+2Ch] [bp-2Ch]@1
uint bytesPerSample; // [sp+30h] [bp-28h]@1
int slicesPerTile; // [sp+34h] [bp-24h]@1
uint groupSize; // [sp+38h] [bp-20h]@1
uint splitSize; // [sp+3Ch] [bp-1Ch]@1
uint rowSize; // [sp+40h] [bp-18h]@1
uint swapSize; // [sp+44h] [bp-14h]@1
uint numPipes; // [sp+48h] [bp-10h]@1
uint numBanks; // [sp+4Ch] [bp-Ch]@1
uint bankSwapWidth; // [sp+50h] [bp-8h]@1
/*R600AddrLib *thisa;*/
// [sp+54h] [bp-4h]@1
//memset(&v9, -858993460, 0x54u);
//thisa = this;
bankSwapWidth = 0;
numBanks = this/*->baseclass_0*/.m_banks;
numPipes = this/*->baseclass_0*/.m_pipes;
swapSize = this/*->*/.m_swapSize;
rowSize = this/*->baseclass_0*/.m_rowSize;
splitSize = this/*->*/.m_splitSize;
groupSize = this/*->baseclass_0*/.m_pipeInterleaveBytes;
slicesPerTile = 1;
bytesPerSample = 8 * bpp & 0x1FFFFFFF;
samplesPerTile = splitSize / bytesPerSample;
if ((splitSize / bytesPerSample) != 0)
{
slicesPerTile = (int)(numSamples / samplesPerTile);
if ((numSamples / samplesPerTile) == 0)
slicesPerTile = 1;
}
pSlicesPerTile = (uint)slicesPerTile;
//SafeAssign_2(pSlicesPerTile, slicesPerTile);
if (IsThickMacroTiled(tileMode))
numSamples = 4;
bytesPerTileSlice = (uint)(numSamples * bytesPerSample / slicesPerTile);
if (IsBankSwappedTileMode(tileMode))
{
factor = ComputeMacroTileAspectRatio(tileMode);
swapTiles = (swapSize >> 1) / bpp;
if (swapTiles != 0)
v11 = swapTiles;
else
v11 = 1;
v7 = v11 * 8 * numBanks;
swapWidth = v11 * 8 * numBanks;
heightBytes = (uint)(numSamples * factor * numPipes * bpp / slicesPerTile);
swapMax = numPipes * numBanks * rowSize / heightBytes;
swapMin = groupSize * 8 * numBanks / bytesPerTileSlice;
if (numPipes * numBanks * rowSize / heightBytes >= swapWidth)
{
if (swapMin <= swapWidth)
v9 = swapWidth;
else
v9 = swapMin;
v7 = v9;
v10 = v9;
}
else
{
v10 = swapMax;
}
v6 = v10;
for (bankSwapWidth = v10; bankSwapWidth >= 2 * pitch; bankSwapWidth >>= 1)
v7 = bankSwapWidth >> 1;
}
return bankSwapWidth;//_RTC_CheckEsp(v7, v6);
}
private static bool IsThickMacroTiled(/*_AddrTileMode*/int tileMode)
{
bool thickMacroTiled; // [sp+4h] [bp-4h]@1
thickMacroTiled = false;
switch (tileMode)
{
case 7:
case 11:
case 13:
case 15:
thickMacroTiled = true;
break;
default:
return thickMacroTiled;
}
return thickMacroTiled;
}
private uint ComputeSurfaceRotationFromTileMode(/*R600AddrLib *this, *//*_AddrTileMode*/int tileMode)
{
uint result; // eax@2
uint v3; // [sp+0h] [bp-14h]@4
uint pipes; // [sp+Ch] [bp-8h]@1
pipes = this/*->baseclass_0*/.m_pipes;
switch (tileMode)
{
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
result = pipes * ((this/*->baseclass_0*/.m_banks >> 1) - 1);
break;
case 12:
case 13:
case 14:
case 15:
if (pipes >= 4)
v3 = (pipes >> 1) - 1;
else
v3 = 1;
result = v3;
break;
default:
result = 0;
break;
}
return result;
}
private uint ComputePipeFromCoordWoRotation(/*R600AddrLib *this, */uint x, uint y)
{
int pipe; // [sp+14h] [bp-8h]@2
switch (this/*->baseclass_0*/.m_pipes)
{
case 1u:
pipe = 0;
break;
case 2u:
pipe = ((byte)(y >> 3) ^ (byte)(x >> 3)) & 1;
break;
case 4u:
pipe = ((byte)(y >> 3) ^ (byte)(x >> 4)) & 1 | 2
* (((byte)(y >> 4) ^ (byte)(x >> 3)) & 1);
break;
case 8u:
pipe = ((byte)(y >> 3) ^ (byte)(x >> 5)) & 1 | 2
* (((byte)(y >> 4) ^ (byte)((x >> 5) ^ (x >> 4))) & 1) | 4 * (((byte)(y >> 5) ^ (byte)(x >> 3)) & 1);
break;
default:
pipe = 0;
break;
}
return (uint)pipe;
}
private uint ComputeBankFromCoordWoRotation(/*R600AddrLib *this, */uint x, uint y)
{
uint bankOpt; // [sp+8h] [bp-20h]@1
uint numBanks; // [sp+Ch] [bp-1Ch]@1
uint numPipes; // [sp+10h] [bp-18h]@1
uint bankBit0; // [sp+1Ch] [bp-Ch]@4
uint bankBit0a; // [sp+1Ch] [bp-Ch]@8
uint bank; // [sp+20h] [bp-8h]@3
numPipes = this/*->baseclass_0*/.m_pipes;
numBanks = this/*->baseclass_0*/.m_banks;
bankOpt = (this/*->baseclass_0*/.m_configFlags/*.value*/ >> 1) & 1;
if (numBanks == 4)
{
bankBit0 = (y / (16 * numPipes) ^ (byte)(x >> 3)) & 1;
if (bankOpt == 1 && numPipes == 8)
bankBit0 ^= x / 0x20 & 1;
bank = bankBit0 | 2 * ((y / (8 * numPipes) ^ (byte)(x >> 4)) & 1);
}
else
{
if (this/*->baseclass_0*/.m_banks == 8)
{
bankBit0a = (y / (32 * numPipes) ^ (byte)(x >> 3)) & 1;
if (bankOpt == 1 && numPipes == 8)
bankBit0a ^= x / (8 * numBanks) & 1;
bank = bankBit0a | 2 * ((y / (32 * numPipes) ^ (byte)(y / (16 * numPipes) ^ (x >> 4))) & 1) | 4 * ((y / (8 * numPipes) ^ (byte)(x >> 5)) & 1);
}
else
{
bank = 0;
}
}
return bank;
}
private static int GetTileType(bool isDepth)
{
return (isDepth) ? 1 : 0;
}
private uint ComputePixelIndexWithinMicroTile(/*AddrLib *this,*/ uint x, uint y, uint z, uint bpp, /*_AddrTileMode*/int tileMode, /*_AddrTileType*/int microTileType)
{
uint v8; // [sp+4h] [bp-34h]@1
uint thickness; // [sp+8h] [bp-30h]@1
uint pixelBit8; // [sp+10h] [bp-28h]@1
uint pixelBit7; // [sp+14h] [bp-24h]@1
uint pixelBit6; // [sp+18h] [bp-20h]@1
uint pixelBit5; // [sp+1Ch] [bp-1Ch]@4
uint pixelBit4; // [sp+20h] [bp-18h]@4
uint pixelBit3; // [sp+24h] [bp-14h]@4
uint pixelBit2; // [sp+28h] [bp-10h]@4
uint pixelBit1; // [sp+2Ch] [bp-Ch]@4
uint pixelBit0; // [sp+30h] [bp-8h]@4
// AddrLib *thisa; // [sp+34h] [bp-4h]@1
// memset(&v8, -858993460, 0x34u);
//thisa = this;
pixelBit6 = 0;
pixelBit7 = 0;
pixelBit8 = 0;
thickness = ComputeSurfaceThickness(tileMode);
if (microTileType == 3)
{
pixelBit0 = x & 1;
pixelBit1 = y & 1;
pixelBit2 = z & 1;
pixelBit3 = (x & 2) >> 1;
pixelBit4 = (y & 2) >> 1;
pixelBit5 = (z & 2) >> 1;
pixelBit6 = (x & 4) >> 2;
pixelBit7 = (y & 4) >> 2;
}
else
{
if (microTileType != 0)
{
pixelBit0 = x & 1;
pixelBit1 = y & 1;
pixelBit2 = (x & 2) >> 1;
pixelBit3 = (y & 2) >> 1;
pixelBit4 = (x & 4) >> 2;
pixelBit5 = (y & 4) >> 2;
}
else
{
v8 = bpp - 8;
switch (bpp)
{
case 8u:
pixelBit0 = x & 1;
pixelBit1 = (x & 2) >> 1;
pixelBit2 = (x & 4) >> 2;
pixelBit3 = (y & 2) >> 1;
pixelBit4 = y & 1;
pixelBit5 = (y & 4) >> 2;
break;
case 0x10u:
pixelBit0 = x & 1;
pixelBit1 = (x & 2) >> 1;
pixelBit2 = (x & 4) >> 2;
pixelBit3 = y & 1;
pixelBit4 = (y & 2) >> 1;
pixelBit5 = (y & 4) >> 2;
break;
case 0x20u:
case 0x60u:
pixelBit0 = x & 1;
pixelBit1 = (x & 2) >> 1;
pixelBit2 = y & 1;
pixelBit3 = (x & 4) >> 2;
pixelBit4 = (y & 2) >> 1;
pixelBit5 = (y & 4) >> 2;
break;
case 0x40u:
pixelBit0 = x & 1;
pixelBit1 = y & 1;
pixelBit2 = (x & 2) >> 1;
pixelBit3 = (x & 4) >> 2;
pixelBit4 = (y & 2) >> 1;
pixelBit5 = (y & 4) >> 2;
break;
case 0x80u:
pixelBit0 = y & 1;
pixelBit1 = x & 1;
pixelBit2 = (x & 2) >> 1;
pixelBit3 = (x & 4) >> 2;
pixelBit4 = (y & 2) >> 1;
pixelBit5 = (y & 4) >> 2;
break;
default:
pixelBit0 = x & 1;
pixelBit1 = (x & 2) >> 1;
pixelBit2 = y & 1;
pixelBit3 = (x & 4) >> 2;
pixelBit4 = (y & 2) >> 1;
pixelBit5 = (y & 4) >> 2;
break;
}
}
if (thickness > 1)
{
pixelBit6 = z & 1;
pixelBit7 = (z & 2) >> 1;
}
}
if (thickness == 8) pixelBit8 = (z & 4) >> 2;
return (pixelBit8 << 8) | (pixelBit7 << 7) | (pixelBit6 << 6) | 32 * pixelBit5 | 16 * pixelBit4 | 8 * pixelBit3 | 4 * pixelBit2 | pixelBit0 | 2 * pixelBit1;
}
private static uint ComputeSurfaceThickness(/*_AddrTileMode*/int tileMode)
{
uint thickness; // [sp+4h] [bp-4h]@2
switch (tileMode)
{
case 3:
case 7:
case 11:
case 13:
case 15:
thickness = 4;
break;
case 16:
case 17:
thickness = 8;
break;
default:
thickness = 1;
break;
}
return thickness;
}
}
}

436
WiiU/GPU/Textures.cs Normal file
View File

@ -0,0 +1,436 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using LibEveryFileExplorer.IO;
using LibEveryFileExplorer.GFX;
namespace WiiU.GPU
{
public class Textures
{
public enum TileMode : uint
{
Default = 0,
LinearAligned = 1,
Tiled1DThin1 = 2,
Tiled1DThick = 3,
Tiled2DThin1 = 4,
Tiled2DThin2 = 5,
Tiled2DThin4 = 6,
Tiled2DThick = 7,
Tiled2BThin1 = 8,
Tiled2BThin2 = 9,
Tiled2BThin4 = 10,
Tiled2BThick = 11,
Tiled3DThin1 = 12,
Tiled3DThick = 13,
Tiled3BThin1 = 14,
Tiled3BThick = 15,
LinearSpecial = 16
}
public enum ImageFormat : uint
{
RGB565,
DXT5
//ETC1,
//ETC1A4
}
//private static readonly int[] Bpp = { 32, 24, 16, 16, 16, 16, 16, 8, 8, 8, 4, 4, 4, 8 };
private static readonly int[] TileOrder =
{
0, 1, 4, 5,
2, 3, 6, 7,
8, 9, 12, 13,
10, 11, 14, 15
};
//1. Swap column 1 and 2, 4 and 5 etc.
//2. Put back 8x8 tiles in 16x16 blocks in the order 0, 3
// 1, 2
private static readonly int[,] ETC1Modifiers =
{
{ 2, 8 },
{ 5, 17 },
{ 9, 29 },
{ 13, 42 },
{ 18, 60 },
{ 24, 80 },
{ 33, 106 },
{ 47, 183 }
};
//public static int GetBpp(ImageFormat Format) { return Bpp[(uint)Format]; }
public static Bitmap ToBitmap(byte[] Data, int Width, int Height, ImageFormat Format, TileMode TileMode, uint SwizzleMode, bool ExactSize = false)
{
return ToBitmap(Data, 0, Width, Height, Format, TileMode, SwizzleMode, ExactSize);
}
public static unsafe Bitmap ToBitmap(byte[] Data, int Offset, int Width, int Height, ImageFormat Format, TileMode TileMode, uint SwizzleMode, bool ExactSize = false)
{
if (Data == null || Data.Length < 1 || Offset < 0 || Offset >= Data.Length || Width < 1 || Height < 1) return null;
if (ExactSize && ((Width % 8) != 0 || (Height % 8) != 0)) return null;
int physicalwidth = Width;
int physicalheight = Height;
if (!ExactSize)
{
Width = 1 << (int)Math.Ceiling(Math.Log(Width, 2));
Height = 1 << (int)Math.Ceiling(Math.Log(Height, 2));
}
Bitmap bitm = new Bitmap(Width, Height);//physicalwidth, physicalheight);
BitmapData d = bitm.LockBits(new Rectangle(0, 0, bitm.Width, bitm.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
uint* res = (uint*)d.Scan0;
int offs = Offset;//0;
int stride = d.Stride / 4;
switch (Format)
{
case ImageFormat.RGB565:
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
//if (x >= physicalwidth) continue;
if (y >= physicalheight) continue;
res[y * stride + x] =
GFXUtil.ConvertColorFormat(
IOUtil.ReadU16LE(Data, offs),
ColorFormat.RGB565,
ColorFormat.ARGB8888);
offs += 2;
}
}
break;
case ImageFormat.DXT5:
for (int y2 = 0; y2 < Height; y2 += 4)
{
for (int x2 = 0; x2 < Width; x2 += 4)
{
ulong a_data = IOUtil.ReadU64LE(Data, offs);
byte[] AlphaPalette = new byte[8];
AlphaPalette[0] = (byte)(a_data & 0xFF);
AlphaPalette[1] = (byte)((a_data >> 8) & 0xFF);
a_data >>= 16;
if (AlphaPalette[0] > AlphaPalette[1])
{
AlphaPalette[2] = (byte)((6 * AlphaPalette[0] + 1 * AlphaPalette[1]) / 7);
AlphaPalette[3] = (byte)((5 * AlphaPalette[0] + 2 * AlphaPalette[1]) / 7);
AlphaPalette[4] = (byte)((4 * AlphaPalette[0] + 3 * AlphaPalette[1]) / 7);
AlphaPalette[5] = (byte)((3 * AlphaPalette[0] + 4 * AlphaPalette[1]) / 7);
AlphaPalette[6] = (byte)((2 * AlphaPalette[0] + 5 * AlphaPalette[1]) / 7);
AlphaPalette[7] = (byte)((1 * AlphaPalette[0] + 6 * AlphaPalette[1]) / 7);
}
else
{
AlphaPalette[2] = (byte)((4 * AlphaPalette[0] + 1 * AlphaPalette[1]) / 5);
AlphaPalette[3] = (byte)((3 * AlphaPalette[0] + 2 * AlphaPalette[1]) / 5);
AlphaPalette[4] = (byte)((2 * AlphaPalette[0] + 3 * AlphaPalette[1]) / 5);
AlphaPalette[5] = (byte)((1 * AlphaPalette[0] + 4 * AlphaPalette[1]) / 5);
AlphaPalette[6] = 0;
AlphaPalette[7] = 255;
}
offs += 8;
ushort color0 = IOUtil.ReadU16LE(Data, offs);
ushort color1 = IOUtil.ReadU16LE(Data, offs + 2);
uint data = IOUtil.ReadU32LE(Data, offs + 4);
uint[] Palette = new uint[4];
Palette[0] = GFXUtil.ConvertColorFormat(color0, ColorFormat.RGB565, ColorFormat.ARGB8888);
Palette[1] = GFXUtil.ConvertColorFormat(color1, ColorFormat.RGB565, ColorFormat.ARGB8888);
Color a = System.Drawing.Color.FromArgb((int)Palette[0]);
Color b = System.Drawing.Color.FromArgb((int)Palette[1]);
if (color0 > color1)//1/3 and 2/3
{
Palette[2] = GFXUtil.ToColorFormat((a.R * 2 + b.R * 1) / 3, (a.G * 2 + b.G * 1) / 3, (a.B * 2 + b.B * 1) / 3, ColorFormat.ARGB8888);
Palette[3] = GFXUtil.ToColorFormat((a.R * 1 + b.R * 2) / 3, (a.G * 1 + b.G * 2) / 3, (a.B * 1 + b.B * 2) / 3, ColorFormat.ARGB8888);
}
else//1/2 and transparent
{
Palette[2] = GFXUtil.ToColorFormat((a.R + b.R) / 2, (a.G + b.G) / 2, (a.B + b.B) / 2, ColorFormat.ARGB8888);
Palette[3] = 0;
}
int q = 30;
int aq = 45;
for (int y3 = 0; y3 < 4; y3++)
{
for (int x3 = 0; x3 < 4; x3++)
{
//if (x2 + x3 >= physicalwidth) continue;
if (y2 + y3 >= physicalheight) continue;
res[(y2 + y3) * stride + x2 + x3] = (Palette[(data >> q) & 3] & 0xFFFFFF) | ((uint)AlphaPalette[(a_data >> aq) & 7] << 24);
q -= 2;
aq -= 3;
}
}
offs += 8;
}
// }
//}
}
break;
/*case ImageFormat.ETC1://Some reference: http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt
case ImageFormat.ETC1A4:
{
for (int y = 0; y < Height; y += 8)
{
for (int x = 0; x < Width; x += 8)
{
for (int i = 0; i < 8; i += 4)
{
for (int j = 0; j < 8; j += 4)
{
ulong alpha = 0xFFFFFFFFFFFFFFFF;
ulong data = IOUtil.ReadU64BE(Data, offs);
if (Format == ImageFormat.ETC1A4)
{
offs += 8;
alpha = IOUtil.ReadU64BE(Data, offs);
}
bool diffbit = ((data >> 33) & 1) == 1;
bool flipbit = ((data >> 32) & 1) == 1; //0: |||, 1: |-|
int r1, r2, g1, g2, b1, b2;
if (diffbit) //'differential' mode
{
int r = (int)((data >> 59) & 0x1F);
int g = (int)((data >> 51) & 0x1F);
int b = (int)((data >> 43) & 0x1F);
r1 = (r << 3) | ((r & 0x1C) >> 2);
g1 = (g << 3) | ((g & 0x1C) >> 2);
b1 = (b << 3) | ((b & 0x1C) >> 2);
r += (int)((data >> 56) & 0x7) << 29 >> 29;
g += (int)((data >> 48) & 0x7) << 29 >> 29;
b += (int)((data >> 40) & 0x7) << 29 >> 29;
r2 = (r << 3) | ((r & 0x1C) >> 2);
g2 = (g << 3) | ((g & 0x1C) >> 2);
b2 = (b << 3) | ((b & 0x1C) >> 2);
}
else //'individual' mode
{
r1 = (int)((data >> 60) & 0xF) * 0x11;
g1 = (int)((data >> 52) & 0xF) * 0x11;
b1 = (int)((data >> 44) & 0xF) * 0x11;
r2 = (int)((data >> 56) & 0xF) * 0x11;
g2 = (int)((data >> 48) & 0xF) * 0x11;
b2 = (int)((data >> 40) & 0xF) * 0x11;
}
int Table1 = (int)((data >> 37) & 0x7);
int Table2 = (int)((data >> 34) & 0x7);
for (int y3 = 0; y3 < 4; y3++)
{
for (int x3 = 0; x3 < 4; x3++)
{
if (x + j + x3 >= physicalwidth) continue;
if (y + i + y3 >= physicalheight) continue;
int val = (int)((data >> (x3 * 4 + y3)) & 0x1);
bool neg = ((data >> (x3 * 4 + y3 + 16)) & 0x1) == 1;
uint c;
if ((flipbit && y3 < 2) || (!flipbit && x3 < 2))
{
int add = ETC1Modifiers[Table1, val] * (neg ? -1 : 1);
c = GFXUtil.ToColorFormat((byte)(((alpha >> ((x3 * 4 + y3) * 4)) & 0xF) * 0x11), (byte)ColorClamp(r1 + add), (byte)ColorClamp(g1 + add), (byte)ColorClamp(b1 + add), ColorFormat.ARGB8888);
}
else
{
int add = ETC1Modifiers[Table2, val] * (neg ? -1 : 1);
c = GFXUtil.ToColorFormat((byte)(((alpha >> ((x3 * 4 + y3) * 4)) & 0xF) * 0x11), (byte)ColorClamp(r2 + add), (byte)ColorClamp(g2 + add), (byte)ColorClamp(b2 + add), ColorFormat.ARGB8888);
}
res[(i + y3) * stride + x + j + x3] = c;
}
}
offs += 8;
}
}
}
res += stride * 8;
}
}
break;
* */
}
Detile(res, stride, Width, Height, physicalwidth, physicalheight, TileMode);
bitm.UnlockBits(d);
return bitm;
}
private static unsafe void Detile(uint* res, int stride, int width, int height, int physicalwidth, int physicalheight, TileMode Mode)
{
switch (Mode)
{
case Textures.TileMode.Tiled2DThin1:
DetileTiled2DThin1(res, stride, width, height, physicalwidth, physicalheight);
return;
default:
throw new Exception("Unsupported Tilemode!");
}
}
//private static readonly int[] Tiled2DThin1OrderA = { 0, 1, 3, 2 };
//private static readonly int[] Tiled2DThin1OrderB = { 0, 2, 3, 1 };
private static readonly int[] Tiled2DThin1Order = { 2, 0, 1, 3 };
private static unsafe void DetileTiled2DThin1(uint* res, int stride, int width, int height, int physicalwidth, int physicalheight)
{
uint[] Result = new uint[width * height];
int px = 0;
int py = 0;
for (int y = 0; y < height; y += 64)
{
for (int x = 0; x < width; x += 64)
{
for (int i = 0; i < 64; i++)//y2 = 0; y2 < 64; y2 += 8)
{
int tile = i;
int q = Tiled2DThin1Order[(tile / 2) % 4];
int p = tile & ~7;
int xx = (p % 16) * 2 + (q % 2) * 8;
//if ((i / 0x20) == 1)
//{
//xx += (i % 2) * 8;
//}
/*else */xx += (i % 2) * 32;
int yy = p / 16 * 16 + (q / 2) * 8;
for (int y3 = 0; y3 < 8; y3++)
{
for (int x3 = 0; x3 < 8; x3++)
{
//if (x + x2 + x3 >= physicalwidth) continue;
//if (y + y3 + yy >= physicalheight) continue;
Result[(y + y3 + yy) * width + x + x3 + xx] = ReadPixel(res, stride, width, height, ref px, ref py);
}
}
}
}
}
/*R600Tiling t = new R600Tiling();
R600Tiling._ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT r = new R600Tiling._ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT();
r.bpp = 32;
r.tileMode = 4;
r.tileType = 0;
r.pitch = (uint)stride;
r.height = (uint)height;
r.numSlices = 1;
r.numSamples = (uint)(height * width);
R600Tiling._ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT o = new R600Tiling._ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT();
int i = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
r.x = (uint)x;
r.y = (uint)y;
r.sample = (uint)i;
int pixel_number = (int)t.ComputeSurfaceAddrFromCoord(ref r, ref o);
/*int pixel_number = 0;
pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2]
pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1]
pixel_number |= ((y >> 0) & 1) << 4; // pn[4] = y[0]
pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]/
Result[y * width + x] = res[(pixel_number & 0xFFF) / 4];
i++;
}
}*/
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
//if (x >= physicalwidth) continue;
if (y >= physicalheight) continue;
res[y * stride + x] = Result[y * width + x];
}
}
/*
//Swap columns first!
for (int c = 0; c < width; c += 16)
{
//Swap c + 4 and c + 8
for (int y = 0; y < height; y++)
{
for (int x = 0; x < 4; x++)
{
if (c + x >= physicalwidth) continue;
if (y >= physicalheight) continue;
uint a = res[y * stride + c + x + 4];
uint b = res[y * stride + c + x + 8];
res[y * stride + c + x + 4] = b;
res[y * stride + c + x + 8] = a;
}
}
}
uint[] Result = new uint[width * height];
//work in 16x16 and then in 8x8 tiles
int px = 0;
int py = 0;
for (int y = 0; y < height; y += 32)
{
for (int x = 0; x < width; x += 32)
{
for (int j = 0; j < 4; j++)
{
int x4 = (Tiled2DThin1OrderA[j] % 2) * 16;
int y4 = ((Tiled2DThin1OrderA[j] & 2) >> 1) * 16;
//Read out the 256 pixels needed!
uint[] Pixels = new uint[256];
for (int i = 0; i < 256; i++) Pixels[i] = ReadPixel(res, stride, width, height, ref px, ref py);
int idx = 0;
for (int i = 0; i < 4; i++)
{
int x2 = (Tiled2DThin1OrderB[i] % 2) * 8;
int y2 = ((Tiled2DThin1OrderB[i] & 2) >> 1) * 8;
for (int y3 = 0; y3 < 8; y3++)
{
for (int x3 = 0; x3 < 8; x3++)
{
Result[(y + y2 + y3 + y4) * width + x + x2 + x3 + x4] = Pixels[idx++];
//res[(y + y2 + y3) * stride + x + x2 + x3] = Pixels[idx++];
}
}
}
}
}
}
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
if (x >= physicalwidth) continue;
if (y >= physicalheight) continue;
res[y * stride + x] = Result[y * width + x];
}
}
*/
}
private static unsafe uint ReadPixel(uint* res, int stride, int width, int height, ref int px, ref int py)
{
if (px >= width || py >= height || px < 0 || py < 0)
return 0;//throw new ArgumentException("ReadPixel fail!");
uint result = res[py * stride + px];
px++;
if (px == width)
{
px = 0;
py++;
}
return result;
}
private static int ColorClamp(int Color)
{
if (Color > 255) Color = 255;
if (Color < 0) Color = 0;
return Color;
}
}
}

View File

@ -116,7 +116,7 @@ namespace WiiU.NintendoWare.LYT2
public Byte Unknown;
//Tempoarly use 3ds stuff!
public _3DS.GPU.Textures.ImageFormat GetGPUTextureFormat()
/*public _3DS.GPU.Textures.ImageFormat GetGPUTextureFormat()
{
switch (Format)
{
@ -134,17 +134,65 @@ namespace WiiU.NintendoWare.LYT2
case 11: return _3DS.GPU.Textures.ImageFormat.ETC1A4;
case 0x12: return _3DS.GPU.Textures.ImageFormat.L4;
case 0x13: return _3DS.GPU.Textures.ImageFormat.A4;
//Wii U Formats:
case 0x17: return WiiU.GPU.Textures.ImageFormat.ETC1A4;
}
throw new Exception("Unknown Image Format!");
}
}*/
}
public UInt32 DataLength;
//Tempoarly use 3ds stuff!
public Bitmap ToBitmap()
{
if (Image.Unknown == 0) return _3DS.GPU.Textures.ToBitmap(Data, Image.Width, Image.Height, Image.GetGPUTextureFormat());
return _3DS.GPU.Textures.ToBitmap(Data, Image.Height, Image.Width, Image.GetGPUTextureFormat());
if (Header.Endianness == 0xFFFE)//3ds
{
_3DS.GPU.Textures.ImageFormat f3 = 0;
switch (Image.Format)
{
case 0: f3 = _3DS.GPU.Textures.ImageFormat.L8; break;
case 1: f3 = _3DS.GPU.Textures.ImageFormat.A8; break;
case 2: f3 = _3DS.GPU.Textures.ImageFormat.LA4; break;
case 3: f3 = _3DS.GPU.Textures.ImageFormat.LA8; break;
case 4: f3 = _3DS.GPU.Textures.ImageFormat.HILO8; break;
case 5: f3 = _3DS.GPU.Textures.ImageFormat.RGB565; break;
case 6: f3 = _3DS.GPU.Textures.ImageFormat.RGB8; break;
case 7: f3 = _3DS.GPU.Textures.ImageFormat.RGBA5551; break;
case 8: f3 = _3DS.GPU.Textures.ImageFormat.RGBA4; break;
case 9: f3 = _3DS.GPU.Textures.ImageFormat.RGBA8; break;
case 10: f3 = _3DS.GPU.Textures.ImageFormat.ETC1; break;
case 11: f3 = _3DS.GPU.Textures.ImageFormat.ETC1A4; break;
case 0x12: f3 = _3DS.GPU.Textures.ImageFormat.L4; break;
case 0x13: f3 = _3DS.GPU.Textures.ImageFormat.A4; break;
default: throw new Exception("Unknown Image Format!");
}
if (Image.Unknown == 0) return _3DS.GPU.Textures.ToBitmap(Data, Image.Width, Image.Height, f3);
return _3DS.GPU.Textures.ToBitmap(Data, Image.Height, Image.Width, f3);
}
else
{
GPU.Textures.ImageFormat fu = 0;
switch (Image.Format)
{
//case 0: f3 = _3DS.GPU.Textures.ImageFormat.L8; break;
//case 1: f3 = _3DS.GPU.Textures.ImageFormat.A8; break;
//case 2: f3 = _3DS.GPU.Textures.ImageFormat.LA4; break;
//case 3: f3 = _3DS.GPU.Textures.ImageFormat.LA8; break;
//case 4: f3 = _3DS.GPU.Textures.ImageFormat.HILO8; break;
case 5: fu = GPU.Textures.ImageFormat.RGB565; break;
//case 6: f3 = _3DS.GPU.Textures.ImageFormat.RGB8; break;
//case 7: f3 = _3DS.GPU.Textures.ImageFormat.RGBA5551; break;
//case 8: f3 = _3DS.GPU.Textures.ImageFormat.RGBA4; break;
//case 9: f3 = _3DS.GPU.Textures.ImageFormat.RGBA8; break;
//case 10: f3 = _3DS.GPU.Textures.ImageFormat.ETC1; break;
//case 11: f3 = _3DS.GPU.Textures.ImageFormat.ETC1A4; break;
//case 0x12: f3 = _3DS.GPU.Textures.ImageFormat.L4; break;
//case 0x13: f3 = _3DS.GPU.Textures.ImageFormat.A4; break;
case 0x17: fu = GPU.Textures.ImageFormat.DXT5; break;
default: throw new Exception("Unknown Image Format!");
}
return GPU.Textures.ToBitmap(Data, Image.Width, Image.Height, fu, (GPU.Textures.TileMode)(Image.Unknown & 0x1F), (uint)Image.Unknown >> 5);
}
}
public class FLIMIdentifier : FileFormatIdentifier

View File

@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -42,6 +43,8 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="GPU\R600Tiling.cs" />
<Compile Include="GPU\Textures.cs" />
<Compile Include="NintendoWare\LYT2\FLIM.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resource.Designer.cs">