From e4cb00c2376ffb3b9484e126e1450a8d4d808be4 Mon Sep 17 00:00:00 2001 From: KillzXGaming Date: Fri, 30 Aug 2019 18:53:45 -0400 Subject: [PATCH] Add BCLYT support. Some ram usage optmization for bflyt editor --- .../FileFormats/Effects/PCTL.cs | 3 + .../FileFormats/Layout/{ => CAFE}/BFLAN.cs | 0 .../FileFormats/Layout/{ => CAFE}/BFLYT.cs | 127 +- .../FileFormats/Layout/CAFE/FLYT.cs | 18 + .../FileFormats/Layout/CTR/BCLYT.cs | 1121 +++++++++++++++++ .../FileFormats/Layout/Common.cs | 22 +- .../FileFormats/Texture/BNTX.cs | 2 +- .../File_Format_Library.csproj | 20 +- File_Format_Library/GUI/BFLYT/FileSelector.cs | 8 +- .../GUI/BFLYT/LayoutEditor.Designer.cs | 28 +- File_Format_Library/GUI/BFLYT/LayoutEditor.cs | 53 +- .../GUI/BFLYT/LayoutHierarchy.cs | 9 +- .../GUI/BFLYT/LayoutProperties.Designer.cs | 24 +- .../GUI/BFLYT/LayoutProperties.cs | 35 +- .../GUI/BFLYT/LayoutTextDocked.Designer.cs | 37 + .../GUI/BFLYT/LayoutTextDocked.cs | 36 + File_Format_Library/GUI/BFLYT/LayoutViewer.cs | 78 +- File_Format_Library/Main.cs | 1 + .../Custom/FlatTabControl/FlatTabControl.cs | 12 - Switch_Toolbox_Library/IO/FileReader.cs | 29 + Switch_Toolbox_Library/IO/FileWriter.cs | 6 + Switch_Toolbox_Library/IO/STColor.cs | 9 + Switch_Toolbox_Library/IO/STFileLoader.cs | 25 + 23 files changed, 1605 insertions(+), 98 deletions(-) rename File_Format_Library/FileFormats/Layout/{ => CAFE}/BFLAN.cs (100%) rename File_Format_Library/FileFormats/Layout/{ => CAFE}/BFLYT.cs (89%) create mode 100644 File_Format_Library/FileFormats/Layout/CAFE/FLYT.cs create mode 100644 File_Format_Library/FileFormats/Layout/CTR/BCLYT.cs create mode 100644 File_Format_Library/GUI/BFLYT/LayoutTextDocked.Designer.cs create mode 100644 File_Format_Library/GUI/BFLYT/LayoutTextDocked.cs diff --git a/File_Format_Library/FileFormats/Effects/PCTL.cs b/File_Format_Library/FileFormats/Effects/PCTL.cs index 48ab10ee..2015e4f3 100644 --- a/File_Format_Library/FileFormats/Effects/PCTL.cs +++ b/File_Format_Library/FileFormats/Effects/PCTL.cs @@ -148,6 +148,8 @@ namespace FirstPlugin //For saving public List Sections = new List(); + private string UnknownString; + public void Read(FileReader reader, PTCL ptcl) { uint Position = (uint)reader.Position; //Offsets are relative to this @@ -174,6 +176,7 @@ namespace FirstPlugin BlockOffset = reader.ReadUInt16(); uint padding2 = reader.ReadUInt32(); uint FileSize = reader.ReadUInt32(); + reader.Seek(Position + BlockOffset, SeekOrigin.Begin); } else diff --git a/File_Format_Library/FileFormats/Layout/BFLAN.cs b/File_Format_Library/FileFormats/Layout/CAFE/BFLAN.cs similarity index 100% rename from File_Format_Library/FileFormats/Layout/BFLAN.cs rename to File_Format_Library/FileFormats/Layout/CAFE/BFLAN.cs diff --git a/File_Format_Library/FileFormats/Layout/BFLYT.cs b/File_Format_Library/FileFormats/Layout/CAFE/BFLYT.cs similarity index 89% rename from File_Format_Library/FileFormats/Layout/BFLYT.cs rename to File_Format_Library/FileFormats/Layout/CAFE/BFLYT.cs index a1e4bbe4..d3f03127 100644 --- a/File_Format_Library/FileFormats/Layout/BFLYT.cs +++ b/File_Format_Library/FileFormats/Layout/CAFE/BFLYT.cs @@ -85,6 +85,8 @@ namespace LayoutBXLYT serializerSettings.ComparerForKeySorting = null; serializerSettings.RegisterTagMapping("Header", typeof(Header)); + return FLYT.ToXml(header); + var serializer = new Serializer(serializerSettings); string yaml = serializer.Serialize(header, typeof(Header)); return yaml; @@ -100,18 +102,18 @@ namespace LayoutBXLYT { LayoutEditor editor = new LayoutEditor(); editor.Dock = DockStyle.Fill; - editor.LoadBflyt(header, FileName); + editor.LoadBxlyt(header, FileName); return editor; } public void FillEditor(Form control) { - ((LayoutEditor)control).LoadBflyt(header, FileName); + ((LayoutEditor)control).LoadBxlyt(header, FileName); } public Header header; public void Load(System.IO.Stream stream) { - CanSave = false; + CanSave = true; header = new Header(); header.Read(new FileReader(stream), this); @@ -195,12 +197,14 @@ namespace LayoutBXLYT if (Utils.GetExtension(file.FileName) == ".bntx") { BNTX bntx = (BNTX)file.OpenFile(); + file.FileFormat = bntx; foreach (var tex in bntx.Textures) textures.Add(tex.Key, tex.Value); } else if (Utils.GetExtension(file.FileName) == ".bflim") { BFLIM bflim = (BFLIM)file.OpenFile(); + file.FileFormat = bflim; textures.Add(bflim.FileName, bflim); } } @@ -222,11 +226,6 @@ namespace LayoutBXLYT //https://github.com/FuryBaguette/SwitchLayoutEditor/tree/master/SwitchThemesCommon public class Header : BxlytHeader, IDisposable { - public string FileName - { - get { return FileInfo.FileName; } - } - private const string Magic = "FLYT"; private ushort ByteOrderMark; @@ -239,6 +238,13 @@ namespace LayoutBXLYT // private List Sections; // public List Panes = new List(); + public int TotalPaneCount() + { + int panes = GetPanes().Count; + int grpPanes = GetGroupPanes().Count; + return panes + grpPanes; + } + public override List Textures { get { return TextureList.Textures; } @@ -249,6 +255,34 @@ namespace LayoutBXLYT get { return ((BFLYT)FileInfo).GetTextures(); } } + public List GetPanes() + { + List panes = new List(); + GetPaneChildren(panes, (PAN1)RootPane); + return panes; + } + + public List GetGroupPanes() + { + List panes = new List(); + GetGroupChildren(panes, (GRP1)RootGroup); + return panes; + } + + private void GetPaneChildren(List panes, PAN1 root) + { + panes.Add(root); + foreach (var pane in root.Childern) + GetPaneChildren(panes, (PAN1)pane); + } + + private void GetGroupChildren(List panes, GRP1 root) + { + panes.Add(root); + foreach (var pane in root.Childern) + GetGroupChildren(panes, (GRP1)pane); + } + public void Read(FileReader reader, BFLYT bflyt) { LayoutInfo = new LYT1(); @@ -276,6 +310,9 @@ namespace LayoutBXLYT BasePane currentPane = null; BasePane parentPane = null; + BasePane currentGroupPane = null; + BasePane parentGroupPane = null; + reader.SeekBegin(HeaderSize); for (int i = 0; i < sectionCount; i++) { @@ -358,10 +395,16 @@ namespace LayoutBXLYT setGroupRoot = true; } + SetPane(groupPanel, parentGroupPane); + currentGroupPane = groupPanel; break; case "grs1": + if (currentGroupPane != null) + parentGroupPane = currentGroupPane; break; case "gre1": + currentGroupPane = parentGroupPane; + parentGroupPane = currentGroupPane.Parent; break; case "usd1": break; @@ -430,6 +473,8 @@ namespace LayoutBXLYT } + public string Text { get; set; } + public OriginX HorizontalAlignment { get { return (OriginX)((TextAlignment >> 2) & 0x3); } @@ -515,10 +560,17 @@ namespace LayoutBXLYT ShadowForeColor = STColor8.FromBytes(reader.ReadBytes(4)); ShadowBackColor = STColor8.FromBytes(reader.ReadBytes(4)); ShadowItalic = reader.ReadSingle(); + + if (RestrictedTextLengthEnabled) + Text = reader.ReadString(MaxTextLength); + else + Text = reader.ReadString(TextLength); } public override void Write(FileWriter writer, BxlytHeader header) { + long pos = writer.Position; + base.Write(writer, header); writer.Write(TextLength); writer.Write(MaxTextLength); @@ -529,6 +581,7 @@ namespace LayoutBXLYT writer.Write(_flags); writer.Seek(1); writer.Write(ItalicTilt); + long _ofsTextPos = writer.Position; writer.Write(0); //text offset writer.Write(FontForeColor.ToBytes()); writer.Write(FontBackColor.ToBytes()); @@ -540,6 +593,12 @@ namespace LayoutBXLYT writer.Write(ShadowForeColor.ToBytes()); writer.Write(ShadowBackColor.ToBytes()); writer.Write(ShadowItalic); + + writer.WriteUint32Offset(_ofsTextPos, pos); + if (RestrictedTextLengthEnabled) + writer.WriteString(Text, MaxTextLength); + else + writer.WriteString(Text, TextLength); } public enum BorderType : byte @@ -565,14 +624,60 @@ namespace LayoutBXLYT } + public ushort StretchLeft; + public ushort StretchRight; + public ushort StretchTop; + public ushort StretchBottm; + public ushort FrameElementLeft; + public ushort FrameElementRight; + public ushort FrameElementTop; + public ushort FrameElementBottm; + public byte FrameCount; + private byte _flag; + public WND1(FileReader reader) : base(reader) { + long pos = reader.Position; + + StretchLeft = reader.ReadUInt16(); + StretchRight = reader.ReadUInt16(); + StretchTop = reader.ReadUInt16(); + StretchBottm = reader.ReadUInt16(); + FrameElementLeft = reader.ReadUInt16(); + FrameElementRight = reader.ReadUInt16(); + FrameElementTop = reader.ReadUInt16(); + FrameElementBottm = reader.ReadUInt16(); + FrameCount = reader.ReadByte(); + _flag = reader.ReadByte(); + reader.ReadUInt16();//padding + uint contentOffset = reader.ReadUInt32(); + uint frameOffsetTbl = reader.ReadUInt32(); } public override void Write(FileWriter writer, BxlytHeader header) { + long pos = writer.Position; + base.Write(writer, header); + writer.Write(StretchLeft); + writer.Write(StretchRight); + writer.Write(StretchTop); + writer.Write(StretchBottm); + writer.Write(FrameElementLeft); + writer.Write(FrameElementRight); + writer.Write(FrameElementTop); + writer.Write(FrameElementBottm); + writer.Write(FrameCount); + writer.Write(_flag); + writer.Seek(2); + + long _ofsContentPos = writer.Position; + writer.Write(0); + writer.Write(0); + + writer.WriteUint32Offset(_ofsContentPos, pos); + } } @@ -799,7 +904,7 @@ namespace LayoutBXLYT } public byte Alpha { get; set; } - public byte Unknown { get; set; } + public byte PaneMagFlags { get; set; } public string UserDataInfo { get; set; } @@ -813,7 +918,7 @@ namespace LayoutBXLYT _flags1 = reader.ReadByte(); _flags2 = reader.ReadByte(); Alpha = reader.ReadByte(); - Unknown = reader.ReadByte(); + PaneMagFlags = reader.ReadByte(); Name = reader.ReadString(0x18).Replace("\0", string.Empty); UserDataInfo = reader.ReadString(0x8).Replace("\0", string.Empty); Translate = reader.ReadVec3SY(); @@ -828,7 +933,7 @@ namespace LayoutBXLYT writer.Write(_flags1); writer.Write(_flags2); writer.Write(Alpha); - writer.Write(Unknown); + writer.Write(PaneMagFlags); writer.WriteString(Name, 0x18); writer.WriteString(UserDataInfo, 0x8); writer.Write(Translate); diff --git a/File_Format_Library/FileFormats/Layout/CAFE/FLYT.cs b/File_Format_Library/FileFormats/Layout/CAFE/FLYT.cs new file mode 100644 index 00000000..5633464e --- /dev/null +++ b/File_Format_Library/FileFormats/Layout/CAFE/FLYT.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using System.Xml; +using System.Xml.Serialization; + +namespace LayoutBXLYT +{ + public class FLYT + { + public static string ToXml(BFLYT.Header header) + { + return ""; + } + } +} diff --git a/File_Format_Library/FileFormats/Layout/CTR/BCLYT.cs b/File_Format_Library/FileFormats/Layout/CTR/BCLYT.cs new file mode 100644 index 00000000..d6560b27 --- /dev/null +++ b/File_Format_Library/FileFormats/Layout/CTR/BCLYT.cs @@ -0,0 +1,1121 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Toolbox; +using System.Windows.Forms; +using Toolbox.Library; +using Toolbox.Library.Forms; +using Toolbox.Library.IO; +using FirstPlugin.Forms; +using Syroot.Maths; +using SharpYaml.Serialization; +using FirstPlugin; + +namespace LayoutBXLYT +{ + public class BCLYT : IFileFormat, IEditorForm, IConvertableTextFormat + { + public FileType FileType { get; set; } = FileType.Layout; + + public bool CanSave { get; set; } + public string[] Description { get; set; } = new string[] { "CTR Layout (GUI)" }; + public string[] Extension { get; set; } = new string[] { "*.bclyt" }; + public string FileName { get; set; } + public string FilePath { get; set; } + public IFileInfo IFileInfo { get; set; } + + public bool Identify(System.IO.Stream stream) + { + using (var reader = new Toolbox.Library.IO.FileReader(stream, true)) + { + return reader.CheckSignature(4, "CLYT"); + } + } + + public Type[] Types + { + get + { + List types = new List(); + return types.ToArray(); + } + } + + #region Text Converter Interface + public TextFileType TextFileType => TextFileType.Xml; + public bool CanConvertBack => false; + + public string ConvertToString() + { + var serializerSettings = new SerializerSettings() + { + // EmitTags = false + }; + + serializerSettings.DefaultStyle = SharpYaml.YamlStyle.Any; + serializerSettings.ComparerForKeySorting = null; + serializerSettings.RegisterTagMapping("Header", typeof(Header)); + + var serializer = new Serializer(serializerSettings); + string yaml = serializer.Serialize(header, typeof(Header)); + return yaml; + } + + public void ConvertFromString(string text) + { + } + + #endregion + + public LayoutEditor OpenForm() + { + LayoutEditor editor = new LayoutEditor(); + editor.Dock = DockStyle.Fill; + editor.LoadBxlyt(header, FileName); + return editor; + } + + public void FillEditor(Form control) { + ((LayoutEditor)control).LoadBxlyt(header, FileName); + } + + public Header header; + public void Load(System.IO.Stream stream) + { + CanSave = true; + + header = new Header(); + header.Read(new FileReader(stream), this); + } + + public List GetLayouts() + { + List animations = new List(); + if (IFileInfo.ArchiveParent != null) + { + foreach (var file in IFileInfo.ArchiveParent.Files) + { + if (Utils.GetExtension(file.FileName) == ".bclyt") + { + BCLYT bclyt = (BCLYT)file.OpenFile(); + animations.Add(bclyt); + } + } + } + return animations; + } + + public Dictionary GetTextures() + { + Dictionary textures = new Dictionary(); + if (IFileInfo.ArchiveParent != null) + { + foreach (var file in IFileInfo.ArchiveParent.Files) + { + if (Utils.GetExtension(file.FileName) == ".bclim") + { + BCLIM bclim = (BCLIM)file.OpenFile(); + file.FileFormat = bclim; + textures.Add(bclim.FileName, bclim); + } + } + } + + return textures; + } + + public void Unload() + { + + } + + public void Save(System.IO.Stream stream) { + header.Write(new FileWriter(stream)); + } + + //Thanks to SwitchThemes for flags, and enums + //https://github.com/FuryBaguette/SwitchLayoutEditor/tree/master/SwitchThemesCommon + public class Header : BxlytHeader, IDisposable + { + public string FileName + { + get { return FileInfo.FileName; } + } + + private const string Magic = "CLYT"; + + private ushort ByteOrderMark; + private ushort HeaderSize; + + public LYT1 LayoutInfo { get; set; } + public TXL1 TextureList { get; set; } + public MAT1 MaterialList { get; set; } + public FNL1 FontList { get; set; } + // private List Sections; + // public List Panes = new List(); + + public int TotalPaneCount() + { + int panes = GetPanes().Count; + int grpPanes = GetGroupPanes().Count; + return panes + grpPanes; + } + + public override List Textures + { + get { return TextureList.Textures; } + } + + public override Dictionary GetTextures + { + get { return ((BCLYT)FileInfo).GetTextures(); } + } + + public List GetPanes() + { + List panes = new List(); + GetPaneChildren(panes, (PAN1)RootPane); + return panes; + } + + public List GetGroupPanes() + { + List panes = new List(); + GetGroupChildren(panes, (GRP1)RootGroup); + return panes; + } + + private void GetPaneChildren(List panes, PAN1 root) + { + panes.Add(root); + foreach (var pane in root.Childern) + GetPaneChildren(panes, (PAN1)pane); + } + + private void GetGroupChildren(List panes, GRP1 root) + { + panes.Add(root); + foreach (var pane in root.Childern) + GetGroupChildren(panes, (GRP1)pane); + } + + public void Read(FileReader reader, BCLYT bclyt) + { + LayoutInfo = new LYT1(); + TextureList = new TXL1(); + MaterialList = new MAT1(); + FontList = new FNL1(); + RootPane = new PAN1(); + RootGroup = new GRP1(); + + FileInfo = bclyt; + + reader.SetByteOrder(true); + reader.ReadSignature(4, Magic); + ByteOrderMark = reader.ReadUInt16(); + reader.CheckByteOrderMark(ByteOrderMark); + HeaderSize = reader.ReadUInt16(); + Version = reader.ReadUInt32(); + uint FileSize = reader.ReadUInt32(); + ushort sectionCount = reader.ReadUInt16(); + reader.ReadUInt16(); //Padding + + bool setRoot = false; + bool setGroupRoot = false; + + BasePane currentPane = null; + BasePane parentPane = null; + + BasePane currentGroupPane = null; + BasePane parentGroupPane = null; + + reader.SeekBegin(HeaderSize); + for (int i = 0; i < sectionCount; i++) + { + long pos = reader.Position; + + string Signature = reader.ReadString(4, Encoding.ASCII); + uint SectionSize = reader.ReadUInt32(); + + SectionCommon section = new SectionCommon(); + switch (Signature) + { + case "lyt1": + LayoutInfo = new LYT1(reader); + break; + case "txl1": + TextureList = new TXL1(reader); + break; + case "fnl1": + FontList = new FNL1(reader); + break; + case "mat1": + MaterialList = new MAT1(reader, this); + break; + case "pan1": + var panel = new PAN1(reader); + if (!setRoot) + { + RootPane = panel; + setRoot = true; + } + + SetPane(panel, parentPane); + currentPane = panel; + break; + case "pic1": + var picturePanel = new PIC1(reader, this); + + SetPane(picturePanel, parentPane); + currentPane = picturePanel; + break; + case "txt1": + var textPanel = new TXT1(reader); + + SetPane(textPanel, parentPane); + currentPane = textPanel; + break; + case "bnd1": + var boundsPanel = new BND1(reader); + + SetPane(boundsPanel, parentPane); + currentPane = boundsPanel; + break; + case "prt1": + var partsPanel = new PRT1(reader); + + SetPane(partsPanel, parentPane); + currentPane = partsPanel; + break; + case "wnd1": + var windowPanel = new WND1(reader); + SetPane(windowPanel, parentPane); + currentPane = windowPanel; + break; + case "cnt1": + break; + case "pas1": + if (currentPane != null) + parentPane = currentPane; + break; + case "pae1": + currentPane = parentPane; + parentPane = currentPane.Parent; + break; + case "grp1": + var groupPanel = new GRP1(reader, this); + + if (!setGroupRoot) + { + RootGroup = groupPanel; + setGroupRoot = true; + } + + SetPane(groupPanel, parentGroupPane); + currentGroupPane = groupPanel; + break; + case "grs1": + if (currentGroupPane != null) + parentGroupPane = currentGroupPane; + break; + case "gre1": + currentGroupPane = parentGroupPane; + parentGroupPane = currentGroupPane.Parent; + break; + case "usd1": + break; + //If the section is not supported store the raw bytes + default: + section.Data = reader.ReadBytes((int)SectionSize); + break; + } + + section.Signature = Signature; + section.SectionSize = SectionSize; + + reader.SeekBegin(pos + SectionSize); + } + } + + private void SetPane(BasePane pane, BasePane parentPane) + { + if (parentPane != null) + { + parentPane.Childern.Add(pane); + pane.Parent = parentPane; + } + } + + public void Write(FileWriter writer) + { + Version = VersionMajor << 24 | VersionMinor << 16 | VersionMicro << 8 | VersionMicro2; + + writer.WriteSignature(Magic); + writer.Write(ByteOrderMark); + writer.Write(HeaderSize); + writer.Write(Version); + writer.Write(uint.MaxValue); //Reserve space for file size later + writer.Write(ushort.MaxValue); //Reserve space for section count later + writer.Seek(2); //padding + + //Write the total file size + using (writer.TemporarySeek(0x0C, System.IO.SeekOrigin.Begin)) + { + writer.Write((uint)writer.BaseStream.Length); + } + } + } + + public class TexCoord + { + public Vector2F TopLeft { get; set; } + public Vector2F TopRight { get; set; } + public Vector2F BottomLeft { get; set; } + public Vector2F BottomRight { get; set; } + + public TexCoord() + { + TopLeft = new Vector2F(0, 0); + TopRight = new Vector2F(1, 0); + BottomLeft = new Vector2F(0, 1); + BottomRight = new Vector2F(1, 1); + } + } + + public class TXT1 : PAN1 + { + public TXT1() : base() + { + + } + + public string Text { get; set; } + + public OriginX HorizontalAlignment + { + get { return (OriginX)((TextAlignment >> 2) & 0x3); } + set + { + TextAlignment &= unchecked((byte)(~0xC)); + TextAlignment |= (byte)((byte)(value) << 2); + } + } + + public OriginX VerticalAlignment + { + get { return (OriginX)((TextAlignment) & 0x3); } + set + { + TextAlignment &= unchecked((byte)(~0x3)); + TextAlignment |= (byte)(value); + } + } + + public ushort TextLength { get; set; } + public ushort MaxTextLength { get; set; } + public ushort MaterialIndex { get; set; } + public ushort FontIndex { get; set; } + + public byte TextAlignment { get; set; } + public LineAlign LineAlignment { get; set; } + + public float ItalicTilt { get; set; } + + public STColor8 FontForeColor { get; set; } + public STColor8 FontBackColor { get; set; } + public Vector2F FontSize { get; set; } + + public float CharacterSpace { get; set; } + public float LineSpace { get; set; } + + public Vector2F ShadowXY { get; set; } + public Vector2F ShadowXYSize { get; set; } + + public STColor8 ShadowForeColor { get; set; } + public STColor8 ShadowBackColor { get; set; } + + public float ShadowItalic { get; set; } + + public bool PerCharTransform + { + get { return (_flags & 0x10) != 0; } + set { _flags = value ? (byte)(_flags | 0x10) : unchecked((byte)(_flags & (~0x10))); } + } + public bool RestrictedTextLengthEnabled + { + get { return (_flags & 0x2) != 0; } + set { _flags = value ? (byte)(_flags | 0x2) : unchecked((byte)(_flags & (~0x2))); } + } + public bool ShadowEnabled + { + get { return (_flags & 1) != 0; } + set { _flags = value ? (byte)(_flags | 1) : unchecked((byte)(_flags & (~1))); } + } + + private byte _flags; + + public TXT1(FileReader reader) : base(reader) + { + TextLength = reader.ReadUInt16(); + MaxTextLength = reader.ReadUInt16(); + MaterialIndex = reader.ReadUInt16(); + FontIndex = reader.ReadUInt16(); + TextAlignment = reader.ReadByte(); + LineAlignment = (LineAlign)reader.ReadByte(); + _flags = reader.ReadByte(); + reader.Seek(1); //padding + ItalicTilt = reader.ReadSingle(); + uint textOffset = reader.ReadUInt32(); + FontForeColor = STColor8.FromBytes(reader.ReadBytes(4)); + FontBackColor = STColor8.FromBytes(reader.ReadBytes(4)); + FontSize = reader.ReadVec2SY(); + CharacterSpace = reader.ReadSingle(); + LineSpace = reader.ReadSingle(); + ShadowXY = reader.ReadVec2SY(); + ShadowXYSize = reader.ReadVec2SY(); + ShadowForeColor = STColor8.FromBytes(reader.ReadBytes(4)); + ShadowBackColor = STColor8.FromBytes(reader.ReadBytes(4)); + ShadowItalic = reader.ReadSingle(); + + if (RestrictedTextLengthEnabled) + Text = reader.ReadString(MaxTextLength); + else + Text = reader.ReadString(TextLength); + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + long pos = writer.Position; + + base.Write(writer, header); + writer.Write(TextLength); + writer.Write(MaxTextLength); + writer.Write(MaterialIndex); + writer.Write(FontIndex); + writer.Write(TextAlignment); + writer.Write(LineAlignment, false); + writer.Write(_flags); + writer.Seek(1); + writer.Write(ItalicTilt); + long _ofsTextPos = writer.Position; + writer.Write(0); //text offset + writer.Write(FontForeColor.ToBytes()); + writer.Write(FontBackColor.ToBytes()); + writer.Write(FontSize); + writer.Write(CharacterSpace); + writer.Write(LineSpace); + writer.Write(ShadowXY); + writer.Write(ShadowXYSize); + writer.Write(ShadowForeColor.ToBytes()); + writer.Write(ShadowBackColor.ToBytes()); + writer.Write(ShadowItalic); + + writer.WriteUint32Offset(_ofsTextPos, pos); + if (RestrictedTextLengthEnabled) + writer.WriteString(Text, MaxTextLength); + else + writer.WriteString(Text, TextLength); + } + + public enum BorderType : byte + { + Standard = 0, + DeleteBorder = 1, + RenderTwoCycles = 2, + }; + + public enum LineAlign : byte + { + Unspecified = 0, + Left = 1, + Center = 2, + Right = 3, + }; + } + + public class WND1 : PAN1 + { + public WND1() : base() + { + + } + + public WND1(FileReader reader) : base(reader) + { + + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + base.Write(writer, header); + } + } + + public class BND1 : PAN1 + { + public BND1() : base() + { + + } + + public BND1(FileReader reader) : base(reader) + { + + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + base.Write(writer, header); + } + } + + public class GRP1 : BasePane + { + public List Panes { get; set; } = new List(); + + public GRP1() : base() + { + + } + + public GRP1(FileReader reader, Header header) + { + Name = reader.ReadString(0x10).Replace("\0", string.Empty); + ushort numNodes = reader.ReadUInt16(); + reader.ReadUInt16();//padding + + for (int i = 0; i < numNodes; i++) + Panes.Add(reader.ReadString(0x10)); + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + if (header.Version >= 0x05020000) + { + writer.WriteString(Name, 34); + writer.Write((ushort)Panes.Count); + } + else + { + writer.WriteString(Name, 24); + writer.Write((ushort)Panes.Count); + writer.Seek(2); + } + + for (int i = 0; i < Panes.Count; i++) + writer.WriteString(Panes[i], 24); + } + } + + public class PRT1 : PAN1 + { + public PRT1() : base() + { + + } + + public PRT1(FileReader reader) : base(reader) + { + + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + base.Write(writer, header); + } + } + + public class PIC1 : PAN1 + { + public TexCoord[] TexCoords { get; set; } + + public STColor8 ColorTopLeft { get; set; } + public STColor8 ColorTopRight { get; set; } + public STColor8 ColorBottomLeft { get; set; } + public STColor8 ColorBottomRight { get; set; } + + public ushort MaterialIndex { get; set; } + + public Material GetMaterial() + { + return ParentLayout.MaterialList.Materials[MaterialIndex]; + } + + public string GetTexture(int index) + { + var mat = GetMaterial(); + return ParentLayout.TextureList.Textures[mat.TextureMaps[index].ID]; + } + + private BCLYT.Header ParentLayout; + + public PIC1() : base() { + ColorTopLeft = STColor8.White; + ColorTopRight = STColor8.White; + ColorBottomLeft = STColor8.White; + ColorBottomRight = STColor8.White; + MaterialIndex = 0; + TexCoords = new TexCoord[1]; + TexCoords[0] = new TexCoord(); + } + + public PIC1(FileReader reader, BCLYT.Header header) : base(reader) + { + ParentLayout = header; + + ColorTopLeft = STColor8.FromBytes(reader.ReadBytes(4)); + ColorTopRight = STColor8.FromBytes(reader.ReadBytes(4)); + ColorBottomLeft = STColor8.FromBytes(reader.ReadBytes(4)); + ColorBottomRight = STColor8.FromBytes(reader.ReadBytes(4)); + MaterialIndex = reader.ReadUInt16(); + byte numUVs = reader.ReadByte(); + reader.Seek(1); //padding + + TexCoords = new TexCoord[numUVs]; + for (int i = 0; i < numUVs; i++) + { + TexCoords[i] = new TexCoord() + { + TopLeft = reader.ReadVec2SY(), + TopRight = reader.ReadVec2SY(), + BottomLeft = reader.ReadVec2SY(), + BottomRight = reader.ReadVec2SY(), + }; + } + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + base.Write(writer, header); + writer.Write(ColorTopLeft.ToBytes()); + writer.Write(ColorTopRight.ToBytes()); + writer.Write(ColorBottomLeft.ToBytes()); + writer.Write(ColorBottomRight.ToBytes()); + writer.Write(MaterialIndex); + writer.Write(TexCoords != null ? TexCoords.Length : 0); + } + } + + public class PAN1 : BasePane + { + private byte _flags1; + + public bool Visible + { + get { return (_flags1 & 0x1) == 0x1; } + set { + if (value) + _flags1 |= 0x1; + else + _flags1 &= 0xFE; + } + } + + public bool InfluenceAlpha + { + get { return (_flags1 & 0x2) == 0x2; } + set + { + if (value) + _flags1 |= 0x2; + else + _flags1 &= 0xFD; + } + } + + public byte Origin { get; set; } + + public byte Alpha { get; set; } + + public byte PartsScale { get; set; } + + public byte PaneMagFlags { get; set; } + + public string UserDataInfo { get; set; } + + public PAN1() : base() + { + + } + + enum BCLYTOriginX : byte + { + Left = 0, + Center = 1, + Right = 2 + }; + + enum BCLYTOriginY : byte + { + Top = 0, + Center = 1, + Bottom = 2 + }; + + public override OriginX originX + { + get + { + var bclytOriginX = (BCLYTOriginX)(Origin % 3); + if (bclytOriginX == BCLYTOriginX.Center) + return OriginX.Center; + else if (bclytOriginX == BCLYTOriginX.Left) + return OriginX.Left; + else + return OriginX.Right; + } + } + + public override OriginY originY + { + get + { + var bclytOriginY = (BCLYTOriginY)(Origin / 3); + if (bclytOriginY == BCLYTOriginY.Center) + return OriginY.Center; + else if (bclytOriginY == BCLYTOriginY.Top) + return OriginY.Top; + else + return OriginY.Bottom; + } + } + + public PAN1(FileReader reader) : base() + { + _flags1 = reader.ReadByte(); + Origin = reader.ReadByte(); + Alpha = reader.ReadByte(); + PaneMagFlags = reader.ReadByte(); + Name = reader.ReadString(0x18).Replace("\0", string.Empty); + Translate = reader.ReadVec3SY(); + Rotate = reader.ReadVec3SY(); + Scale = reader.ReadVec2SY(); + Width = reader.ReadSingle(); + Height = reader.ReadSingle(); + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + writer.Write(_flags1); + writer.Write(Alpha); + writer.Write(PaneMagFlags); + writer.WriteString(Name, 0x18); + writer.Write(Translate); + writer.Write(Rotate); + writer.Write(Scale); + writer.Write(Width); + writer.Write(Height); + } + + public bool ParentVisibility + { + get + { + if (Scale.X == 0 || Scale.Y == 0) + return false; + if (!Visible) + return false; + if (Parent != null && Parent is PAN1) + { + return ((PAN1)Parent).ParentVisibility && Visible; + } + return true; + } + } + } + + public class MAT1 : SectionCommon + { + public List Materials { get; set; } + + public MAT1() { + Materials = new List(); + } + + public MAT1(FileReader reader, Header header) : base() + { + Materials = new List(); + + long pos = reader.Position; + + ushort numMats = reader.ReadUInt16(); + reader.Seek(2); //padding + + uint[] offsets = reader.ReadUInt32s(numMats); + for (int i = 0; i < numMats; i++) + { + reader.SeekBegin(pos + offsets[i] - 8); + Materials.Add(new Material(reader, header)); + } + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + writer.Write((ushort)Materials.Count); + writer.Seek(2); + } + } + + public class Material + { + public string Name { get; set; } + + public STColor8 TevColor { get; set; } + public STColor8[] TevConstantColors { get; set; } + + public List TextureMaps { get; set; } + public List TextureTransforms { get; set; } + + private uint flags; + private int unknown; + + private BCLYT.Header ParentLayout; + public string GetTexture(int index) + { + if (TextureMaps[index].ID != -1) + return ParentLayout.TextureList.Textures[TextureMaps[index].ID]; + else + return ""; + } + + public Material() + { + TextureMaps = new List(); + TextureTransforms = new List(); + } + + public Material(FileReader reader, Header header) : base() + { + ParentLayout = header; + + TextureMaps = new List(); + TextureTransforms = new List(); + + Name = reader.ReadString(0x1C).Replace("\0", string.Empty); + TevColor = reader.ReadColor8RGBA(); + TevConstantColors = reader.ReadColor8sRGBA(8); + flags = reader.ReadUInt32(); + + uint texCount = Convert.ToUInt32(flags & 3); + uint mtxCount = Convert.ToUInt32(flags >> 2) & 3; + for (int i = 0; i < texCount; i++) + TextureMaps.Add(new TextureRef(reader)); + + for (int i = 0; i < mtxCount; i++) + TextureTransforms.Add(new TextureTransform(reader)); + } + + public void Write(FileWriter writer, Header header) + { + writer.WriteString(Name, 0x1C); + writer.Write(TevColor); + writer.Write(TevConstantColors); + writer.Write(flags); + + for (int i = 0; i < TextureMaps.Count; i++) + TextureMaps[i].Write(writer); + + for (int i = 0; i < TextureTransforms.Count; i++) + TextureTransforms[i].Write(writer); + } + } + + public class TextureTransform + { + public Vector2F Translate; + public float Rotate; + public Vector2F Scale; + + public TextureTransform() { } + + public TextureTransform(FileReader reader) + { + Translate = reader.ReadVec2SY(); + Rotate = reader.ReadSingle(); + Scale = reader.ReadVec2SY(); + } + + public void Write(FileWriter writer) + { + writer.Write(Translate); + writer.Write(Rotate); + writer.Write(Scale); + } + } + + public class TextureRef + { + public short ID; + byte flag1; + byte flag2; + + public WrapMode WrapModeU + { + get { return (WrapMode)(flag1 & 0x3); } + } + + public WrapMode WrapModeV + { + get { return (WrapMode)(flag2 & 0x3); } + } + + public FilterMode MinFilterMode + { + get { return (FilterMode)((flag1 >> 2) & 0x3); } + } + + public FilterMode MaxFilterMode + { + get { return (FilterMode)((flag2 >> 2) & 0x3); } + } + + public TextureRef() {} + + public TextureRef(FileReader reader) { + ID = reader.ReadInt16(); + flag1 = reader.ReadByte(); + flag2 = reader.ReadByte(); + } + + public void Write(FileWriter writer) + { + writer.Write(ID); + writer.Write(flag1); + writer.Write(flag2); + } + + public enum FilterMode + { + Near = 0, + Linear = 1 + } + + public enum WrapMode + { + Clamp = 0, + Repeat = 1, + Mirror = 2 + } + } + + public class FNL1 : SectionCommon + { + public List Fonts { get; set; } + + public FNL1() + { + Fonts = new List(); + } + + public FNL1(FileReader reader) : base() + { + Fonts = new List(); + + ushort numFonts = reader.ReadUInt16(); + reader.Seek(2); //padding + + long pos = reader.Position; + + uint[] offsets = reader.ReadUInt32s(numFonts); + for (int i = 0; i < offsets.Length; i++) + { + reader.SeekBegin(offsets[i] + pos); + } + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + writer.Write((ushort)Fonts.Count); + writer.Seek(2); + + //Fill empty spaces for offsets later + long pos = writer.Position; + writer.Write(new uint[Fonts.Count]); + + //Save offsets and strings + for (int i = 0; i < Fonts.Count; i++) + { + writer.WriteUint32Offset(pos + (i * 4), pos); + writer.WriteString(Fonts[i]); + } + } + } + + public class TXL1 : SectionCommon + { + public List Textures { get; set; } + + public TXL1() + { + Textures = new List(); + } + + public TXL1(FileReader reader) : base() + { + Textures = new List(); + + ushort numTextures = reader.ReadUInt16(); + reader.Seek(2); //padding + + long pos = reader.Position; + + uint[] offsets = reader.ReadUInt32s(numTextures); + for (int i = 0; i < offsets.Length; i++) + { + reader.SeekBegin(offsets[i] + pos); + Textures.Add(reader.ReadZeroTerminatedString()); + } + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + writer.Write((ushort)Textures.Count); + writer.Seek(2); + + //Fill empty spaces for offsets later + long pos = writer.Position; + writer.Write(new uint[Textures.Count]); + + //Save offsets and strings + for (int i = 0; i < Textures.Count; i++) + { + writer.WriteUint32Offset(pos + (i * 4), pos); + writer.WriteString(Textures[i]); + } + } + } + + public class LYT1 : SectionCommon + { + public bool DrawFromCenter { get; set; } + + public float Width { get; set; } + public float Height { get; set; } + + public LYT1() + { + DrawFromCenter = false; + Width = 0; + Height = 0; + } + + public LYT1(FileReader reader) + { + DrawFromCenter = reader.ReadBoolean(); + reader.Seek(3); //padding + Width = reader.ReadSingle(); + Height = reader.ReadSingle(); + } + + public override void Write(FileWriter writer, BxlytHeader header) + { + writer.Write(DrawFromCenter); + writer.Seek(3); + writer.Write(Width); + writer.Write(Height); + } + } + } +} diff --git a/File_Format_Library/FileFormats/Layout/Common.cs b/File_Format_Library/FileFormats/Layout/Common.cs index 18ee59eb..34f42f07 100644 --- a/File_Format_Library/FileFormats/Layout/Common.cs +++ b/File_Format_Library/FileFormats/Layout/Common.cs @@ -10,11 +10,6 @@ using WeifenLuo.WinFormsUI.Docking; namespace LayoutBXLYT { - public class LayoutDocked : DockContent - { - - } - public class BasePane : SectionCommon { public bool DisplayInEditor { get; set; } = true; @@ -41,6 +36,13 @@ namespace LayoutBXLYT get { return Childern.Count > 0; } } + public BasePane() + { + originX = OriginX.Center; + originY = OriginY.Center; + ParentOriginX = OriginX.Center; + ParentOriginY = OriginY.Center; + } public CustomRectangle CreateRectangle() { @@ -117,6 +119,11 @@ namespace LayoutBXLYT public class BxlytHeader : IDisposable { + public string FileName + { + get { return FileInfo.FileName; } + } + internal IFileFormat FileInfo; public BasePane RootPane { get; set; } @@ -200,4 +207,9 @@ namespace LayoutBXLYT BottomPoint = bottom; } } + + public class LayoutDocked : DockContent + { + + } } diff --git a/File_Format_Library/FileFormats/Texture/BNTX.cs b/File_Format_Library/FileFormats/Texture/BNTX.cs index 9be7f82d..64c30dd1 100644 --- a/File_Format_Library/FileFormats/Texture/BNTX.cs +++ b/File_Format_Library/FileFormats/Texture/BNTX.cs @@ -277,7 +277,7 @@ namespace FirstPlugin { get { - if (Textures.Any(item => item.Value.RenderableTex.GLInitialized == false)) + if (Textures.Any(item => item.Value.RenderableTex == null || item.Value.RenderableTex.GLInitialized == false)) return false; else return true; diff --git a/File_Format_Library/File_Format_Library.csproj b/File_Format_Library/File_Format_Library.csproj index a0079805..c6552e61 100644 --- a/File_Format_Library/File_Format_Library.csproj +++ b/File_Format_Library/File_Format_Library.csproj @@ -293,6 +293,8 @@ + + @@ -322,25 +324,31 @@ FileSelector.cs - UserControl + Form LayoutHierarchy.cs - UserControl + Form LayoutProperties.cs + + Form + + + LayoutTextDocked.cs + - UserControl + Form LayoutTextureList.cs - UserControl + Form LayoutViewer.cs @@ -388,8 +396,8 @@ - - + + diff --git a/File_Format_Library/GUI/BFLYT/FileSelector.cs b/File_Format_Library/GUI/BFLYT/FileSelector.cs index 0aeb55a5..591e4d76 100644 --- a/File_Format_Library/GUI/BFLYT/FileSelector.cs +++ b/File_Format_Library/GUI/BFLYT/FileSelector.cs @@ -24,18 +24,18 @@ namespace LayoutBXLYT listViewCustom1.MultiSelect = true; } - public List SelectedLayouts() + public List SelectedLayouts() { - List layouts = new List(); + List layouts = new List(); foreach (ListViewItem item in listViewCustom1.SelectedItems) - layouts.Add((BFLYT)item.Tag); + layouts.Add((IFileFormat)item.Tag); listViewCustom1.Items.Clear(); return layouts; } - public void LoadLayoutFiles(List layoutFiles) + public void LoadLayoutFiles(List layoutFiles) { listViewCustom1.BeginUpdate(); foreach (var file in layoutFiles) diff --git a/File_Format_Library/GUI/BFLYT/LayoutEditor.Designer.cs b/File_Format_Library/GUI/BFLYT/LayoutEditor.Designer.cs index 3e29eea4..cba865c7 100644 --- a/File_Format_Library/GUI/BFLYT/LayoutEditor.Designer.cs +++ b/File_Format_Library/GUI/BFLYT/LayoutEditor.Designer.cs @@ -36,11 +36,12 @@ this.toolStripButton1 = new System.Windows.Forms.ToolStripButton(); this.stMenuStrip1 = new Toolbox.Library.Forms.STMenuStrip(); this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.clearWorkspaceToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.textureListToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); - this.openToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.textConverterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); ((System.ComponentModel.ISupportInitialize)(this.backColorDisplay)).BeginInit(); this.stToolStrip1.SuspendLayout(); this.stMenuStrip1.SuspendLayout(); @@ -118,10 +119,17 @@ this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); this.fileToolStripMenuItem.Text = "File"; // + // openToolStripMenuItem + // + this.openToolStripMenuItem.Name = "openToolStripMenuItem"; + this.openToolStripMenuItem.Size = new System.Drawing.Size(127, 22); + this.openToolStripMenuItem.Text = "Open"; + this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); + // // clearWorkspaceToolStripMenuItem // this.clearWorkspaceToolStripMenuItem.Name = "clearWorkspaceToolStripMenuItem"; - this.clearWorkspaceToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.clearWorkspaceToolStripMenuItem.Size = new System.Drawing.Size(127, 22); this.clearWorkspaceToolStripMenuItem.Text = "Clear Files"; this.clearWorkspaceToolStripMenuItem.Click += new System.EventHandler(this.clearWorkspaceToolStripMenuItem_Click); // @@ -134,7 +142,8 @@ // viewToolStripMenuItem // this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { - this.textureListToolStripMenuItem}); + this.textureListToolStripMenuItem, + this.textConverterToolStripMenuItem}); this.viewToolStripMenuItem.Name = "viewToolStripMenuItem"; this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20); this.viewToolStripMenuItem.Text = "View"; @@ -142,16 +151,16 @@ // textureListToolStripMenuItem // this.textureListToolStripMenuItem.Name = "textureListToolStripMenuItem"; - this.textureListToolStripMenuItem.Size = new System.Drawing.Size(133, 22); + this.textureListToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.textureListToolStripMenuItem.Text = "Texture List"; this.textureListToolStripMenuItem.Click += new System.EventHandler(this.textureListToolStripMenuItem_Click); // - // openToolStripMenuItem + // textConverterToolStripMenuItem // - this.openToolStripMenuItem.Name = "openToolStripMenuItem"; - this.openToolStripMenuItem.Size = new System.Drawing.Size(180, 22); - this.openToolStripMenuItem.Text = "Open"; - this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click); + this.textConverterToolStripMenuItem.Name = "textConverterToolStripMenuItem"; + this.textConverterToolStripMenuItem.Size = new System.Drawing.Size(180, 22); + this.textConverterToolStripMenuItem.Text = "Text Converter"; + this.textConverterToolStripMenuItem.Click += new System.EventHandler(this.textConverterToolStripMenuItem_Click); // // LayoutEditor // @@ -193,5 +202,6 @@ private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem clearWorkspaceToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem openToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem textConverterToolStripMenuItem; } } diff --git a/File_Format_Library/GUI/BFLYT/LayoutEditor.cs b/File_Format_Library/GUI/BFLYT/LayoutEditor.cs index cb269613..18361ee2 100644 --- a/File_Format_Library/GUI/BFLYT/LayoutEditor.cs +++ b/File_Format_Library/GUI/BFLYT/LayoutEditor.cs @@ -18,6 +18,8 @@ namespace LayoutBXLYT { public partial class LayoutEditor : Form { + private Dictionary Textures; + public List LayoutFiles = new List(); private BxlytHeader ActiveLayout; @@ -35,6 +37,8 @@ namespace LayoutBXLYT { InitializeComponent(); + Textures = new Dictionary(); + var theme = new VS2015DarkTheme(); this.dockPanel1.Theme = theme; this.dockPanel1.BackColor = FormThemes.BaseTheme.FormBackColor; @@ -53,14 +57,15 @@ namespace LayoutBXLYT private LayoutHierarchy LayoutHierarchy; private LayoutTextureList LayoutTextureList; private LayoutProperties LayoutProperties; + private LayoutTextDocked TextConverter; private bool isLoaded = false; - public void LoadBflyt(BFLYT.Header header, string fileName) + public void LoadBxlyt(BxlytHeader header, string fileName) { LayoutFiles.Add(header); ActiveLayout = header; - LayoutViewer Viewport = new LayoutViewer(header); + LayoutViewer Viewport = new LayoutViewer(header, Textures); Viewport.Dock = DockStyle.Fill; Viewport.Show(dockPanel1, DockState.Document); Viewport.DockHandler.AllowEndUserDocking = false; @@ -89,6 +94,8 @@ namespace LayoutBXLYT LayoutTextureList.Reset(); if (LayoutProperties != null) LayoutProperties.Reset(); + if (TextConverter != null) + TextConverter.Reset(); } private void ReloadEditors(BxlytHeader activeLayout) @@ -101,6 +108,11 @@ namespace LayoutBXLYT LayoutHierarchy.LoadLayout(activeLayout, ObjectSelected); if (LayoutTextureList != null) LayoutTextureList.LoadTextures(activeLayout); + if (TextConverter != null) + { + if (ActiveLayout.FileInfo is BFLYT) + TextConverter.LoadLayout((BFLYT)ActiveLayout.FileInfo); + } } private void OnObjectChanged(object sender, EventArgs e) @@ -277,7 +289,9 @@ namespace LayoutBXLYT if (file == null) return; if (file is BFLYT) - LoadBflyt(((BFLYT)file).header, file.FileName); + LoadBxlyt(((BFLYT)file).header, file.FileName); + else if (file is BCLYT) + LoadBxlyt(((BCLYT)file).header, file.FileName); else if (file is IArchiveFile) { var layouts = SearchLayoutFiles((IArchiveFile)file); @@ -289,13 +303,19 @@ namespace LayoutBXLYT { foreach (var layout in form.SelectedLayouts()) { - LoadBflyt(layout.header, file.FileName); + if (layout is BFLYT) + LoadBxlyt(((BFLYT)layout).header, file.FileName); + if (layout is BCLYT) + LoadBxlyt(((BCLYT)layout).header, file.FileName); } } } else if (layouts.Count > 0) { - LoadBflyt(layouts[0].header, file.FileName); + if (layouts[0] is BFLYT) + LoadBxlyt(((BFLYT)layouts[0]).header, file.FileName); + if (layouts[0] is BCLYT) + LoadBxlyt(((BCLYT)layouts[0]).header, file.FileName); } } else if (file is BFLAN) @@ -308,19 +328,24 @@ namespace LayoutBXLYT } } - private List SearchLayoutFiles(IArchiveFile archiveFile) + private List SearchLayoutFiles(IArchiveFile archiveFile) { - List layouts = new List(); + List layouts = new List(); foreach (var file in archiveFile.Files) { var fileFormat = STFileLoader.OpenFileFormat(file.FileName, - new Type[] { typeof(BFLYT), typeof(SARC) }, file.FileData); + new Type[] { typeof(BFLYT), typeof(BCLYT), typeof(SARC) }, file.FileData); if (fileFormat is BFLYT) { fileFormat.IFileInfo.ArchiveParent = archiveFile; - layouts.Add((BFLYT)fileFormat); + layouts.Add(fileFormat); + } + else if (fileFormat is BCLYT) + { + fileFormat.IFileInfo.ArchiveParent = archiveFile; + layouts.Add(fileFormat); } else if (Utils.GetExtension(file.FileName) == ".bntx") { @@ -374,5 +399,15 @@ namespace LayoutBXLYT OpenFile(filename); } } + + private void textConverterToolStripMenuItem_Click(object sender, EventArgs e) + { + if (ActiveLayout.FileInfo is BFLYT) + { + TextConverter = new LayoutTextDocked(); + TextConverter.LoadLayout((BFLYT)ActiveLayout.FileInfo); + TextConverter.Show(dockPanel1, DockState.DockLeft); + } + } } } diff --git a/File_Format_Library/GUI/BFLYT/LayoutHierarchy.cs b/File_Format_Library/GUI/BFLYT/LayoutHierarchy.cs index f2fdfe82..2dd7f1e0 100644 --- a/File_Format_Library/GUI/BFLYT/LayoutHierarchy.cs +++ b/File_Format_Library/GUI/BFLYT/LayoutHierarchy.cs @@ -34,15 +34,15 @@ namespace LayoutBXLYT private bool isLoaded = false; private EventHandler OnProperySelected; - public void LoadLayout(BxlytHeader bflyt, EventHandler onPropertySelected) + public void LoadLayout(BxlytHeader bxlyt, EventHandler onPropertySelected) { isLoaded = false; OnProperySelected = onPropertySelected; treeView1.Nodes.Clear(); - LoadPane(bflyt.RootGroup); - LoadPane(bflyt.RootPane); + LoadPane(bxlyt.RootGroup); + LoadPane(bxlyt.RootPane); isLoaded = true; } @@ -64,6 +64,9 @@ namespace LayoutBXLYT if (pane is BFLYT.WND1) imageKey = "WindowPane"; else if (pane is BFLYT.PIC1) imageKey = "PicturePane"; else if (pane is BFLYT.BND1) imageKey = "BoundryPane"; + else if (pane is BCLYT.WND1) imageKey = "WindowPane"; + else if (pane is BCLYT.BND1) imageKey = "BoundryPane"; + else if (pane is BCLYT.PIC1) imageKey = "PicturePane"; else imageKey = "NullPane"; paneNode.ImageKey = imageKey; diff --git a/File_Format_Library/GUI/BFLYT/LayoutProperties.Designer.cs b/File_Format_Library/GUI/BFLYT/LayoutProperties.Designer.cs index 6a4ff039..d0f44043 100644 --- a/File_Format_Library/GUI/BFLYT/LayoutProperties.Designer.cs +++ b/File_Format_Library/GUI/BFLYT/LayoutProperties.Designer.cs @@ -28,32 +28,32 @@ /// private void InitializeComponent() { - this.stTabControl1 = new FlatTabControl.FlatTabControl(); + this.stPropertyGrid1 = new Toolbox.Library.Forms.STPropertyGrid(); this.SuspendLayout(); // - // stTabControl1 + // stPropertyGrid1 // - this.stTabControl1.Dock = System.Windows.Forms.DockStyle.Fill; - this.stTabControl1.Location = new System.Drawing.Point(0, 0); - this.stTabControl1.myBackColor = System.Drawing.Color.Empty; - this.stTabControl1.Name = "stTabControl1"; - this.stTabControl1.SelectedIndex = 0; - this.stTabControl1.Size = new System.Drawing.Size(368, 338); - this.stTabControl1.TabIndex = 0; + this.stPropertyGrid1.AutoScroll = true; + this.stPropertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill; + this.stPropertyGrid1.Location = new System.Drawing.Point(0, 0); + this.stPropertyGrid1.Name = "stPropertyGrid1"; + this.stPropertyGrid1.ShowHintDisplay = true; + this.stPropertyGrid1.Size = new System.Drawing.Size(352, 299); + this.stPropertyGrid1.TabIndex = 0; // // LayoutProperties // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.stTabControl1); + this.ClientSize = new System.Drawing.Size(352, 299); + this.Controls.Add(this.stPropertyGrid1); this.Name = "LayoutProperties"; - this.Size = new System.Drawing.Size(368, 338); this.ResumeLayout(false); } #endregion - private FlatTabControl.FlatTabControl stTabControl1; + private Toolbox.Library.Forms.STPropertyGrid stPropertyGrid1; } } diff --git a/File_Format_Library/GUI/BFLYT/LayoutProperties.cs b/File_Format_Library/GUI/BFLYT/LayoutProperties.cs index 5350c4d4..263595d4 100644 --- a/File_Format_Library/GUI/BFLYT/LayoutProperties.cs +++ b/File_Format_Library/GUI/BFLYT/LayoutProperties.cs @@ -16,37 +16,36 @@ namespace LayoutBXLYT public LayoutProperties() { InitializeComponent(); - - stTabControl1.myBackColor = FormThemes.BaseTheme.FormBackColor; } public void Reset() { - stTabControl1.Controls.Clear(); + stPropertyGrid1.LoadProperty(null); } public void LoadProperties(BasePane prop, Action propChanged) { - stTabControl1.Controls.Clear(); - - if (prop is BFLYT.PIC1) - { - LoadPropertyTab("Pane", prop, propChanged); - LoadPropertyTab("Materials", ((BFLYT.PIC1)prop).GetMaterial(), propChanged); - } - else - LoadPropertyTab("Pane", prop, propChanged); + LoadPropertyTab("Pane", prop, propChanged); } private void LoadPropertyTab(string text, object prop, Action propChanged) { - TabPage page = new TabPage(); + DoubleBufferedTabPage page = new DoubleBufferedTabPage(); + page.Enabled = false; page.Text = text; - var propGrid = new STPropertyGrid(); - propGrid.Dock = DockStyle.Fill; - propGrid.LoadProperty(prop, propChanged); - page.Controls.Add(propGrid); - stTabControl1.Controls.Add(page); + stPropertyGrid1.LoadProperty(prop, propChanged); + } + + class DoubleBufferedTabPage : System.Windows.Forms.TabPage + { + public DoubleBufferedTabPage() + { + this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true); + } + } + + private void stTabControl1_TabIndexChanged(object sender, EventArgs e) + { } } } diff --git a/File_Format_Library/GUI/BFLYT/LayoutTextDocked.Designer.cs b/File_Format_Library/GUI/BFLYT/LayoutTextDocked.Designer.cs new file mode 100644 index 00000000..7ac0d9e0 --- /dev/null +++ b/File_Format_Library/GUI/BFLYT/LayoutTextDocked.Designer.cs @@ -0,0 +1,37 @@ +namespace LayoutBXLYT +{ + partial class LayoutTextDocked + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + } + + #endregion + } +} diff --git a/File_Format_Library/GUI/BFLYT/LayoutTextDocked.cs b/File_Format_Library/GUI/BFLYT/LayoutTextDocked.cs new file mode 100644 index 00000000..c11ca5fb --- /dev/null +++ b/File_Format_Library/GUI/BFLYT/LayoutTextDocked.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Toolbox.Library.Forms; + +namespace LayoutBXLYT +{ + public partial class LayoutTextDocked : LayoutDocked + { + TextEditor editor; + public LayoutTextDocked() + { + InitializeComponent(); + + editor = new TextEditor(); + editor.Dock = DockStyle.Fill; + Controls.Add(editor); + } + + public void Reset() + { + editor.FillEditor(""); + } + + public void LoadLayout(BFLYT bflyt) + { + editor.FillEditor(bflyt.ConvertToString()); + } + } +} diff --git a/File_Format_Library/GUI/BFLYT/LayoutViewer.cs b/File_Format_Library/GUI/BFLYT/LayoutViewer.cs index fbe1cd5a..97b79b93 100644 --- a/File_Format_Library/GUI/BFLYT/LayoutViewer.cs +++ b/File_Format_Library/GUI/BFLYT/LayoutViewer.cs @@ -31,17 +31,22 @@ namespace LayoutBXLYT public BxlytHeader LayoutFile; - private static Dictionary Textures; + private Dictionary Textures; - public LayoutViewer(BFLYT.Header bflyt) + public LayoutViewer(BxlytHeader bxlyt, Dictionary textures) { InitializeComponent(); - LayoutFile = bflyt; - Text = bflyt.FileName; + LayoutFile = bxlyt; + Text = bxlyt.FileName; - Textures = new Dictionary(); - if (bflyt.TextureList.Textures.Count > 0) - Textures = ((BFLYT)bflyt.FileInfo).GetTextures(); + Textures = textures; + if (bxlyt.Textures.Count > 0) + { + if (bxlyt.FileInfo is BFLYT) + Textures = ((BFLYT)bxlyt.FileInfo).GetTextures(); + else if (bxlyt.FileInfo is BCLYT) + Textures = ((BCLYT)bxlyt.FileInfo).GetTextures(); + } } protected override void OnFormClosing(FormClosingEventArgs e) @@ -115,8 +120,12 @@ namespace LayoutBXLYT { if (pane is BFLYT.PIC1) DrawPicturePane((BFLYT.PIC1)pane); + else if (pane is BCLYT.PIC1) + DrawDefaultPane((BCLYT.PIC1)pane); else if (pane is BFLYT.PAN1) DrawDefaultPane((BFLYT.PAN1)pane); + else if (pane is BCLYT.PAN1) + DrawDefaultPane((BCLYT.PAN1)pane); } else isRoot = false; @@ -164,7 +173,7 @@ namespace LayoutBXLYT GL.PopMatrix(); } - private void DrawDefaultPane(BFLYT.PAN1 pane) + private void DrawDefaultPane(BasePane pane) { Vector2[] TexCoords = new Vector2[] { new Vector2(1,1), @@ -187,6 +196,47 @@ namespace LayoutBXLYT DrawRectangle(pane.CreateRectangle(), TexCoords, Colors); } + private void DrawPicturePane(BCLYT.PIC1 pane) + { + Vector2[] TexCoords = new Vector2[] { + new Vector2(1,1), + new Vector2(0,1), + new Vector2(0,0), + new Vector2(1,0) + }; + + Color[] Colors = new Color[] { + pane.ColorTopLeft.Color, + pane.ColorTopRight.Color, + pane.ColorBottomRight.Color, + pane.ColorBottomLeft.Color, + }; + + GL.Enable(EnableCap.Texture2D); + + if (pane.TexCoords.Length > 0) + { + var mat = pane.GetMaterial(); + string textureMap0 = ""; + if (mat.TextureMaps.Count > 0) + textureMap0 = mat.GetTexture(0); + + // if (Textures.ContainsKey(textureMap0)) + // BindGLTexture(mat.TextureMaps[0], Textures[textureMap0]); + + TexCoords = new Vector2[] { + pane.TexCoords[0].TopLeft.ToTKVector2(), + pane.TexCoords[0].TopRight.ToTKVector2(), + pane.TexCoords[0].BottomRight.ToTKVector2(), + pane.TexCoords[0].BottomLeft.ToTKVector2(), + }; + } + + DrawRectangle(pane.CreateRectangle(), TexCoords, Colors, false); + + GL.BindTexture(TextureTarget.Texture2D, 0); + } + private void DrawPicturePane(BFLYT.PIC1 pane) { Vector2[] TexCoords = new Vector2[] { @@ -473,6 +523,18 @@ namespace LayoutBXLYT } } + protected override void OnClosed(EventArgs e) + { + foreach (var tex in LayoutFile.Textures) + { + if (Textures.ContainsKey(tex)) + { + Textures[tex].DisposeRenderable(); + Textures.Remove(tex); + } + } + } + protected override void OnMouseWheel(MouseEventArgs e) { base.OnMouseWheel(e); diff --git a/File_Format_Library/Main.cs b/File_Format_Library/Main.cs index 81764793..de731d14 100644 --- a/File_Format_Library/Main.cs +++ b/File_Format_Library/Main.cs @@ -367,6 +367,7 @@ namespace FirstPlugin Formats.Add(typeof(CMB)); Formats.Add(typeof(G1T)); Formats.Add(typeof(LayoutBXLYT.BFLYT)); + Formats.Add(typeof(LayoutBXLYT.BCLYT)); Formats.Add(typeof(ZSI)); Formats.Add(typeof(IGZ_TEX)); Formats.Add(typeof(MOD)); diff --git a/Switch_Toolbox_Library/Forms/Custom/FlatTabControl/FlatTabControl.cs b/Switch_Toolbox_Library/Forms/Custom/FlatTabControl/FlatTabControl.cs index 4e9710cc..21253e2d 100644 --- a/Switch_Toolbox_Library/Forms/Custom/FlatTabControl/FlatTabControl.cs +++ b/Switch_Toolbox_Library/Forms/Custom/FlatTabControl/FlatTabControl.cs @@ -399,18 +399,6 @@ namespace FlatTabControl private void FlatTabControl_SelectedIndexChanged(object sender, EventArgs e) { - foreach (TabPage tpCheck in TabPages) - { - tpCheck.BackColor = FormThemes.BaseTheme.TabPageInactive; - tpCheck.ForeColor = FormThemes.BaseTheme.DisabledItemColor; - } - - if (SelectedTab != null) - { - SelectedTab.BackColor = FormThemes.BaseTheme.TabPageActive; - SelectedTab.ForeColor = FormThemes.BaseTheme.TextForeColor; - } - UpdateUpDown(); Invalidate(); // we need to update border and background colors } diff --git a/Switch_Toolbox_Library/IO/FileReader.cs b/Switch_Toolbox_Library/IO/FileReader.cs index 7be0f9ea..39400644 100644 --- a/Switch_Toolbox_Library/IO/FileReader.cs +++ b/Switch_Toolbox_Library/IO/FileReader.cs @@ -281,6 +281,35 @@ namespace Toolbox.Library.IO return ReadString(BinaryStringFormat.ZeroTerminated, encoding); } } + + public STColor8[] ReadColor8sRGBA(int count) + { + STColor8[] colors = new STColor8[count]; + for (int i = 0; i < count; i++) + colors[i] = STColor8.FromBytes(ReadBytes(4)); + + return colors; + } + + public STColor8 ReadColor8RGBA() + { + return STColor8.FromBytes(ReadBytes(4)); + } + + public STColor[] ReadColorsRGBA(int count) + { + STColor[] colors = new STColor[count]; + for (int i = 0; i < count; i++) + colors[i] = STColor.FromFloats(ReadSingles(4)); + + return colors; + } + + public STColor ReadColorRGBA() + { + return STColor.FromFloats(ReadSingles(4)); + } + public static byte[] DeflateZLIB(byte[] i) { MemoryStream output = new MemoryStream(); diff --git a/Switch_Toolbox_Library/IO/FileWriter.cs b/Switch_Toolbox_Library/IO/FileWriter.cs index ee5cd0a3..acbc9569 100644 --- a/Switch_Toolbox_Library/IO/FileWriter.cs +++ b/Switch_Toolbox_Library/IO/FileWriter.cs @@ -58,6 +58,12 @@ namespace Toolbox.Library.IO Write(color.ToBytes()); } + public void Write(STColor8[] colors) + { + foreach (var color in colors) + Write(color.ToBytes()); + } + public void WriteStruct(T item) => Write(item.StructToBytes(ByteOrder == ByteOrder.BigEndian)); public void WriteSignature(string value) diff --git a/Switch_Toolbox_Library/IO/STColor.cs b/Switch_Toolbox_Library/IO/STColor.cs index ee7a5a4c..e7993e93 100644 --- a/Switch_Toolbox_Library/IO/STColor.cs +++ b/Switch_Toolbox_Library/IO/STColor.cs @@ -45,7 +45,16 @@ namespace Toolbox.Library col.G = color[1] / 255f; col.B = color[2] / 255f; col.A = color[3] / 255f; + return col; + } + public static STColor FromFloats(float[] color) + { + STColor col = new STColor(); + col.R = color[0]; + col.G = color[1]; + col.B = color[2]; + col.A = color[3]; return col; } diff --git a/Switch_Toolbox_Library/IO/STFileLoader.cs b/Switch_Toolbox_Library/IO/STFileLoader.cs index 95ebb1d8..14819982 100644 --- a/Switch_Toolbox_Library/IO/STFileLoader.cs +++ b/Switch_Toolbox_Library/IO/STFileLoader.cs @@ -31,6 +31,31 @@ namespace Toolbox.Library.IO return null; } + public static Type CheckFileFormatType(string FileName, Type[] FileTypes, byte[] data = null) + { + //Todo. Create a compression list like IFileFormat to decompress via an Identiy method + data = CheckCompression(FileName, data); + + Stream stream; + if (data != null) + stream = new MemoryStream(data); + else + stream = File.OpenRead(FileName); + + foreach (IFileFormat fileFormat in FileManager.GetFileFormats()) + { + fileFormat.FileName = Path.GetFileName(FileName); + + foreach (Type type in FileTypes) + { + if (fileFormat.Identify(stream) && fileFormat.GetType() == type) + return type; + } + } + + return typeof(IFileFormat); + } + public static IFileFormat OpenFileFormat(string FileName, Type[] FileTypes, byte[] data = null) { //Todo. Create a compression list like IFileFormat to decompress via an Identiy method