Add support for basic BTI and TXE

This commit is contained in:
JohnFiddleystein 2019-08-04 14:15:34 +01:00
parent 1f8bd2e19e
commit dd33b5e6c5
16 changed files with 390 additions and 34 deletions

BIN
.vs/Toolbox/v16/.suo Normal file

Binary file not shown.

View file

Binary file not shown.

View file

@ -0,0 +1,175 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.Forms;
using Toolbox.Library.IO;
namespace AmbrosiaPikmin1.FileFormats.BTI
{
class BTI : TreeNodeFile, IFileFormat
{
public FileType FileType { get; set; } = FileType.Image;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Binary Texture Image" };
public string[] Extension { get; set; } = new string[] { "*.bti" };
public string FileName { get; set; }
public string FilePath { get; set; }
//Stores compression info from being opened (done automaitcally)
public IFileInfo IFileInfo { get; set; }
//Check how the file wil be opened
public bool Identify(System.IO.Stream stream)
{
return Utils.HasExtension(FileName, ".bti");
}
//A Type list for custom types
//With this you can add in classes with IFileMenuExtension to add menus for this format
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
private int RoundWidth(int width, int BlockWidth)
{
return width + ((BlockWidth - (width % BlockWidth)) % BlockWidth);
}
private int RoundHeight(int height, int BlockHeight)
{
return height + ((BlockHeight - (height % BlockHeight)) % BlockHeight);
}
public void Load(System.IO.Stream stream)
{
//Set this if you want to save the file format
CanSave = true;
//You can add a FileReader with Toolbox.Library.IO namespace
using (var reader = new FileReader(stream))
{
Texture tex = new Texture();
tex.CanEdit = false;
reader.SetByteOrder(true);
//Turn this format into a common format used by this tool
byte texFormat = reader.ReadByte();
tex.Format = Decode_Gamecube.ToGenericFormat((Decode_Gamecube.TextureFormats)texFormat);
_ = reader.ReadByte(); // enable alpha
tex.Width = reader.ReadUInt16();
tex.Height = reader.ReadUInt16();
_ = reader.ReadByte(); // wrap s
_ = reader.ReadByte(); // wrap t
tex.PaletteFormat = (PALETTE_FORMAT)reader.ReadInt16();
_ = reader.ReadInt16(); // num of palette entries
_ = reader.ReadInt32(); // offset to palette data
_ = reader.ReadInt32(); // border colour
_ = reader.ReadByte(); // min filter type
_ = reader.ReadByte(); // mag filter type
_ = reader.ReadInt16();
tex.MipCount = reader.ReadByte();
_ = reader.ReadByte();
_ = reader.ReadInt16();
uint offsetToImageData = reader.ReadUInt32(); // offset to image data
//Lets set our method of decoding
tex.PlatformSwizzle = PlatformSwizzle.Platform_Gamecube;
reader.Seek(offsetToImageData, System.IO.SeekOrigin.Begin);
int imageDataSize = RoundWidth((int)tex.Width, (int)STGenericTexture.GetBlockWidth(tex.Format)) * RoundHeight((int)tex.Height, (int)STGenericTexture.GetBlockHeight(tex.Format))
* (int)STGenericTexture.GetBytesPerPixel(tex.Format) >> 3;
tex.ImageData = reader.ReadBytes(imageDataSize);
tex.Name = FileName;
tex.ToolTipText = "Binary Texture Image, used for 2D textures like fonts";
_ = Nodes.Add(tex);
}
}
public byte[] Save()
{
return null;
}
public void Unload()
{
}
public class Texture : STGenericTexture
{
public byte[] ImageData { get; set; }
//A list of supported formats
//This gets used in the re encode option
public override TEX_FORMAT[] SupportedFormats
{
get
{
return new TEX_FORMAT[]
{
TEX_FORMAT.I4,
TEX_FORMAT.I8,
TEX_FORMAT.I4,
TEX_FORMAT.I8,
TEX_FORMAT.RGB565,
TEX_FORMAT.RGB5A3,
TEX_FORMAT.RGBA32,
TEX_FORMAT.C4,
TEX_FORMAT.C8,
TEX_FORMAT.C14X2,
TEX_FORMAT.CMPR,
};
}
}
public override bool CanEdit { get; set; } = false;
//This gets used in the image editor if the image gets edited
//This wll not be ran if "CanEdit" is set to false!
public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel)
{
}
//Gets the raw image data in bytes
//Gets decoded automatically
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
{
return ImageData;
}
//This is an event for when the tree is clicked on
//Load our editor
public override void OnClick(TreeView treeView)
{
//Here we check for an active editor and load a new one if not found
//This is used when a tree/object editor is used
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
if (editor == null)
{
editor = new ImageEditorBase();
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
//Load our image and any properties
//If you don't make a class for properties you can use a generic class provided in STGenericTexture
editor.LoadProperties(GenericProperties);
editor.LoadImage(this);
}
}
}
}

View file

@ -0,0 +1,156 @@
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using Toolbox.Library;
using Toolbox.Library.Forms;
using Toolbox.Library.IO;
namespace AmbrosiaPikmin1.FileFormats.TXE
{
class TXE : TreeNodeFile, IFileFormat
{
public FileType FileType { get; set; } = FileType.Image;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Pikmin 1 Proprietary Texture" };
public string[] Extension { get; set; } = new string[] { "*.txe" };
public string FileName { get; set; }
public string FilePath { get; set; }
//Stores compression info from being opened (done automaitcally)
public IFileInfo IFileInfo { get; set; }
//Check how the file wil be opened
public bool Identify(System.IO.Stream stream)
{
return Utils.HasExtension(FileName, ".txe");
}
//A Type list for custom types
//With this you can add in classes with IFileMenuExtension to add menus for this format
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
private void SkipPadding(FileReader stream, int offset)
{
stream.Seek((~(offset - 1) & (stream.Position + offset - 1)) - stream.Position);
}
public void Load(System.IO.Stream stream)
{
//Set this if you want to save the file format
CanSave = true;
//You can add a FileReader with Toolbox.Library.IO namespace
using (var reader = new FileReader(stream))
{
Texture tex = new Texture();
tex.CanEdit = false;
reader.SetByteOrder(true);
tex.Width = reader.ReadUInt16();
tex.Height = reader.ReadUInt16();
_ = reader.ReadInt16();
//Turn this format into a common format used by this tool
short texFormat = reader.ReadInt16();
tex.Format = Decode_Gamecube.ToGenericFormat((Decode_Gamecube.TextureFormats)texFormat);
//Lets set our method of decoding
tex.PlatformSwizzle = PlatformSwizzle.Platform_Gamecube;
int imageDataSize = reader.ReadInt32();
SkipPadding(reader, 0x20);
tex.ImageData = reader.ReadBytes(imageDataSize);
tex.Name = FileName;
tex.ToolTipText = "Binary Texture Image, used for 2D textures like fonts";
_ = Nodes.Add(tex);
}
}
public byte[] Save()
{
return null;
}
public void Unload()
{
}
public class Texture : STGenericTexture
{
public byte[] ImageData { get; set; }
//A list of supported formats
//This gets used in the re encode option
public override TEX_FORMAT[] SupportedFormats
{
get
{
return new TEX_FORMAT[]
{
TEX_FORMAT.I4,
TEX_FORMAT.I8,
TEX_FORMAT.I4,
TEX_FORMAT.I8,
TEX_FORMAT.RGB565,
TEX_FORMAT.RGB5A3,
TEX_FORMAT.RGBA32,
TEX_FORMAT.C4,
TEX_FORMAT.C8,
TEX_FORMAT.C14X2,
TEX_FORMAT.CMPR,
};
}
}
public override bool CanEdit { get; set; } = false;
//This gets used in the image editor if the image gets edited
//This wll not be ran if "CanEdit" is set to false!
public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel)
{
}
//Gets the raw image data in bytes
//Gets decoded automatically
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
{
return ImageData;
}
//This is an event for when the tree is clicked on
//Load our editor
public override void OnClick(TreeView treeView)
{
//Here we check for an active editor and load a new one if not found
//This is used when a tree/object editor is used
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
if (editor == null)
{
editor = new ImageEditorBase();
editor.Dock = DockStyle.Fill;
LibraryGUI.LoadEditor(editor);
}
//Load our image and any properties
//If you don't make a class for properties you can use a generic class provided in STGenericTexture
editor.LoadProperties(GenericProperties);
editor.LoadImage(this);
}
}
}
}

View file

@ -275,10 +275,12 @@
<Compile Include="FileFormats\Font\BFTTF.cs" /> <Compile Include="FileFormats\Font\BFTTF.cs" />
<Compile Include="FileFormats\HyruleWarriors\G1M.cs" /> <Compile Include="FileFormats\HyruleWarriors\G1M.cs" />
<Compile Include="FileFormats\Message\MSBP.cs" /> <Compile Include="FileFormats\Message\MSBP.cs" />
<Compile Include="FileFormats\Texture\TXE.cs" />
<Compile Include="FileFormats\Texture\CTPK.cs" /> <Compile Include="FileFormats\Texture\CTPK.cs" />
<Compile Include="FileFormats\Grezzo\CTXB.cs" /> <Compile Include="FileFormats\Grezzo\CTXB.cs" />
<Compile Include="FileFormats\Texture\TPL.cs" /> <Compile Include="FileFormats\Texture\TPL.cs" />
<Compile Include="FileFormats\Rom\GCDisk.cs" /> <Compile Include="FileFormats\Rom\GCDisk.cs" />
<Compile Include="FileFormats\Texture\BTI.cs" />
<Compile Include="GL\BMD_Renderer.cs" /> <Compile Include="GL\BMD_Renderer.cs" />
<Compile Include="GL\CMB_Renderer.cs" /> <Compile Include="GL\CMB_Renderer.cs" />
<Compile Include="GL\GXToOpenGL.cs" /> <Compile Include="GL\GXToOpenGL.cs" />

View file

@ -8,6 +8,8 @@ using Toolbox.Library.Forms;
using Toolbox.Library.IO; using Toolbox.Library.IO;
using FirstPlugin.Forms; using FirstPlugin.Forms;
using FirstPlugin.LuigisMansion.DarkMoon; using FirstPlugin.LuigisMansion.DarkMoon;
using AmbrosiaPikmin1.FileFormats.BTI;
using AmbrosiaPikmin1.FileFormats.TXE;
namespace FirstPlugin namespace FirstPlugin
{ {
@ -287,6 +289,8 @@ namespace FirstPlugin
private Type[] LoadFileFormats() private Type[] LoadFileFormats()
{ {
List<Type> Formats = new List<Type>(); List<Type> Formats = new List<Type>();
Formats.Add(typeof(BTI));
Formats.Add(typeof(TXE));
Formats.Add(typeof(SARC)); Formats.Add(typeof(SARC));
Formats.Add(typeof(BFRES)); Formats.Add(typeof(BFRES));
Formats.Add(typeof(BCRES)); Formats.Add(typeof(BCRES));

View file

@ -188,5 +188,7 @@ namespace Toolbox.Library
C8 = 247, C8 = 247,
C14X2 = 248, C14X2 = 248,
CMPR = 249, CMPR = 249,
RGB565 = 250,
RGB5A3 = 251
} }
} }

View file

@ -103,7 +103,7 @@ namespace Toolbox.Library
// //
//Gets a list of surfaces given the start index of the array and the amount of arrays to obtain //Gets a list of surfaces given the start index of the array and the amount of arrays to obtain
// //
public List<Surface> GetSurfaces(int ArrayIndexStart = 0, bool GetAllSurfaces = true, int GetSurfaceAmount = 1 ) public List<Surface> GetSurfaces(int ArrayIndexStart = 0, bool GetAllSurfaces = true, int GetSurfaceAmount = 1)
{ {
if (GetAllSurfaces) if (GetAllSurfaces)
GetSurfaceAmount = (int)ArrayCount; GetSurfaceAmount = (int)ArrayCount;
@ -146,7 +146,8 @@ namespace Toolbox.Library
public uint MipCount public uint MipCount
{ {
get { return mipCount; } get { return mipCount; }
set { set
{
if (value == 0) if (value == 0)
mipCount = 1; mipCount = 1;
else if (value > 17) else if (value > 17)
@ -184,7 +185,7 @@ namespace Toolbox.Library
public RenderableTex RenderableTex { get; set; } public RenderableTex RenderableTex { get; set; }
public abstract TEX_FORMAT[] SupportedFormats { get;} public abstract TEX_FORMAT[] SupportedFormats { get; }
public static uint GetBytesPerPixel(TEX_FORMAT Format) public static uint GetBytesPerPixel(TEX_FORMAT Format)
{ {
@ -317,7 +318,20 @@ namespace Toolbox.Library
{ TEX_FORMAT.D16_UNORM, new FormatInfo(2, 1, 1, 1, TargetBuffer.Depth) }, { TEX_FORMAT.D16_UNORM, new FormatInfo(2, 1, 1, 1, TargetBuffer.Depth) },
{ TEX_FORMAT.D24_UNORM_S8_UINT, new FormatInfo(4, 1, 1, 1, TargetBuffer.Depth) }, { TEX_FORMAT.D24_UNORM_S8_UINT, new FormatInfo(4, 1, 1, 1, TargetBuffer.Depth) },
{ TEX_FORMAT.D32_FLOAT, new FormatInfo(4, 1, 1, 1, TargetBuffer.Depth) }, { TEX_FORMAT.D32_FLOAT, new FormatInfo(4, 1, 1, 1, TargetBuffer.Depth) },
{ TEX_FORMAT.D32_FLOAT_S8X24_UINT, new FormatInfo(8, 1, 1, 1,TargetBuffer.DepthStencil) } { TEX_FORMAT.D32_FLOAT_S8X24_UINT, new FormatInfo(8, 1, 1, 1, TargetBuffer.DepthStencil)},
{ TEX_FORMAT.I4, new FormatInfo(4, 8, 8, 1, TargetBuffer.Color) },
{ TEX_FORMAT.I8, new FormatInfo(8, 8, 4, 1, TargetBuffer.Color) },
{ TEX_FORMAT.IA4, new FormatInfo(8, 8, 4, 1, TargetBuffer.Color) },
{ TEX_FORMAT.IA8, new FormatInfo(16, 4, 4, 1, TargetBuffer.Color) },
{ TEX_FORMAT.RGB565, new FormatInfo(16, 4, 4, 1, TargetBuffer.Color) },
{ TEX_FORMAT.RGB5A3, new FormatInfo(16, 4, 4, 1, TargetBuffer.Color) },
{ TEX_FORMAT.RGBA32, new FormatInfo(32, 4, 4, 1, TargetBuffer.Color) },
{ TEX_FORMAT.C4, new FormatInfo(4, 8, 8, 1, TargetBuffer.Color) },
{ TEX_FORMAT.C8, new FormatInfo(8, 8, 4, 1, TargetBuffer.Color) },
{ TEX_FORMAT.C14X2, new FormatInfo(16, 4, 4, 1, TargetBuffer.Color) },
{ TEX_FORMAT.CMPR, new FormatInfo(4, 8, 8, 1, TargetBuffer.Color) }
}; };
/// <summary> /// <summary>
@ -328,7 +342,7 @@ namespace Toolbox.Library
public List<byte[]> mipmaps = new List<byte[]>(); public List<byte[]> mipmaps = new List<byte[]>();
} }
public void CreateGenericTexture(uint width, uint height, List<Surface> surfaces, TEX_FORMAT format ) public void CreateGenericTexture(uint width, uint height, List<Surface> surfaces, TEX_FORMAT format)
{ {
Width = width; Width = width;
Height = height; Height = height;
@ -383,14 +397,15 @@ namespace Toolbox.Library
byte[] data = GetImageData(ArrayLevel, MipLevel); byte[] data = GetImageData(ArrayLevel, MipLevel);
byte[] paletteData = GetPaletteData(); byte[] paletteData = GetPaletteData();
if (data.Length == 0) if (data.Length == 0)
return new Bitmap(1,1); return new Bitmap(1, 1);
try try
{ {
if (data == null) if (data == null)
throw new Exception("Data is null!"); throw new Exception("Data is null!");
if (PlatformSwizzle == PlatformSwizzle.Platform_3DS && !IsCompressed(Format)) { if (PlatformSwizzle == PlatformSwizzle.Platform_3DS && !IsCompressed(Format))
{
var Image = BitmapExtension.GetBitmap(ConvertBgraToRgba(CTR_3DS.DecodeBlock(data, (int)width, (int)height, Format)), var Image = BitmapExtension.GetBitmap(ConvertBgraToRgba(CTR_3DS.DecodeBlock(data, (int)width, (int)height, Format)),
(int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); (int)width, (int)height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
Image.RotateFlip(RotateFlipType.RotateNoneFlipY); //It's upside down for some reason so flip it Image.RotateFlip(RotateFlipType.RotateNoneFlipY); //It's upside down for some reason so flip it
@ -686,7 +701,8 @@ namespace Toolbox.Library
} }
} }
public override void Export(string FileName) { public override void Export(string FileName)
{
Export(FileName); Export(FileName);
} }
@ -712,7 +728,7 @@ namespace Toolbox.Library
if (sfd.ShowDialog() == DialogResult.OK) if (sfd.ShowDialog() == DialogResult.OK)
{ {
Export(sfd.FileName, false, false, 0,0); Export(sfd.FileName, false, false, 0, 0);
} }
} }

Binary file not shown.

Binary file not shown.

View file

@ -27,9 +27,9 @@ namespace Toolbox.Library
case TextureFormats.I8: return TEX_FORMAT.I8; case TextureFormats.I8: return TEX_FORMAT.I8;
case TextureFormats.IA4: return TEX_FORMAT.IA4; case TextureFormats.IA4: return TEX_FORMAT.IA4;
case TextureFormats.IA8: return TEX_FORMAT.IA8; case TextureFormats.IA8: return TEX_FORMAT.IA8;
case TextureFormats.RGB565: return TEX_FORMAT.R5G5B5_UNORM; case TextureFormats.RGB565: return TEX_FORMAT.RGB565;
case TextureFormats.RGB5A3: return TEX_FORMAT.R5G5B5A3_UNORM; case TextureFormats.RGB5A3: return TEX_FORMAT.RGB5A3;
case TextureFormats.RGBA32: return TEX_FORMAT.R32G32B32A32_FLOAT; case TextureFormats.RGBA32: return TEX_FORMAT.RGBA32;
default: default:
throw new Exception("Unknown Format " + Format); throw new Exception("Unknown Format " + Format);
} }
@ -72,9 +72,9 @@ namespace Toolbox.Library
case TEX_FORMAT.I8: return TextureFormats.I8; case TEX_FORMAT.I8: return TextureFormats.I8;
case TEX_FORMAT.IA4: return TextureFormats.IA4; case TEX_FORMAT.IA4: return TextureFormats.IA4;
case TEX_FORMAT.IA8: return TextureFormats.IA8; case TEX_FORMAT.IA8: return TextureFormats.IA8;
case TEX_FORMAT.R5G5B5_UNORM: return TextureFormats.RGB565; case TEX_FORMAT.RGB565: return TextureFormats.RGB565;
case TEX_FORMAT.R5G5B5A3_UNORM: return TextureFormats.RGB5A3; case TEX_FORMAT.RGB5A3: return TextureFormats.RGB5A3;
case TEX_FORMAT.R32G32B32A32_FLOAT: return TextureFormats.RGBA32; case TEX_FORMAT.RGBA32: return TextureFormats.RGBA32;
default: default:
throw new Exception("Unknown Format " + Format); throw new Exception("Unknown Format " + Format);
} }

View file

@ -98,6 +98,7 @@
<HintPath>..\Toolbox\Lib\NAudio.dll</HintPath> <HintPath>..\Toolbox\Lib\NAudio.dll</HintPath>
<Private>False</Private> <Private>False</Private>
</Reference> </Reference>
<Reference Include="netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" />
<Reference Include="ObjectListView"> <Reference Include="ObjectListView">
<HintPath>..\Toolbox\Lib\ObjectListView.dll</HintPath> <HintPath>..\Toolbox\Lib\ObjectListView.dll</HintPath>
<Private>False</Private> <Private>False</Private>

View file

@ -1 +1 @@
747948e0929dd8935549f97d0e91eb2d59336ea8 2dd7d0617dba111aa487a7da42ed4f5f18627a3f