private void ReadGx2(FileReader reader) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; header = new GTXHeader(); header.Read(reader); Console.WriteLine("header size " + header.HeaderSize); uint surfBlockType; uint dataBlockType; uint mipBlockType; if (header.MajorVersion == 6) { surfBlockType = 0x0A; dataBlockType = 0x0B; mipBlockType = 0x0C; } else if (header.MajorVersion == 7) { surfBlockType = 0x0B; dataBlockType = 0x0C; mipBlockType = 0x0D; } else { throw new Exception($"Unsupported GTX version {header.MajorVersion}"); } if (header.GpuVersion != 2) { throw new Exception($"Unsupported GPU version {header.GpuVersion}"); } reader.Position = header.HeaderSize; bool blockB = false; bool blockC = false; uint ImageInfo = 0; uint images = 0; while (reader.Position < reader.BaseStream.Length) { GTXDataBlock block = new GTXDataBlock(); block.Read(reader); blocks.Add(block); //Here we use "if" instead of "case" statements as types vary between versions if ((uint)block.BlockType == surfBlockType) { ImageInfo += 1; blockB = true; var surface = new SurfaceInfoParse(); surface.Read(new FileReader(block.data)); if (surface.numMips > 14) { throw new Exception($"Invalid number of mip maps {surface.numMips}!"); } TextureData textureData = new TextureData(); textureData.surface = surface; textureData.Text = "Texture" + ImageInfo; Nodes.Add(textureData); textures.Add(textureData); } else if ((uint)block.BlockType == dataBlockType) { images += 1; blockC = true; data.Add(block.data); } else if ((uint)block.BlockType == mipBlockType) { mipMaps.Add(block.data); } } if (textures.Count != data.Count) { throw new Exception($"Bad size! {textures.Count} {data.Count}"); } int curTex = 0; int curMip = 0; foreach (var node in Nodes) { TextureData tex = (TextureData)node; tex.surface.data = data[curTex]; tex.surface.bpp = GTX.surfaceGetBitsPerPixel(tex.surface.format) >> 3; Console.WriteLine(); if (tex.surface.numMips > 1) { tex.surface.mipData = mipMaps[curMip++]; } else { tex.surface.mipData = new byte[0]; } Console.WriteLine(""); Console.WriteLine("// ----- GX2Surface Info ----- "); Console.WriteLine(" dim = " + tex.surface.dim); Console.WriteLine(" width = " + tex.surface.width); Console.WriteLine(" height = " + tex.surface.height); Console.WriteLine(" depth = " + tex.surface.depth); Console.WriteLine(" numMips = " + tex.surface.numMips); Console.WriteLine(" format = " + tex.surface.format); Console.WriteLine(" aa = " + tex.surface.aa); Console.WriteLine(" use = " + tex.surface.use); Console.WriteLine(" imageSize = " + tex.surface.imageSize); Console.WriteLine(" mipSize = " + tex.surface.mipSize); Console.WriteLine(" tileMode = " + tex.surface.tileMode); Console.WriteLine(" swizzle = " + tex.surface.swizzle); Console.WriteLine(" alignment = " + tex.surface.alignment); Console.WriteLine(" pitch = " + tex.surface.pitch); Console.WriteLine(" bits per pixel = " + (tex.surface.bpp << 3)); Console.WriteLine(" bytes per pixel = " + tex.surface.bpp); Console.WriteLine(" data size = " + tex.surface.data.Length); Console.WriteLine(" mip size = " + tex.surface.mipData.Length); Console.WriteLine(" realSize = " + tex.surface.imageSize); List <byte[]> mips = GTX.Decode(tex.surface); tex.Surfaces.Add(new STGenericTexture.Surface() { mipmaps = mips }); tex.RenderableTex.LoadOpenGLTexture(tex); curTex++; } }
private void ReadGx2(FileReader reader) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; header = new GTXHeader(); header.Read(reader); Console.WriteLine("header size " + header.HeaderSize); uint surfBlockType; uint dataBlockType; uint mipBlockType; uint vertexShaderHeader = 0x03; uint vertexShaderProgram = 0x05; uint pixelShaderHeader = 0x06; uint pixelShaderProgram = 0x07; uint geometryShaderHeader = 0x08; uint geometryShaderProgram = 0x09; uint userDataBlock = 0x10; if (header.MajorVersion == 6 && header.MinorVersion == 0) { surfBlockType = 0x0A; dataBlockType = 0x0B; mipBlockType = 0x0C; } else if (header.MajorVersion == 6 || header.MajorVersion == 7) { surfBlockType = 0x0B; dataBlockType = 0x0C; mipBlockType = 0x0D; } else { throw new Exception($"Unsupported GTX version {header.MajorVersion}"); } if (header.GpuVersion != 2) { throw new Exception($"Unsupported GPU version {header.GpuVersion}"); } reader.Position = header.HeaderSize; bool blockB = false; bool blockC = false; uint ImageInfo = 0; uint images = 0; while (reader.Position < reader.BaseStream.Length) { Console.WriteLine("BLOCK POS " + reader.Position + " " + reader.BaseStream.Length); GTXDataBlock block = new GTXDataBlock(); block.Read(reader); blocks.Add(block); bool BlockIsEmpty = block.BlockType == BlockType.AlignData || block.BlockType == BlockType.EndOfFile; //Here we use "if" instead of "case" statements as types vary between versions if ((uint)block.BlockType == surfBlockType) { ImageInfo += 1; blockB = true; var surface = new SurfaceInfoParse(); surface.Read(new FileReader(block.data)); if (surface.tileMode == 0 || surface.tileMode > 16) { throw new Exception($"Invalid tileMode {surface.tileMode}!"); } if (surface.numMips > 14) { throw new Exception($"Invalid number of mip maps {surface.numMips}!"); } TextureData textureData = new TextureData(); textureData.surface = surface; textureData.MipCount = surface.numMips; textureData.ArrayCount = surface.depth; textureData.Text = "Texture" + ImageInfo; Nodes.Add(textureData); textures.Add(textureData); } else if ((uint)block.BlockType == dataBlockType) { images += 1; blockC = true; data.Add(block.data); } else if ((uint)block.BlockType == mipBlockType) { mipMaps.Add(block.data); } else if ((uint)block.BlockType == vertexShaderHeader) { Nodes.Add(new BlockDisplay(block.data) { Text = "Vertex Shader Header" }); } else if ((uint)block.BlockType == vertexShaderProgram) { Nodes.Add(new BlockDisplay(block.data) { Text = "Vertex Shader Program" }); } else if ((uint)block.BlockType == pixelShaderHeader) { Nodes.Add(new BlockDisplay(block.data) { Text = "Pixel Shader Header" }); } else if ((uint)block.BlockType == pixelShaderProgram) { Nodes.Add(new BlockDisplay(block.data) { Text = "Pixel Shader Program" }); } else if ((uint)block.BlockType == geometryShaderHeader) { Nodes.Add(new BlockDisplay(block.data) { Text = "Geometry Shader Header" }); } else if ((uint)block.BlockType == geometryShaderProgram) { Nodes.Add(new BlockDisplay(block.data) { Text = "Geometry Shader Program" }); } else if (!BlockIsEmpty) { Nodes.Add(new BlockDisplay(block.data) { Text = $"Block Type {block.BlockType.ToString("X")}" }); } } if (textures.Count != data.Count) { throw new Exception($"Bad size! {textures.Count} {data.Count}"); } int curTex = 0; int curMip = 0; foreach (var node in Nodes) { if (node is TextureData) { TextureData tex = (TextureData)node; tex.surface.data = data[curTex]; tex.surface.bpp = GX2.surfaceGetBitsPerPixel(tex.surface.format) >> 3; tex.Format = FTEX.ConvertFromGx2Format((Syroot.NintenTools.Bfres.GX2.GX2SurfaceFormat)tex.surface.format); tex.Width = tex.surface.width; tex.Height = tex.surface.height; if (tex.surface.numMips > 1) { tex.surface.mipData = mipMaps[curMip++]; } else { tex.surface.mipData = new byte[0]; } if (tex.surface.mipData == null) { tex.surface.numMips = 1; } curTex++; } } }
private void ReadGx2(FileReader reader) { reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; header = new GTXHeader(); header.Read(reader); Console.WriteLine("header size " + header.HeaderSize); uint surfBlockType; uint dataBlockType; uint mipBlockType; if (header.MajorVersion == 6) { surfBlockType = 0x0A; dataBlockType = 0x0B; mipBlockType = 0x0C; } else if (header.MajorVersion == 7) { surfBlockType = 0x0B; dataBlockType = 0x0C; mipBlockType = 0x0D; } else { throw new Exception($"Unsupported GTX version {header.MajorVersion}"); } if (header.GpuVersion != 2) { throw new Exception($"Unsupported GPU version {header.GpuVersion}"); } reader.Position = header.HeaderSize; bool blockB = false; bool blockC = false; uint ImageInfo = 0; uint images = 0; while (reader.Position < reader.BaseStream.Length) { GTXDataBlock block = new GTXDataBlock(); block.Read(reader); blocks.Add(block); //Here we use "if" instead of "case" statements as types vary between versions if ((uint)block.BlockType == surfBlockType) { ImageInfo += 1; blockB = true; var surface = new SurfaceInfoParse(); surface.Read(new FileReader(block.data)); if (surface.numMips > 14) { throw new Exception($"Invalid number of mip maps {surface.numMips}!"); } TextureData textureData = new TextureData(); textureData.surface = surface; textureData.MipCount = surface.numMips; textureData.ArrayCount = surface.numArray; textureData.Text = "Texture" + ImageInfo; Nodes.Add(textureData); textures.Add(textureData); } else if ((uint)block.BlockType == dataBlockType) { images += 1; blockC = true; data.Add(block.data); } else if ((uint)block.BlockType == mipBlockType) { mipMaps.Add(block.data); } } if (textures.Count != data.Count) { throw new Exception($"Bad size! {textures.Count} {data.Count}"); } int curTex = 0; int curMip = 0; foreach (var node in Nodes) { TextureData tex = (TextureData)node; tex.surface.data = data[curTex]; tex.surface.bpp = GTX.surfaceGetBitsPerPixel(tex.surface.format) >> 3; tex.Format = FTEX.ConvertFromGx2Format((Syroot.NintenTools.Bfres.GX2.GX2SurfaceFormat)tex.surface.format); tex.Width = tex.surface.width; tex.Height = tex.surface.height; if (tex.surface.numMips > 1) { tex.surface.mipData = mipMaps[curMip++]; } else { tex.surface.mipData = new byte[0]; } if (tex.surface.mipData == null) { tex.surface.numMips = 1; } curTex++; } reader.Close(); reader.Dispose(); }