From f9f00d193c9608d71c9a23d9f3ab7e752f4ada2a Mon Sep 17 00:00:00 2001 From: Gericom Date: Tue, 3 Nov 2015 16:18:38 +0100 Subject: [PATCH] Importing textures for bcmdl is possible now And some older stuff I didn't commit yet. --- 3DS/NintendoWare/GFX/CGFX.cs | 9 +- 3DS/NintendoWare/GFX/CMDL.cs | 226 ++++- 3DS/UI/CMDLViewer.Designer.cs | 3 +- 3DS/UI/CMDLViewer.cs | 13 + 3DS/UI/CMDLViewer.resx | 22 +- 3DS/UI/TXOBViewer.Designer.cs | 180 ++-- 3DS/UI/TXOBViewer.cs | 43 + 3DS/UI/TXOBViewer.resx | 3 + CommonFiles/CommonFiles.csproj | 1 + CommonFiles/Maya/MayaASCIIWriter.cs | 135 +++ LibEveryFileExplorer/Collections/Matrix33.cs | 2 +- LibEveryFileExplorer/Collections/Matrix44.cs | 2 +- MarioKart/MK7/KMP/CDMD.cs | 2 +- MarioKart/MKDS/KCL.cs | 1 + MarioKart/MKDS/NKM/AREA.cs | 2 +- NDS/NDS.csproj | 2 + NDS/NitroSystem/SND/SDAT.cs | 18 +- NDS/NitroSystem/SND/SWAR.cs | 81 ++ NDS/NitroSystem/SND/SWAV.cs | 31 + WiiU/GPU/Textures.cs | 849 ++++++++++--------- 20 files changed, 1121 insertions(+), 504 deletions(-) create mode 100644 CommonFiles/Maya/MayaASCIIWriter.cs create mode 100644 NDS/NitroSystem/SND/SWAR.cs create mode 100644 NDS/NitroSystem/SND/SWAV.cs 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; + } + + } }