diff --git a/Switch_FileFormatsMain/FileFormats/BCRES/BCRES.cs b/Switch_FileFormatsMain/FileFormats/BCRES/BCRES.cs index c97d30e1..54b3875d 100644 --- a/Switch_FileFormatsMain/FileFormats/BCRES/BCRES.cs +++ b/Switch_FileFormatsMain/FileFormats/BCRES/BCRES.cs @@ -97,6 +97,14 @@ namespace FirstPlugin if (Wrapper is CMDLWrapper) { LoadPropertyGrid(((CMDLWrapper)Wrapper).Model, OnPropertyChanged); } + + if (Wrapper is CRESBoneWrapper) { + LoadPropertyGrid(((CRESBoneWrapper)Wrapper).Bone, OnPropertyChanged); + } + + if (Wrapper is CRESSkeletonWrapper) { + LoadPropertyGrid(((CRESSkeletonWrapper)Wrapper).Skeleton, OnPropertyChanged); + } } private void LoadPropertyGrid(object property, Action OnPropertyChanged) diff --git a/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CMDLWrapper.cs b/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CMDLWrapper.cs index a6e7bdd6..952392a6 100644 --- a/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CMDLWrapper.cs +++ b/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CMDLWrapper.cs @@ -47,9 +47,11 @@ namespace FirstPlugin var MaterialFolder = new TreeNode("Materials"); var MeshFolder = new TreeNode("Meshes"); + var SkeletonWrapper = new CRESSkeletonWrapper(); Nodes.Add(MeshFolder); Nodes.Add(MaterialFolder); + Nodes.Add(SkeletonWrapper); foreach (var material in model.Materials.Values) { @@ -63,8 +65,10 @@ namespace FirstPlugin meshWrapper.Load(mesh); MeshFolder.Nodes.Add(meshWrapper); Shapes.Add(meshWrapper); - - + } + if (model.HasSkeleton) + { + SkeletonWrapper.Load(model.Skeleton, bcres); } } } diff --git a/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CRESBoneWrapper.cs b/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CRESBoneWrapper.cs new file mode 100644 index 00000000..24455d3c --- /dev/null +++ b/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CRESBoneWrapper.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Switch_Toolbox.Library; +using BcresLibrary; + +namespace FirstPlugin +{ + public class CRESBoneWrapper : STBone + { + internal BCRES BcresParent; + internal Bone Bone; + + public CRESBoneWrapper() + { + ImageKey = "Bone"; + SelectedImageKey = "Bone"; + } + + public CRESBoneWrapper(Bone bone, BCRES bcres) : base() + { + BcresParent = bcres; + Load(bone, bcres); + } + + public override void OnClick(TreeView treeview) { + BcresParent.LoadEditors(this, OnPropertyChanged); + } + + private void OnPropertyChanged() + { + + } + + public void Load(Bone bone, BCRES bcres) + { + BcresParent = bcres; + + Bone = bone; + Text = bone.Name; + } + } +} diff --git a/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CRESSkeletonWrapper.cs b/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CRESSkeletonWrapper.cs new file mode 100644 index 00000000..86268933 --- /dev/null +++ b/Switch_FileFormatsMain/FileFormats/BCRES/Wrappers/CMDL/CRESSkeletonWrapper.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Switch_Toolbox.Library; +using BcresLibrary; + +namespace FirstPlugin +{ + public class CRESSkeletonWrapper : STBone + { + internal BCRES BcresParent; + internal Skeleton Skeleton; + internal STSkeleton Renderable; + + public CRESSkeletonWrapper() + { + ImageKey = "Skeleton"; + SelectedImageKey = "Skeleton"; + } + + public CRESSkeletonWrapper(Skeleton skeleton, BCRES bcres) : base() + { + BcresParent = bcres; + Load(skeleton, bcres); + } + + public override void OnClick(TreeView treeview) { + BcresParent.LoadEditors(this, OnPropertyChanged); + } + + private void OnPropertyChanged() + { + + } + + public void Load(Skeleton skeleton, BCRES bcres) + { + Renderable = new STSkeleton(); + + BcresParent = bcres; + + Skeleton = skeleton; + Text = "Skeleton"; + + foreach (var bone in skeleton.Bones.Values) + { + var boneWrapper = new CRESBoneWrapper(); + boneWrapper.skeletonParent = Renderable; + boneWrapper.Load(bone, bcres); + Nodes.Add(boneWrapper); + Renderable.bones.Add(boneWrapper); + } + } + } +} diff --git a/Switch_FileFormatsMain/FileFormats/Font/BFFNT.cs b/Switch_FileFormatsMain/FileFormats/Font/BFFNT.cs index 95f02729..4985a53a 100644 --- a/Switch_FileFormatsMain/FileFormats/Font/BFFNT.cs +++ b/Switch_FileFormatsMain/FileFormats/Font/BFFNT.cs @@ -8,6 +8,8 @@ using System.Windows.Forms; using Switch_Toolbox.Library; using System.IO; using Switch_Toolbox.Library.IO; +using Switch_Toolbox.Library.Forms; +using System.Drawing; namespace FirstPlugin { @@ -46,13 +48,32 @@ namespace FirstPlugin FFNT bffnt = new FFNT(); bffnt.Read(new FileReader(stream)); - TGLP tglp = bffnt.finf.tglp; + TGLP tglp = bffnt.GetFontSection().tglp; + + var textureFolder = new TreeNode("Textures"); + Nodes.Add(textureFolder); + if (tglp.SheetDataList.Count > 0) + { + var bntx = STFileLoader.OpenFileFormat("Sheet_0", tglp.SheetDataList[0]); + if (bntx != null) + { + textureFolder.Nodes.Add((BNTX)bntx); + } + else + { + var surface = new Gx2ImageBlock(); + surface.Text = "Sheet_0"; + surface.Load(bffnt.GetFontSection()); + textureFolder.Nodes.Add(surface); + } + } + int i = 0; foreach (byte[] texture in tglp.SheetDataList) { - BNTX file = (BNTX)STFileLoader.OpenFileFormat("Sheet" + i++, texture); - Nodes.Add(file); + // BNTX file = (BNTX)STFileLoader.OpenFileFormat("Sheet" + i++, texture); + // Nodes.Add(file); } } public void Unload() @@ -105,30 +126,204 @@ namespace FirstPlugin public class FFNT { public ushort BOM; + public ushort HeaderSize; public uint Version; - public FINF finf; + + public FINF GetFontSection() + { + foreach (var block in Blocks) + { + if (block.GetType() == typeof(FINF)) + return (FINF)block; + } + return null; + } + + public List Blocks = new List(); public void Read(FileReader reader) { + reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian; + string Signature = reader.ReadString(4, Encoding.ASCII); if (Signature != "FFNT") throw new Exception($"Invalid signature {Signature}! Expected FFNT."); - char[] Magic = reader.ReadChars(4); BOM = reader.ReadUInt16(); + reader.CheckByteOrderMark(BOM); + HeaderSize = reader.ReadUInt16(); Version = reader.ReadUInt32(); uint FileSize = reader.ReadUInt16(); - uint BlockCount = reader.ReadUInt16(); - uint unk = reader.ReadUInt16(); + ushort BlockCount = reader.ReadUInt16(); + ushort Padding = reader.ReadUInt16(); - finf = new FINF(); - finf.Read(reader); + reader.Seek(HeaderSize, SeekOrigin.Begin); + string SignatureCheck = CheckSignature(reader); + switch (SignatureCheck) + { + case "FINF": + FINF finf = new FINF(); + finf.Read(reader); + Blocks.Add(finf); + break; + default: + throw new NotImplementedException("Unsupported block found! " + SignatureCheck); + } reader.Close(); reader.Dispose(); } + + private string CheckSignature(FileReader reader) + { + string Signature = reader.ReadString(4, Encoding.ASCII); + reader.Seek(-4, SeekOrigin.Current); + return Signature; + } } - public class FINF + + public enum Gx2ImageFormats + { + RGBA8_UNORM, + RGB8_UNORM, + RGB5A1_UNORM, + RGB565_UNORM, + RGBA4_UNORM, + LA8_UNORM, + LA4_UNORM, + A4_UNORM, + A8_UNORM, + BC1_UNORM, + BC2_UNORM, + BC3_UNORM, + BC4_UNORM, + BC5_UNORM, + RGBA8_SRGB, + BC1_SRGB, + BC2_SRGB, + BC3_SRGB, + } + + public class Gx2ImageBlock : STGenericTexture + { + public FINF TextureFINF; + + public void Load(FINF texture) + { + TextureFINF = texture; + Height = TextureFINF.Height; + Width = TextureFINF.Width; + var BFNTFormat = (Gx2ImageFormats)TextureFINF.tglp.Format; + Format = ConvertToGeneric(BFNTFormat); + + ImageKey = "Texture"; + SelectedImageKey = "Texture"; + } + + public override bool CanEdit { get; set; } = false; + + public override TEX_FORMAT[] SupportedFormats + { + get + { + return new TEX_FORMAT[] { + }; + } + } + + public TEX_FORMAT ConvertToGeneric(Gx2ImageFormats Format) + { + switch (Format) + { + case Gx2ImageFormats.A8_UNORM: return TEX_FORMAT.R8_UNORM; + case Gx2ImageFormats.BC1_SRGB: return TEX_FORMAT.BC1_UNORM_SRGB; + case Gx2ImageFormats.BC1_UNORM: return TEX_FORMAT.BC1_UNORM; + case Gx2ImageFormats.BC2_UNORM: return TEX_FORMAT.BC2_UNORM; + case Gx2ImageFormats.BC2_SRGB: return TEX_FORMAT.BC2_UNORM_SRGB; + case Gx2ImageFormats.BC3_UNORM: return TEX_FORMAT.BC3_UNORM; + case Gx2ImageFormats.BC4_UNORM: return TEX_FORMAT.BC4_UNORM; + case Gx2ImageFormats.BC5_UNORM: return TEX_FORMAT.BC5_UNORM; + case Gx2ImageFormats.LA4_UNORM: return TEX_FORMAT.R4G4_UNORM; + case Gx2ImageFormats.LA8_UNORM: return TEX_FORMAT.R8G8_UNORM; + case Gx2ImageFormats.RGB565_UNORM: return TEX_FORMAT.B5G6R5_UNORM; + case Gx2ImageFormats.RGB5A1_UNORM: return TEX_FORMAT.B5G5R5A1_UNORM; + case Gx2ImageFormats.RGB8_UNORM: return TEX_FORMAT.R8G8_UNORM; + case Gx2ImageFormats.RGBA8_SRGB: return TEX_FORMAT.R8G8B8A8_UNORM_SRGB; + case Gx2ImageFormats.RGBA8_UNORM: return TEX_FORMAT.R8G8B8A8_UNORM; + default: + throw new NotImplementedException("Unsupported format " + Format); + } + } + + public override void SetImageData(Bitmap bitmap, int ArrayLevel) + { + throw new NotImplementedException("Cannot set image data! Operation not implemented!"); + } + + public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0) + { + uint bpp = GetBytesPerPixel(Format); + + GX2.GX2Surface surf = new GX2.GX2Surface(); + surf.bpp = bpp; + surf.height = Height; + surf.width = Width; + surf.aa = (uint)GX2.GX2AAMode.GX2_AA_MODE_1X; + surf.alignment = 0; + surf.depth = 1; + surf.dim = (uint)GX2.GX2SurfaceDimension.DIM_2D; + surf.format = (uint)Bfres.Structs.FTEX.ConvertToGx2Format(Format); + surf.use = (uint)GX2.GX2SurfaceUse.USE_COLOR_BUFFER; + surf.pitch = 0; + surf.data = TextureFINF.tglp.SheetDataList[ArrayLevel]; + surf.numMips = 1; + surf.mipOffset = new uint[0]; + surf.mipData = null; + surf.tileMode = (uint)GX2.GX2TileMode.MODE_2D_TILED_THIN1; + surf.swizzle = 0; + surf.numArray = 1; + + var surfaces = GX2.Decode(surf); + + return surfaces[ArrayLevel][MipLevel]; + } + + public override void OnClick(TreeView treeview) + { + UpdateEditor(); + } + + private void UpdateEditor() + { + ImageEditorBase editor = (ImageEditorBase)LibraryGUI.Instance.GetActiveContent(typeof(ImageEditorBase)); + if (editor == null) + { + editor = new ImageEditorBase(); + editor.Dock = DockStyle.Fill; + LibraryGUI.Instance.LoadEditor(editor); + } + + Properties prop = new Properties(); + prop.Width = Width; + prop.Height = Height; + prop.Depth = Depth; + prop.MipCount = MipCount; + prop.ArrayCount = ArrayCount; + prop.ImageSize = (uint)TextureFINF.tglp.SheetDataList[0].Length; + prop.Format = Format; + + editor.Text = Text; + editor.LoadProperties(prop); + editor.LoadImage(this); + } + } + + public class BFFNT_Block + { + + } + + public class FINF : BFFNT_Block { public uint Size; public uint Type; @@ -208,6 +403,7 @@ namespace FirstPlugin { for (int i = 0; i < SheetCount; i++) { + } SheetDataList.Add(reader.ReadBytes((int)SheetSize * SheetCount)); } diff --git a/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj b/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj index f65ca62f..e01d2879 100644 --- a/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj +++ b/Switch_FileFormatsMain/Switch_FileFormatsMain.csproj @@ -58,7 +58,6 @@ False ..\Toolbox\Lib\BcresLibrary.dll - False ..\Toolbox\Lib\BezelEngineArchive_Lib.dll @@ -209,6 +208,8 @@ + + diff --git a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache index 48399a3d..c56ab2d0 100644 Binary files a/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache and b/Switch_FileFormatsMain/obj/Release/DesignTimeResolveAssemblyReferences.cache differ diff --git a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csproj.CoreCompileInputs.cache b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csproj.CoreCompileInputs.cache index fa359e84..4337029b 100644 --- a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csproj.CoreCompileInputs.cache +++ b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -4d5e73277106e1aec8f32776e14883abfe56435f +6a0ed70e297938eacb07b25b8680e0a366c6a29f diff --git a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache index 0e028d71..a2cbf527 100644 Binary files a/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache and b/Switch_FileFormatsMain/obj/Release/Switch_FileFormatsMain.csprojAssemblyReference.cache differ diff --git a/Toolbox/Lib/BcresLibrary.dll b/Toolbox/Lib/BcresLibrary.dll index 6f17b5e9..c8f1314e 100644 Binary files a/Toolbox/Lib/BcresLibrary.dll and b/Toolbox/Lib/BcresLibrary.dll differ diff --git a/Toolbox/Lib/BcresLibrary.pdb b/Toolbox/Lib/BcresLibrary.pdb index e647958e..04fe8df6 100644 Binary files a/Toolbox/Lib/BcresLibrary.pdb and b/Toolbox/Lib/BcresLibrary.pdb differ