diff --git a/3DS/NintendoWare/GFX/CGFX.cs b/3DS/NintendoWare/GFX/CGFX.cs
index 905c24e..eb74e85 100644
--- a/3DS/NintendoWare/GFX/CGFX.cs
+++ b/3DS/NintendoWare/GFX/CGFX.cs
@@ -43,11 +43,12 @@ namespace _3DS.NintendoWare.GFX
public string GetSaveDefaultFileFilter()
{
- return "CTR Graphics Resource (*.bcres)|*.bcres";
+ return "CTR Graphics Resource (*.bcres;*.bcmdl)|*.bcres;*.bcmdl";
}
public byte[] Write()
{
+ //MessageBox.Show("CGFX saving is experimental! A couple of sections (like animations) are lost while saving!");
MemoryStream m = new MemoryStream();
EndianBinaryWriter er = new EndianBinaryWriter(m, Endianness.LittleEndian);
Header.NrBlocks = 1;
@@ -224,9 +225,9 @@ namespace _3DS.NintendoWare.GFX
er.Write((uint)0);
for (int i = 0; i < 16; i++)
{
- if (Dictionaries[i] != null)
+ if (Dictionaries[i] != null && (i == 0 || i == 1))
{
- if (i != 0 && i != 1) throw new NotImplementedException();
+ //if (i != 0 && i != 1) throw new NotImplementedException();
er.Write((uint)Dictionaries[i].Count);
er.Write((uint)0);//dictoffset
}
@@ -239,7 +240,7 @@ namespace _3DS.NintendoWare.GFX
long[] dictoffsets = new long[16];
for (int i = 0; i < 16; i++)
{
- if (Dictionaries[i] != null)
+ if (Dictionaries[i] != null && (i == 0 || i == 1))
{
dictoffsets[i] = er.BaseStream.Position;
er.BaseStream.Position = basepos + 8 + i * 8 + 4;
diff --git a/3DS/NintendoWare/GFX/CMDL.cs b/3DS/NintendoWare/GFX/CMDL.cs
index 05f5c16..ca0302d 100644
--- a/3DS/NintendoWare/GFX/CMDL.cs
+++ b/3DS/NintendoWare/GFX/CMDL.cs
@@ -44,8 +44,8 @@ namespace _3DS.NintendoWare.GFX
NrChildren = er.ReadUInt32();
Unknown7 = er.ReadUInt32();
NrAnimationGroupDescriptions = er.ReadUInt32();
- AnimationGroupDescriptionsDictOffset =er.ReadUInt32();
- if (AnimationGroupDescriptionsDictOffset != 0) AnimationGroupDescriptionsDictOffset += (UInt32)er.BaseStream.Position - 4;
+ AnimationGroupDescriptionsDictOffset = er.ReadUInt32();
+ if (AnimationGroupDescriptionsDictOffset != 0) AnimationGroupDescriptionsDictOffset += (UInt32)er.BaseStream.Position - 4;
Scale = er.ReadVector3();
Rotation = er.ReadVector3();
Translation = er.ReadVector3();
@@ -3857,6 +3857,228 @@ namespace _3DS.NintendoWare.GFX
return o;
}
+ public String ToMayaASCII(CGFX Resource)
+ {
+ var er = new CommonFiles.Maya.MayaASCIIWriter();
+ if (Resource.Data.Textures != null)
+ {
+ foreach (var tex in Resource.Data.Textures)
+ {
+ er.CreateNode("file", tex.Name.Replace('.', '_') + "_tex");
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("\".ftn\"");
+ er.WriteArgument("-type", "\"string\"");
+ er.WriteArgument("\"Tex/" + tex.Name + ".png\"");
+ }
+ er.EndStatement();
+ er.CreateNode("place2dTexture", tex.Name.Replace('.', '_') + "_tex_p2d");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.c", tex.Name.Replace('.', '_') + "_tex.c");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.tf", tex.Name.Replace('.', '_') + "_tex.tf");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.rf", tex.Name.Replace('.', '_') + "_tex.rf");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.mu", tex.Name.Replace('.', '_') + "_tex.mu");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.mv", tex.Name.Replace('.', '_') + "_tex.mv");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.s", tex.Name.Replace('.', '_') + "_tex.s");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.wu", tex.Name.Replace('.', '_') + "_tex.wu");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.wv", tex.Name.Replace('.', '_') + "_tex.wv");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.re", tex.Name.Replace('.', '_') + "_tex.re");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.of", tex.Name.Replace('.', '_') + "_tex.of");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.r", tex.Name.Replace('.', '_') + "_tex.ro");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.n", tex.Name.Replace('.', '_') + "_tex.n");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.vt1", tex.Name.Replace('.', '_') + "_tex.vt1");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.vt2", tex.Name.Replace('.', '_') + "_tex.vt2");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.vt3", tex.Name.Replace('.', '_') + "_tex.vt3");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.vc1", tex.Name.Replace('.', '_') + "_tex.vc1");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.o", tex.Name.Replace('.', '_') + "_tex.uv");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex_p2d.ofs", tex.Name.Replace('.', '_') + "_tex.fs");
+ er.ConnectAttribute(tex.Name.Replace('.', '_') + "_tex.msg", ":defaultTextureList1.tx", true);
+ }
+ }
+ foreach (var mat in Materials)
+ {
+ er.CreateNode("phong", mat.Name.Replace('.', '_'));
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("\".dc\"", 1);
+ }
+ er.EndStatement();
+ er.CreateNode("shadingEngine", mat.Name.Replace('.', '_') + "_Sg");
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("\".ihi\"", 0);
+ }
+ er.EndStatement();
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("\".ro\"", "yes");
+ }
+ er.EndStatement();
+ er.CreateNode("materialInfo", mat.Name.Replace('.', '_') + "_In");
+ er.ConnectAttribute(mat.Name.Replace('.', '_') + ".oc", mat.Name.Replace('.', '_') + "_Sg.ss");
+ er.ConnectAttribute(mat.Name.Replace('.', '_') + "_Sg.msg", mat.Name.Replace('.', '_') + "_In.sg");
+ er.ConnectAttribute(mat.Name.Replace('.', '_') + ".msg", mat.Name.Replace('.', '_') + "_In.m");
+ er.ConnectAttribute(mat.Name.Replace('.', '_') + "_Sg.pa", ":renderPartition.st", true);
+ er.ConnectAttribute(mat.Name.Replace('.', '_') + ".msg", ":defaultShaderList1.s", true);
+ if (mat.Tex0 != null && mat.Tex0.TextureObject is ReferenceTexture)
+ {
+ er.ConnectAttribute(((ReferenceTexture)mat.Tex0.TextureObject).LinkedTextureName.Replace('.', '_') + "_tex.oc", mat.Name.Replace('.', '_') + ".c");
+ er.ConnectAttribute(((ReferenceTexture)mat.Tex0.TextureObject).LinkedTextureName.Replace('.', '_') + "_tex.msg", mat.Name.Replace('.', '_') + "_In.t", true);
+ }
+ }
+ int s = 0;
+ foreach (var vv in Shapes)
+ {
+ var mat = Materials[Meshes[s].MaterialIndex];
+ er.CreateNode("transform", "S" + s + "_trans");
+ er.CreateNode("mesh", "S" + s + "_mesh", "S" + s + "_trans");
+ Polygon p = vv.GetVertexData(this);
+ int cnt = 0;
+ foreach (var q in vv.PrimitiveSets[0].Primitives[0].IndexStreams)
+ {
+ Vector3[] defs = q.GetFaceData();
+ cnt += defs.Length;
+ }
+ if (p.TexCoords != null)
+ {
+ if (mat.NrActiveTextureCoordiators > 0 && mat.TextureCoordiators[0].MappingMethod == 0)
+ {
+ Vector2[] texc;
+ if (mat.TextureCoordiators[0].SourceCoordinate == 0)
+ {
+ texc = p.TexCoords;
+ }
+ else if (mat.TextureCoordiators[0].SourceCoordinate == 1)
+ {
+ texc = p.TexCoords2;
+ }
+ else
+ {
+ texc = p.TexCoords3;
+ }
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("\".uvst[0].uvsn\"");
+ er.WriteArgument("-type", "\"string\"");
+ er.WriteArgument("\"map1\"");
+ }
+ er.EndStatement();
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("-s", texc.Length);
+ er.WriteArgument("\".uvst[0].uvsp[0:" + (texc.Length - 1) + "]\"");
+ er.WriteArgument("-type", "\"float2\"");
+ foreach (var v in texc)
+ {
+ er.WriteArgument(v.X);
+ er.WriteArgument(v.Y);
+ }
+ }
+ er.EndStatement();
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("\".cuvs\"");
+ er.WriteArgument("-type", "\"string\"");
+ er.WriteArgument("\"map1\"");
+ }
+ er.EndStatement();
+ }
+ }
+ if (p.Vertex != null)
+ {
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("-s", p.Vertex.Length);
+ er.WriteArgument("\".vt[0:" + (p.Vertex.Length - 1) + "]\"");
+ foreach (var v in p.Vertex)
+ {
+ er.WriteArgument(v.X);
+ er.WriteArgument(v.Y);
+ er.WriteArgument(v.Z);
+ }
+ }
+ er.EndStatement();
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("-s", cnt * 3);
+ er.WriteArgument("\".ed[0:" + ((cnt * 3) - 1) + "]\"");
+ int idx = 0;
+ foreach (var q in vv.PrimitiveSets[0].Primitives[0].IndexStreams)
+ {
+ Vector3[] defs = q.GetFaceData();
+ foreach (Vector3 def in defs)
+ {
+ er.WriteArgument(def.X);
+ er.WriteArgument(def.Y);
+ er.WriteArgument(0);
+
+ er.WriteArgument(def.Y);
+ er.WriteArgument(def.Z);
+ er.WriteArgument(0);
+
+ er.WriteArgument(def.X);
+ er.WriteArgument(def.Z);
+ er.WriteArgument(0);
+ }
+ }
+ }
+ er.EndStatement();
+ }
+ if (p.Colors != null)
+ {
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("-s", p.Colors.Length);
+ er.WriteArgument("\".clr[0:" + (p.Colors.Length - 1) + "]\"");
+ foreach (var v in p.Colors)
+ {
+ er.WriteArgument(v.R / 255f);
+ er.WriteArgument(v.G / 255f);
+ er.WriteArgument(v.B / 255f);
+ er.WriteArgument(1);//v.A / 255f);
+ }
+ }
+ er.EndStatement();
+ }
+ er.BeginStatement("setAttr");
+ {
+ er.WriteArgument("-s", cnt);
+ er.WriteArgument("\".fc[0:" + (cnt - 1) + "]\"");
+ er.WriteArgument("-type", "\"polyFaces\"");
+ int idx = 0;
+ foreach (var q in vv.PrimitiveSets[0].Primitives[0].IndexStreams)
+ {
+ Vector3[] defs = q.GetFaceData();
+ foreach (Vector3 def in defs)
+ {
+ er.WriteArgument("\nf", 3);
+ er.WriteArgument(idx++);
+ er.WriteArgument(idx++);
+ er.WriteArgument(idx++);
+
+ er.WriteArgument("\nmu", 0);
+ er.WriteArgument(3);
+ er.WriteArgument(def.X);
+ er.WriteArgument(def.Y);
+ er.WriteArgument(def.Z);
+
+ if (p.Colors != null)
+ {
+ er.WriteArgument("\nfc");
+ er.WriteArgument(3);
+ er.WriteArgument(def.X);
+ er.WriteArgument(def.Y);
+ er.WriteArgument(def.Z);
+ }
+ }
+ }
+ }
+ er.EndStatement();
+ er.ConnectAttribute("S" + s + "_mesh.iog", Materials[Meshes[s].MaterialIndex].Name.Replace('.', '_') + "_Sg.dsm", true);
+ s++;
+ }
+ return er.Close();
+ }
+
public override string ToString()
{
return Name;
diff --git a/3DS/UI/CMDLViewer.Designer.cs b/3DS/UI/CMDLViewer.Designer.cs
index b8c84f8..9969dda 100644
--- a/3DS/UI/CMDLViewer.Designer.cs
+++ b/3DS/UI/CMDLViewer.Designer.cs
@@ -76,7 +76,8 @@
//
// saveFileDialog1
//
- this.saveFileDialog1.Filter = "COLLADA DAE File (*.dae)|*.dae|Wavefront OBJ File (*.obj)|*.obj";
+ this.saveFileDialog1.Filter = "COLLADA DAE File (*.dae)|*.dae|Wavefront OBJ File (*.obj)|*.obj|Maya ASCII (*.ma)" +
+ "|*.ma";
//
// CMDLViewer
//
diff --git a/3DS/UI/CMDLViewer.cs b/3DS/UI/CMDLViewer.cs
index 7260764..bef42d6 100644
--- a/3DS/UI/CMDLViewer.cs
+++ b/3DS/UI/CMDLViewer.cs
@@ -457,6 +457,19 @@ namespace _3DS.UI
}
break;
}
+ case 2:
+ {
+ String result = Model.ToMayaASCII(Resource);
+ File.Create(saveFileDialog1.FileName).Close();
+ File.WriteAllBytes(saveFileDialog1.FileName, Encoding.ASCII.GetBytes(result));
+ Directory.CreateDirectory(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex");
+ foreach (var v in Resource.Data.Textures)
+ {
+ if (!(v is ImageTextureCtr)) continue;
+ ((ImageTextureCtr)v).GetBitmap().Save(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex\\" + v.Name + ".png");
+ }
+ break;
+ }
}
}
}
diff --git a/3DS/UI/CMDLViewer.resx b/3DS/UI/CMDLViewer.resx
index 5f52d69..e953495 100644
--- a/3DS/UI/CMDLViewer.resx
+++ b/3DS/UI/CMDLViewer.resx
@@ -124,17 +124,17 @@
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
- YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAI3SURBVDhPYxi6gLmM2R3KxALqGTiYS5hdmEuZO5lKmFYD
- 8R6mUqa96BiqGg0UM8gzFzLPVOtROh+xNeh11uHkHyUnc/6Xnsr9X3U+/3/zjZL/HXfL/zMVMO2D6kAC
- WQzyXCUc6z2Xuj7N2JvyP3FbIhgnbY//n3c49X/Nxbz/DVcL/zffLPnPlIfugnigszOZZznNt38atznm
- f9T6qP+R6yKAdAhQc9L/irPZcFx6JuMnUybTOqhOCGBOZnaVrZG5GL4m9H/Q8qD/3gu8gLTX/+wDCUAD
- kpFwyv/YrUFvGVMYe6BaIYAxnrHXborNW58FPv8dpjr895jr/D95R8z/lJ2oGGSIWqPyJeYEZleoVghg
- jGbc4DTD8af1BOv/Vv3mYKej4/gtEf+9l67/LVuRvUemsJATqhUCmEKZDtlOsvmvXqP232+x9/+Apb5w
- HLjMF2yA6yy75wY9Bz6YT7552XzS3RioVghgCmA6ql6j/t95hiPYAP8lPmCNVhNm/TPq3P5Hu2nzN/X6
- rW90Ws5cnv70/3+99ktndFrPQw2xZ+BhdGY8joFdGI/JFiz9MOnx//9ZV///j72IwMU3/v9Xrjx8BmKA
- OUMRowVjB4MsgxREAAGE/DtmimdtPYOMLY7+/w+iJXK2QV2gz7CbgZ/BEcjSAmJVIJYHYgkgFgJiHiBm
- B2ImIGbgiVl+BoR541aihAHIZpAGUSAWBmIBIAZpBIU0GxCzADEjEDOwBc6ZyRowG6qZgQEAZbYdbqlW
- taMAAAAASUVORK5CYII=
+ YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAI3SURBVDhPYxi6gLmM2R3KxALqGTiYS5hdmEuZOxlLGFcD
+ 8R7GUsa96BiqGg0UM8gzFzLPVOtROh++Neh15uGkHyUnc/6Xnsr9X3U+/3/zjZL/HXfL/zPmM+6D6kAC
+ WQzyXCXs6z2XuD7N2JvyP3FbIhgnbY//n3c49X/Nxbz/DVcL/zffLPnPmIfugnigszOYZznOt38atznm
+ f9T6qP+R6yKAdAhQc9L/irPZcFxyOuMnYybjOqhOCGBOZnaVrZG5GL4m9H/Q8qD/3gu8gLTX/+wDCUAD
+ kpFwyv+YLYFvGVMYe6BaIYAxnrHXborNW58FPv8dpjr895jr/D95R8z/lJ2oGGSIaoPyJeYEZleoVghg
+ jGbc4Djd4af1BOv/Vv3mYKej4/gtEf+9l6z7LVOevUemsJATqhUCmEKZDtlOsvmvXqP232+x9/+Apb5w
+ HLjMF2yA6yzb5/o9Bz6YT7552XzS3RioVghgCmA6ql6j/t95hiPYAP8lPmCNVv0z/xl2bP+j1bj5m1r9
+ 1jfazWcuT3/6/79e+6UzOq3noYbYM/AwOjEex8AujMdk8pd8mPT4//+sq///x15E4OIb//8rVx4+AzHA
+ nKGI0YKxg0GWQQoigABCfh0zxbK2nkHGFkf//wfREjnboC7QY9jNwM/gCGRpAbEqEMsDsQQQCwExDxCz
+ AzETEDPwxCw/A8K8cStRwgBkM0iDKBALA7EAEIM0gkKaDYhZgJgRiBnYAufMZA2YDdXMwAAA4o0dKpJu
+ g5EAAAAASUVORK5CYII=
diff --git a/3DS/UI/TXOBViewer.Designer.cs b/3DS/UI/TXOBViewer.Designer.cs
index e7f1494..c511f1f 100644
--- a/3DS/UI/TXOBViewer.Designer.cs
+++ b/3DS/UI/TXOBViewer.Designer.cs
@@ -28,96 +28,103 @@
///
private void InitializeComponent()
{
- System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TXOBViewer));
- this.toolStrip1 = new System.Windows.Forms.ToolStrip();
- this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
- this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
- this.toolStripComboBox1 = new System.Windows.Forms.ToolStripComboBox();
- this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel();
- this.pictureBox1 = new System.Windows.Forms.PictureBox();
- this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
- this.toolStrip1.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
- this.SuspendLayout();
- //
- // toolStrip1
- //
- this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TXOBViewer));
+ this.toolStrip1 = new System.Windows.Forms.ToolStrip();
+ this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
+ this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
+ this.toolStripComboBox1 = new System.Windows.Forms.ToolStripComboBox();
+ this.toolStripLabel1 = new System.Windows.Forms.ToolStripLabel();
+ this.pictureBox1 = new System.Windows.Forms.PictureBox();
+ this.saveFileDialog1 = new System.Windows.Forms.SaveFileDialog();
+ this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
+ this.toolStrip1.SuspendLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
+ this.SuspendLayout();
+ //
+ // toolStrip1
+ //
+ this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripButton1,
this.toolStripButton2,
this.toolStripComboBox1,
this.toolStripLabel1});
- this.toolStrip1.Location = new System.Drawing.Point(0, 0);
- this.toolStrip1.Name = "toolStrip1";
- this.toolStrip1.Size = new System.Drawing.Size(464, 25);
- this.toolStrip1.TabIndex = 0;
- this.toolStrip1.Text = "toolStrip1";
- //
- // toolStripButton1
- //
- this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
- this.toolStripButton1.Enabled = false;
- this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
- this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
- this.toolStripButton1.Name = "toolStripButton1";
- this.toolStripButton1.Size = new System.Drawing.Size(23, 22);
- this.toolStripButton1.Text = "Import";
- //
- // toolStripButton2
- //
- this.toolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
- this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
- this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
- this.toolStripButton2.Name = "toolStripButton2";
- this.toolStripButton2.Size = new System.Drawing.Size(23, 22);
- this.toolStripButton2.Text = "Export";
- this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
- //
- // toolStripComboBox1
- //
- this.toolStripComboBox1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
- this.toolStripComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
- this.toolStripComboBox1.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
- this.toolStripComboBox1.Name = "toolStripComboBox1";
- this.toolStripComboBox1.Size = new System.Drawing.Size(121, 25);
- this.toolStripComboBox1.SelectedIndexChanged += new System.EventHandler(this.toolStripComboBox1_SelectedIndexChanged);
- //
- // toolStripLabel1
- //
- this.toolStripLabel1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
- this.toolStripLabel1.Name = "toolStripLabel1";
- this.toolStripLabel1.Size = new System.Drawing.Size(40, 22);
- this.toolStripLabel1.Text = "Level: ";
- //
- // pictureBox1
- //
- this.pictureBox1.BackgroundImage = global::_3DS.Resource.preview_background;
- this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
- this.pictureBox1.Location = new System.Drawing.Point(0, 25);
- this.pictureBox1.Name = "pictureBox1";
- this.pictureBox1.Size = new System.Drawing.Size(464, 308);
- this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
- this.pictureBox1.TabIndex = 1;
- this.pictureBox1.TabStop = false;
- //
- // saveFileDialog1
- //
- this.saveFileDialog1.Filter = "PNG Images (*.png)|*.png";
- //
- // TXOBViewer
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.Controls.Add(this.pictureBox1);
- this.Controls.Add(this.toolStrip1);
- this.Name = "TXOBViewer";
- this.Size = new System.Drawing.Size(464, 333);
- this.Load += new System.EventHandler(this.TXOBViewer_Load);
- this.toolStrip1.ResumeLayout(false);
- this.toolStrip1.PerformLayout();
- ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
- this.ResumeLayout(false);
- this.PerformLayout();
+ this.toolStrip1.Location = new System.Drawing.Point(0, 0);
+ this.toolStrip1.Name = "toolStrip1";
+ this.toolStrip1.Size = new System.Drawing.Size(464, 25);
+ this.toolStrip1.TabIndex = 0;
+ this.toolStrip1.Text = "toolStrip1";
+ //
+ // toolStripButton1
+ //
+ this.toolStripButton1.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
+ this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.toolStripButton1.Name = "toolStripButton1";
+ this.toolStripButton1.Size = new System.Drawing.Size(23, 22);
+ this.toolStripButton1.Text = "Import";
+ this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click);
+ //
+ // toolStripButton2
+ //
+ this.toolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
+ this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.toolStripButton2.Name = "toolStripButton2";
+ this.toolStripButton2.Size = new System.Drawing.Size(23, 22);
+ this.toolStripButton2.Text = "Export";
+ this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
+ //
+ // toolStripComboBox1
+ //
+ this.toolStripComboBox1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
+ this.toolStripComboBox1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.toolStripComboBox1.FlatStyle = System.Windows.Forms.FlatStyle.Standard;
+ this.toolStripComboBox1.Name = "toolStripComboBox1";
+ this.toolStripComboBox1.Size = new System.Drawing.Size(121, 25);
+ this.toolStripComboBox1.SelectedIndexChanged += new System.EventHandler(this.toolStripComboBox1_SelectedIndexChanged);
+ //
+ // toolStripLabel1
+ //
+ this.toolStripLabel1.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
+ this.toolStripLabel1.Name = "toolStripLabel1";
+ this.toolStripLabel1.Size = new System.Drawing.Size(40, 22);
+ this.toolStripLabel1.Text = "Level: ";
+ //
+ // pictureBox1
+ //
+ this.pictureBox1.BackgroundImage = global::_3DS.Resource.preview_background;
+ this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.pictureBox1.Location = new System.Drawing.Point(0, 25);
+ this.pictureBox1.Name = "pictureBox1";
+ this.pictureBox1.Size = new System.Drawing.Size(464, 308);
+ this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
+ this.pictureBox1.TabIndex = 1;
+ this.pictureBox1.TabStop = false;
+ //
+ // saveFileDialog1
+ //
+ this.saveFileDialog1.Filter = "PNG Images (*.png)|*.png";
+ //
+ // openFileDialog1
+ //
+ this.openFileDialog1.DefaultExt = "png";
+ this.openFileDialog1.FileName = "openFileDialog1";
+ this.openFileDialog1.Filter = "PNG Images (*.png)|*.png";
+ //
+ // TXOBViewer
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.pictureBox1);
+ this.Controls.Add(this.toolStrip1);
+ this.Name = "TXOBViewer";
+ this.Size = new System.Drawing.Size(464, 333);
+ this.Load += new System.EventHandler(this.TXOBViewer_Load);
+ this.toolStrip1.ResumeLayout(false);
+ this.toolStrip1.PerformLayout();
+ ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
+ this.ResumeLayout(false);
+ this.PerformLayout();
}
@@ -130,5 +137,6 @@
private System.Windows.Forms.ToolStripComboBox toolStripComboBox1;
private System.Windows.Forms.ToolStripLabel toolStripLabel1;
private System.Windows.Forms.SaveFileDialog saveFileDialog1;
+ private System.Windows.Forms.OpenFileDialog openFileDialog1;
}
}
\ No newline at end of file
diff --git a/3DS/UI/TXOBViewer.cs b/3DS/UI/TXOBViewer.cs
index de4dec0..2bd68ed 100644
--- a/3DS/UI/TXOBViewer.cs
+++ b/3DS/UI/TXOBViewer.cs
@@ -8,6 +8,8 @@ using System.Text;
using System.Windows.Forms;
using _3DS.NintendoWare.GFX;
using System.Drawing.Imaging;
+using System.IO;
+using _3DS.GPU;
namespace _3DS.UI
{
@@ -43,5 +45,46 @@ namespace _3DS.UI
pictureBox1.Image.Save(saveFileDialog1.FileName, ImageFormat.Png);
}
}
+
+ private void toolStripButton1_Click(object sender, EventArgs e)
+ {
+ if (Texture.HWFormat != Textures.ImageFormat.RGBA8 &&
+ Texture.HWFormat != Textures.ImageFormat.RGB8 &&
+ Texture.HWFormat != Textures.ImageFormat.RGB565 &&
+ Texture.HWFormat != Textures.ImageFormat.ETC1 &&
+ Texture.HWFormat != Textures.ImageFormat.ETC1A4)
+ {
+ MessageBox.Show("This texture format is currently not supported for importing.");
+ return;
+ }
+ if (openFileDialog1.ShowDialog() == DialogResult.OK
+ && openFileDialog1.FileName.Length > 0)
+ {
+ Bitmap b = new Bitmap(new MemoryStream(File.ReadAllBytes(openFileDialog1.FileName)));
+ if (b.Width != Texture.Width && b.Height != Texture.Height)
+ {
+ MessageBox.Show("Make sure the texture is even big as the original texture! (" + Texture.Width + "x" + Texture.Height + ")");
+ return;
+ }
+ for (int i = 0; i < Texture.NrLevels; i++)
+ {
+ int l = i;
+ uint w = Texture.Width;
+ uint h = Texture.Height;
+ int bpp = Textures.GetBpp(Texture.HWFormat);
+ int offset = 0;
+ while (l > 0)
+ {
+ offset += (int)(w * h * bpp / 8);
+ w /= 2;
+ h /= 2;
+ l--;
+ }
+ byte[] result = Textures.FromBitmap(new Bitmap(b, (int)w, (int)h), Texture.HWFormat);
+ Array.Copy(result, 0, Texture.TextureImage.Data, offset, result.Length);
+ }
+ pictureBox1.Image = Texture.GetBitmap(toolStripComboBox1.SelectedIndex);
+ }
+ }
}
}
diff --git a/3DS/UI/TXOBViewer.resx b/3DS/UI/TXOBViewer.resx
index 5114548..9313f92 100644
--- a/3DS/UI/TXOBViewer.resx
+++ b/3DS/UI/TXOBViewer.resx
@@ -153,4 +153,7 @@
122, 17
+
+ 258, 17
+
\ No newline at end of file
diff --git a/CommonFiles/CommonFiles.csproj b/CommonFiles/CommonFiles.csproj
index f4f74ee..2c8ba7c 100644
--- a/CommonFiles/CommonFiles.csproj
+++ b/CommonFiles/CommonFiles.csproj
@@ -46,6 +46,7 @@
+
diff --git a/CommonFiles/Maya/MayaASCIIWriter.cs b/CommonFiles/Maya/MayaASCIIWriter.cs
new file mode 100644
index 0000000..e76eb7f
--- /dev/null
+++ b/CommonFiles/Maya/MayaASCIIWriter.cs
@@ -0,0 +1,135 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+
+namespace CommonFiles.Maya
+{
+ public class MayaASCIIWriter
+ {
+ private StringWriter mWriter;
+
+ public MayaASCIIWriter()
+ {
+ mWriter = new StringWriter();
+ WriteComment("Maya ASCII 3.0 scene");
+ WriteComment("Created by Every File Explorer");
+ mWriter.WriteLine();
+ BeginStatement("requires");
+ {
+ WriteArgument("maya", "\"3.0\"");
+ }
+ EndStatement();
+ BeginStatement("currentUnit");
+ {
+ WriteArgument("-l", "centimeter");
+ WriteArgument("-a", "degree");
+ WriteArgument("-t", "film");
+ }
+ EndStatement();
+ }
+
+ public void WriteComment(String comment)
+ {
+ mWriter.WriteLine("//" + comment);
+ }
+
+ public void BeginStatement(String keyword)
+ {
+ mWriter.Write(keyword);
+ }
+
+ public void WriteArgument(int val)
+ {
+ WriteArgument(val.ToString());
+ }
+
+ public void WriteArgument(float val)
+ {
+ WriteArgument(val.ToString().Replace(",", "."));
+ }
+
+ public void WriteArgument(String arg)
+ {
+ mWriter.Write(" " + arg);
+ }
+
+ public void WriteArgument(String arg, int val)
+ {
+ WriteArgument(arg, val.ToString());
+ }
+
+ public void WriteArgument(String arg, float val)
+ {
+ WriteArgument(arg, val.ToString().Replace(",", "."));
+ }
+
+ public void WriteArgument(String arg, String val)
+ {
+ mWriter.Write(" " + arg + " " + val);
+ }
+
+ public void EndStatement()
+ {
+ mWriter.WriteLine(";");
+ }
+
+ public void CreateNode(String Type, String Name)
+ {
+ CreateNode(Type, Name, null, false, false);
+ }
+
+ public void CreateNode(String Type, String Name, bool Shared)
+ {
+ CreateNode(Type, Name, null, Shared, false);
+ }
+
+ public void CreateNode(String Type, String Name, String Parent)
+ {
+ CreateNode(Type, Name, Parent, false, false);
+ }
+
+ public void CreateNode(String Type, String Name, String Parent, bool Shared)
+ {
+ CreateNode(Type, Name, Parent, Shared, false);
+ }
+
+ public void CreateNode(String Type, String Name, String Parent, bool Shared, bool SkipSelect)
+ {
+ BeginStatement("createNode");
+ {
+ WriteArgument(Type);
+ WriteArgument("-n", "\"" + Name + "\"");
+ if (Parent != null) WriteArgument("-p", "\"" + Parent + "\"");
+ if (Shared) WriteArgument("-s");
+ if (SkipSelect) WriteArgument("-ss");
+ }
+ EndStatement();
+ }
+
+ public void ConnectAttribute(String FirstNode, String SecondNode)
+ {
+ ConnectAttribute(FirstNode, SecondNode, false);
+ }
+
+ public void ConnectAttribute(String FirstNode, String SecondNode, bool NextAvailable)
+ {
+ BeginStatement("connectAttr");
+ {
+ WriteArgument("\"" + FirstNode + "\"");
+ WriteArgument("\"" + SecondNode + "\"");
+ if (NextAvailable) WriteArgument("-na");
+ }
+ EndStatement();
+ }
+
+ public String Close()
+ {
+ mWriter.Flush();
+ String result = mWriter.ToString();
+ mWriter.Close();
+ return result;
+ }
+ }
+}
diff --git a/LibEveryFileExplorer/Collections/Matrix33.cs b/LibEveryFileExplorer/Collections/Matrix33.cs
index cc16d63..72c60d3 100644
--- a/LibEveryFileExplorer/Collections/Matrix33.cs
+++ b/LibEveryFileExplorer/Collections/Matrix33.cs
@@ -100,7 +100,7 @@ namespace LibEveryFileExplorer.Collections
Matrix33 result = Matrix33.Identity;
result[0, 0] = Scale.X;
result[1, 1] = Scale.Y;
- result[2, 2] = Scale.X;
+ result[2, 2] = Scale.Z;
return result;
}
diff --git a/LibEveryFileExplorer/Collections/Matrix44.cs b/LibEveryFileExplorer/Collections/Matrix44.cs
index 6f0a5f0..2ac0da8 100644
--- a/LibEveryFileExplorer/Collections/Matrix44.cs
+++ b/LibEveryFileExplorer/Collections/Matrix44.cs
@@ -194,7 +194,7 @@ namespace LibEveryFileExplorer.Collections
Matrix44 result = Matrix44.Identity;
result[0, 0] = Scale.X;
result[1, 1] = Scale.Y;
- result[2, 2] = Scale.X;
+ result[2, 2] = Scale.Z;
return result;
}
diff --git a/MarioKart/MK7/KMP/CDMD.cs b/MarioKart/MK7/KMP/CDMD.cs
index f25c990..eba3df9 100644
--- a/MarioKart/MK7/KMP/CDMD.cs
+++ b/MarioKart/MK7/KMP/CDMD.cs
@@ -233,7 +233,7 @@ namespace MarioKart.MK7.KMP
{
Point1 = v.Point1,
Point2 = v.Point2,
- KeyPointID = v.Type,
+ KeyPointID = (short)(v.Type == 255?-1:v.Type),
RespawnID = v.RespawnId,
};
diff --git a/MarioKart/MKDS/KCL.cs b/MarioKart/MKDS/KCL.cs
index 2ce6b1a..cae1851 100644
--- a/MarioKart/MKDS/KCL.cs
+++ b/MarioKart/MKDS/KCL.cs
@@ -191,6 +191,7 @@ namespace MarioKart.MKDS
this.Normals = Normals.ToArray();
Planes = planes.ToArray();
Header = new MKDSKCLHeader();
+ //Octree = KCLOctree.FromTriangles(Triangles.ToArray(), Header, 2048, 128, 32, 10);
Octree = KCLOctree.FromTriangles(Triangles.ToArray(), Header, 2048, 128, 128, 50);
}
diff --git a/MarioKart/MKDS/NKM/AREA.cs b/MarioKart/MKDS/NKM/AREA.cs
index 3d1675d..a5a5e89 100644
--- a/MarioKart/MKDS/NKM/AREA.cs
+++ b/MarioKart/MKDS/NKM/AREA.cs
@@ -143,7 +143,7 @@ namespace MarioKart.MKDS.NKM
public Byte Unknown8 { get; set; }
public SByte LinkedCame { get; set; }
- public Byte AreaType { get; set; }//1 = Camera Stuff, 4 = Water Fall Sound Area
+ public Byte AreaType { get; set; }//1 = Camera Area, 3 = Area for Boo's etc. (unknown5 = subtype), 4 = Water Fall Sound Area
public UInt16 Unknown10 { get; set; }//unverified
diff --git a/NDS/NDS.csproj b/NDS/NDS.csproj
index 5472b90..3c2bdb4 100644
--- a/NDS/NDS.csproj
+++ b/NDS/NDS.csproj
@@ -55,6 +55,8 @@
+
+
diff --git a/NDS/NitroSystem/SND/SDAT.cs b/NDS/NitroSystem/SND/SDAT.cs
index 8e07131..a5f6350 100644
--- a/NDS/NitroSystem/SND/SDAT.cs
+++ b/NDS/NitroSystem/SND/SDAT.cs
@@ -6,6 +6,7 @@ using LibEveryFileExplorer.Files;
using System.Drawing;
using System.IO;
using LibEveryFileExplorer.IO;
+using LibEveryFileExplorer.IO.Serialization;
namespace NDS.NitroSystem.SND
{
@@ -13,7 +14,7 @@ namespace NDS.NitroSystem.SND
{
public SDAT(byte[] Data)
{
- EndianBinaryReader er = new EndianBinaryReader(new MemoryStream(Data), Endianness.LittleEndian);
+ EndianBinaryReaderEx er = new EndianBinaryReaderEx(new MemoryStream(Data), Endianness.LittleEndian);
try
{
Header = new SDATHeader(er);
@@ -43,9 +44,10 @@ namespace NDS.NitroSystem.SND
public SDATHeader Header;
public class SDATHeader
{
- public SDATHeader(EndianBinaryReader er)
+ public SDATHeader(EndianBinaryReaderEx er)
{
- Signature = er.ReadString(Encoding.ASCII, 4);
+ er.ReadObject(this);
+ /*Signature = er.ReadString(Encoding.ASCII, 4);
if (Signature != "SDAT") throw new SignatureNotCorrectException(Signature, "SDAT", er.BaseStream.Position - 4);
Endianness = er.ReadUInt16();
Version = er.ReadUInt16();
@@ -60,9 +62,12 @@ namespace NDS.NitroSystem.SND
FATLength = er.ReadUInt32();
FILEOffset = er.ReadUInt32();
FILELength = er.ReadUInt32();
- Padding = er.ReadBytes(16);
+ Padding = er.ReadBytes(16);*/
}
+ [BinaryStringSignature("SDAT")]
+ [BinaryFixedSize(4)]
public String Signature;
+ [BinaryBOM(0xFFFE)]
public UInt16 Endianness;
public UInt16 Version;
public UInt32 FileSize;
@@ -76,6 +81,7 @@ namespace NDS.NitroSystem.SND
public UInt32 FATLength;
public UInt32 FILEOffset;
public UInt32 FILELength;
+ [BinaryFixedSize(16)]
public byte[] Padding;//16
}
@@ -289,12 +295,12 @@ namespace NDS.NitroSystem.SND
public override string GetFileDescription()
{
- return "Sound Data (SDAT)";
+ return "Nitro Sound Data (SDAT)";
}
public override string GetFileFilter()
{
- return "Sound Data (*.sdat)|*.sdat";
+ return "Nitro Sound Data (*.sdat)|*.sdat";
}
public override Bitmap GetIcon()
diff --git a/NDS/NitroSystem/SND/SWAR.cs b/NDS/NitroSystem/SND/SWAR.cs
new file mode 100644
index 0000000..fa03b98
--- /dev/null
+++ b/NDS/NitroSystem/SND/SWAR.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using LibEveryFileExplorer.Files;
+using System.Drawing;
+using LibEveryFileExplorer.IO;
+using LibEveryFileExplorer.IO.Serialization;
+
+namespace NDS.NitroSystem.SND
+{
+ public class SWAR : FileFormat//, IViewable
+ {
+ public SWARHeader Header;
+ public class SWARHeader
+ {
+ public SWARHeader(EndianBinaryReaderEx er)
+ {
+ er.ReadObject(this);
+ }
+ [BinaryStringSignature("SWAR")]
+ [BinaryFixedSize(4)]
+ public String Signature;
+ [BinaryBOM(0xFFFE)]
+ public UInt16 Endianness;
+ public UInt16 Version;
+ public UInt32 FileSize;
+ public UInt16 HeaderSize;
+ public UInt16 NrBlocks;
+ }
+
+ public DATA Data;
+ public class DATA
+ {
+ public DATA(EndianBinaryReaderEx er)
+ {
+ er.ReadObject(this);
+ WaveInfoOffsets = er.ReadUInt32s((int)NrWaves);
+
+ }
+ [BinaryStringSignature("DATA")]
+ [BinaryFixedSize(4)]
+ public String Signature;
+ public UInt32 SectionSize;
+ [BinaryFixedSize(32)]
+ public Byte[] Padding;
+ public UInt32 NrWaves;
+ [BinaryIgnore]
+ public UInt32[] WaveInfoOffsets;
+ }
+ public class SWARIdentifier : FileFormatIdentifier
+ {
+ public override string GetCategory()
+ {
+ return Category_Archives;
+ }
+
+ public override string GetFileDescription()
+ {
+ return "Nitro Sound Wave Archive (SWAR)";
+ }
+
+ public override string GetFileFilter()
+ {
+ return "Nitro Sound Wave Archive (*.sdat)|*.sdat";
+ }
+
+ public override Bitmap GetIcon()
+ {
+ return null;
+ }
+
+ public override FormatMatch IsFormat(EFEFile File)
+ {
+ if (File.Data.Length > 4 && File.Data[0] == 'S' && File.Data[1] == 'W' && File.Data[2] == 'A' && File.Data[3] == 'R') return FormatMatch.Content;
+ return FormatMatch.No;
+ }
+
+ }
+ }
+}
diff --git a/NDS/NitroSystem/SND/SWAV.cs b/NDS/NitroSystem/SND/SWAV.cs
new file mode 100644
index 0000000..100c4c7
--- /dev/null
+++ b/NDS/NitroSystem/SND/SWAV.cs
@@ -0,0 +1,31 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using LibEveryFileExplorer.IO;
+using LibEveryFileExplorer.IO.Serialization;
+using LibEveryFileExplorer.Files;
+
+namespace NDS.NitroSystem.SND
+{
+ public class SWAV : FileFormat//, IViewable
+ {
+ public SWAVHeader Header;
+ public class SWAVHeader
+ {
+ public SWAVHeader(EndianBinaryReaderEx er)
+ {
+ er.ReadObject(this);
+ }
+ [BinaryStringSignature("SWAV")]
+ [BinaryFixedSize(4)]
+ public String Signature;
+ [BinaryBOM(0xFFFE)]
+ public UInt16 Endianness;
+ public UInt16 Version;
+ public UInt32 FileSize;
+ public UInt16 HeaderSize;
+ public UInt16 NrBlocks;
+ }
+ }
+}
diff --git a/WiiU/GPU/Textures.cs b/WiiU/GPU/Textures.cs
index 03d52a7..b72b256 100644
--- a/WiiU/GPU/Textures.cs
+++ b/WiiU/GPU/Textures.cs
@@ -10,40 +10,40 @@ 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 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
- }
+ 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[] Bpp = { 32, 24, 16, 16, 16, 16, 16, 8, 8, 8, 4, 4, 4, 8 };
- private static readonly int[] TileOrder =
+ private static readonly int[] TileOrder =
{
0, 1, 4, 5,
2, 3, 6, 7,
@@ -51,11 +51,11 @@ namespace WiiU.GPU
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
+ //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 =
+ private static readonly int[,] ETC1Modifiers =
{
{ 2, 8 },
{ 5, 17 },
@@ -67,370 +67,439 @@ namespace WiiU.GPU
{ 47, 183 }
};
- //public static int GetBpp(ImageFormat Format) { return Bpp[(uint)Format]; }
+ //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 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;
- }
+ 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 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;
- }
+ 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 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 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]/
+ //Micro tiles: 8x8
+ //Macro tiles: 32x16 (4x2 tiles = 4 banks, 2 pipes)
- 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];
- }
- }
- */
- }
+ //Alignment: 2048 pixels (I think), which matches exactly with the 128x16 blocks
- 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;
- }
+ //First block:
+ // Macro:
+ // 1 2 5 6
+ // 0 3 4 7
+ //Second block:
+ // Macro:
+ // 5 6 1 2
+ // 4 7 0 3
+ //Third block:
+ // Macro:
+ // 3 0 7 4
+ // 2 1 6 5
+ //Fourth block:
+ // Macro:
+ // 7 4 3 0
+ // 6 5 2 1
+ private static unsafe void DetileTiled2DThin1(uint* res, int stride, int width, int height, int physicalwidth, int physicalheight)
+ {
+ uint[] right_order = new uint[width * height];
+ int q = 0;
+ //Let's put the tiles in the right order
+ for (int y = 0; y < height; y += 8)
+ {
+ for (int xx = 0; xx < width; xx += 64)
+ {
+ for (int yy = 0; yy < 8; yy++)
+ {
+ for (int x = 0; x < 64; x++)
+ {
+ right_order[q++] = res[(y + yy) * stride + x + xx];
+ }
+ }
+ }
+ }
- private static int ColorClamp(int Color)
- {
- if (Color > 255) Color = 255;
- if (Color < 0) Color = 0;
- return Color;
- }
+ q = 0;
+ uint[] Result = new uint[width * height];
+ for (int y = 0; y < height; y += 8)
+ {
+ for (int x = 0; x < width; x += 8)
+ {
+ for (int yy = 0; yy < 8; yy++)
+ {
+ for (int xx = 0; xx < 8; xx++)
+ {
+ Result[(y + yy) * width + x + xx] = right_order[q++];
+ }
+ }
+ }
+ }
- }
+ //
+
+ /* uint[] Result = new uint[width * height];
+ int px = 0;
+ int py = 0;
+ for (int y = 0; y < height; y += /*8/16)
+ {
+ for (int x = 0; x < width; x += 64)
+ {
+
+ /*for (int y2 = 0; y2 < 8; y2++)
+ {
+ for (int x2 = 0; x2 < 64; x2++)
+ {
+ Result[(y + (x2 / 8)) * width + x + y2 * 8 + x2 % 8] =
+ res[(y + y2) * stride + x + x2];
+ }
+ }/
+ /*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 (y + y3 + yy >= height || x + x3 + xx >= width) continue;
+ //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);
+ }
+ }
+ }/
+ }
+ }*/
+ //TODO: We now have the tiles, so start constructing the macro tiles
+
+ /*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;
+ }
+
+ }
}