diff --git a/File_Format_Library/FileFormats/Archives/U8.cs b/File_Format_Library/FileFormats/Archives/U8.cs index 50bac6a0..88bbf79e 100644 --- a/File_Format_Library/FileFormats/Archives/U8.cs +++ b/File_Format_Library/FileFormats/Archives/U8.cs @@ -121,19 +121,24 @@ namespace FirstPlugin for (int i = 0; i < dirs.Length; i++) dirs[i] = new DirectoryEntry(); - DirectoryEntry currentDir = dirs[0]; + DirectoryEntry currentDir = dirs[1]; + nodes.Add(currentDir); + //Skip root so start index at 1 + int dirIndex = 1; for (int i = 0; i < TotalNodeCount; i++) { var node = entries[i]; - Console.WriteLine($"node " + node.Name + " " + node.nodeType); + if (node.Name == string.Empty) + continue; + if (node.nodeType == NodeEntry.NodeType.Directory) { - DirectoryEntry dir = new DirectoryEntry(); - dir.Name = node.Name; - dir.nodeEntry = node; - dirs[node.Setting1].AddNode(dir); - currentDir = dir; + dirs[i].Name = node.Name; + dirs[i].nodeEntry = node; + dirs[node.Setting1].AddNode(dirs[i]); + + currentDir = dirs[i]; } else { @@ -147,8 +152,6 @@ namespace FirstPlugin entry.FileData = reader.ReadBytes((int)entry.nodeEntry.Setting2); } } - - nodes.Add(currentDir); } } diff --git a/File_Format_Library/FileFormats/Layout/Rev/BRLYT.cs b/File_Format_Library/FileFormats/Layout/Rev/BRLYT.cs new file mode 100644 index 00000000..fa3fb239 --- /dev/null +++ b/File_Format_Library/FileFormats/Layout/Rev/BRLYT.cs @@ -0,0 +1,1125 @@ +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 BRLYT : IFileFormat, IEditorForm, IConvertableTextFormat + { + public FileType FileType { get; set; } = FileType.Layout; + + public bool CanSave { get; set; } + public string[] Description { get; set; } = new string[] { "Revolution Layout (GUI)" }; + public string[] Extension { get; set; } = new string[] { "*.brlyt" }; + 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, "RLYT"); + } + } + + 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) == ".brlyt") + { + BRLYT brlyt = (BRLYT)file.OpenFile(); + animations.Add(brlyt); + } + } + } + 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 = "RLYT"; + + private ushort ByteOrderMark; + public ushort Version; + 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 ((BRLYT)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, BRLYT brlyt) + { + LayoutInfo = new LYT1(); + TextureList = new TXL1(); + MaterialList = new MAT1(); + FontList = new FNL1(); + RootPane = new PAN1(); + RootGroup = new GRP1(); + + FileInfo = brlyt; + + reader.SetByteOrder(true); + reader.ReadSignature(4, Magic); + ByteOrderMark = reader.ReadUInt16(); + reader.CheckByteOrderMark(ByteOrderMark); + Version = reader.ReadUInt16(); + uint FileSize = reader.ReadUInt32(); + HeaderSize = reader.ReadUInt16(); + 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) + { + writer.WriteSignature(Magic); + writer.Write(ByteOrderMark); + writer.Write(HeaderSize); + 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) + { + 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 BRLYT.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, BRLYT.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 bool IsWideScreen + { + get { return (_flags1 & 0x4) == 0x4; } + } + + 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 OriginType : byte + { + Left = 0, + Top = 0, + Center = 1, + Right = 2, + Bottom = 2 + }; + + public override OriginX originX + { + get + { + var bclytOriginX = (OriginType)(Origin % 3); + if (bclytOriginX == OriginType.Center) + return OriginX.Center; + else if (bclytOriginX == OriginType.Left) + return OriginX.Left; + else + return OriginX.Right; + } + } + + public override OriginY originY + { + get + { + var bclytOriginY = (OriginType)(Origin / 3); + if (bclytOriginY == OriginType.Center) + return OriginY.Center; + else if (bclytOriginY == OriginType.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(0x10).Replace("\0", string.Empty); + UserDataInfo = reader.ReadString(0x8).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, 0x10); + writer.WriteString(UserDataInfo, 0x8); + 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 STColor16 ForeColor { get; set; } + public STColor16 BackColor { get; set; } + public STColor16 ColorRegister3 { get; set; } + + public STColor8 TevColor1 { get; set; } + public STColor8 TevColor2 { get; set; } + public STColor8 TevColor3 { get; set; } + public STColor8 TevColor4 { get; set; } + + public List TextureMaps { get; set; } + public List TextureTransforms { get; set; } + + private uint flags; + private int unknown; + + private BRLYT.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(0x14).Replace("\0", string.Empty); + + ForeColor = reader.ReadColor16RGBA(); + BackColor = reader.ReadColor16RGBA(); + ColorRegister3 = reader.ReadColor16RGBA(); + TevColor1 = reader.ReadColor8RGBA(); + TevColor2 = reader.ReadColor8RGBA(); + TevColor3 = reader.ReadColor8RGBA(); + TevColor4 = reader.ReadColor8RGBA(); + 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(ForeColor); + // writer.Write(BackColor); + 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/Texture/WTB.cs b/File_Format_Library/FileFormats/Texture/WTB.cs index 01bebaec..830da375 100644 --- a/File_Format_Library/FileFormats/Texture/WTB.cs +++ b/File_Format_Library/FileFormats/Texture/WTB.cs @@ -71,6 +71,8 @@ namespace FirstPlugin uint unk2Table = reader.ReadUInt32(); uint textureInfoTable = reader.ReadUInt32(); + bool UseExternalBinary = true; + List entries = new List(); for (int i = 0; i < numTextures; i++) { @@ -80,6 +82,9 @@ namespace FirstPlugin reader.SeekBegin(dataOffsetTable + (i * 4)); tex.DataOffset = reader.ReadUInt32(); + if (i == 0 && tex.DataOffset != 0) + UseExternalBinary = false; + //Get data size reader.SeekBegin(dataSizeTable + (i * 4)); tex.DataSize = reader.ReadUInt32(); @@ -91,18 +96,29 @@ namespace FirstPlugin Nodes.Add(new TextureWrapper(tex) { Text = $"Texture {i}" }); } - string fileData = FilePath.Replace("wta", "wtp"); - if (System.IO.File.Exists(fileData)) + if (UseExternalBinary) { - using (var readerData = new FileReader(fileData)) + string fileData = FilePath.Replace("wta", "wtp"); + if (System.IO.File.Exists(fileData)) { - for (int i = 0; i < numTextures; i++) + using (var readerData = new FileReader(fileData)) { - readerData.SeekBegin(entries[i].DataOffset); - entries[i].ImageData = readerData.ReadBytes((int)entries[i].DataSize); + for (int i = 0; i < numTextures; i++) + { + readerData.SeekBegin(entries[i].DataOffset); + entries[i].ImageData = readerData.ReadBytes((int)entries[i].DataSize); + } } } } + else + { + for (int i = 0; i < numTextures; i++) + { + reader.SeekBegin(entries[i].DataOffset); + entries[i].ImageData = reader.ReadBytes((int)entries[i].DataSize); + } + } } } @@ -221,6 +237,8 @@ namespace FirstPlugin public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0) { + Console.WriteLine($" Texture.ImageData " + Texture.ImageData.Length); + return TegraX1Swizzle.GetImageData(this, Texture.ImageData, ArrayLevel, MipLevel, 1); } diff --git a/File_Format_Library/File_Format_Library.csproj b/File_Format_Library/File_Format_Library.csproj index b4da90b1..c1bddd40 100644 --- a/File_Format_Library/File_Format_Library.csproj +++ b/File_Format_Library/File_Format_Library.csproj @@ -297,6 +297,7 @@ + diff --git a/File_Format_Library/GUI/BFLYT/LayoutEditor.cs b/File_Format_Library/GUI/BFLYT/LayoutEditor.cs index 18361ee2..1fbc4f3b 100644 --- a/File_Format_Library/GUI/BFLYT/LayoutEditor.cs +++ b/File_Format_Library/GUI/BFLYT/LayoutEditor.cs @@ -292,6 +292,8 @@ namespace LayoutBXLYT LoadBxlyt(((BFLYT)file).header, file.FileName); else if (file is BCLYT) LoadBxlyt(((BCLYT)file).header, file.FileName); + else if (file is BRLYT) + LoadBxlyt(((BRLYT)file).header, file.FileName); else if (file is IArchiveFile) { var layouts = SearchLayoutFiles((IArchiveFile)file); @@ -307,6 +309,8 @@ namespace LayoutBXLYT LoadBxlyt(((BFLYT)layout).header, file.FileName); if (layout is BCLYT) LoadBxlyt(((BCLYT)layout).header, file.FileName); + if (layout is BRLYT) + LoadBxlyt(((BRLYT)layout).header, file.FileName); } } } @@ -316,6 +320,8 @@ namespace LayoutBXLYT LoadBxlyt(((BFLYT)layouts[0]).header, file.FileName); if (layouts[0] is BCLYT) LoadBxlyt(((BCLYT)layouts[0]).header, file.FileName); + if (layouts[0] is BRLYT) + LoadBxlyt(((BRLYT)layouts[0]).header, file.FileName); } } else if (file is BFLAN) @@ -335,7 +341,7 @@ namespace LayoutBXLYT foreach (var file in archiveFile.Files) { var fileFormat = STFileLoader.OpenFileFormat(file.FileName, - new Type[] { typeof(BFLYT), typeof(BCLYT), typeof(SARC) }, file.FileData); + new Type[] { typeof(BFLYT), typeof(BCLYT), typeof(BRLYT), typeof(SARC) }, file.FileData); if (fileFormat is BFLYT) { @@ -405,6 +411,7 @@ namespace LayoutBXLYT if (ActiveLayout.FileInfo is BFLYT) { TextConverter = new LayoutTextDocked(); + TextConverter.Text = "Text Converter"; 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 2dd7f1e0..62bfb74e 100644 --- a/File_Format_Library/GUI/BFLYT/LayoutHierarchy.cs +++ b/File_Format_Library/GUI/BFLYT/LayoutHierarchy.cs @@ -62,11 +62,14 @@ namespace LayoutBXLYT string imageKey = ""; 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 BRLYT.WND1) imageKey = "WindowPane"; + else if (pane is BFLYT.PIC1) imageKey = "PicturePane"; else if (pane is BCLYT.PIC1) imageKey = "PicturePane"; + else if (pane is BRLYT.PIC1) imageKey = "PicturePane"; + else if (pane is BFLYT.BND1) imageKey = "BoundryPane"; + else if (pane is BCLYT.BND1) imageKey = "BoundryPane"; + else if (pane is BRLYT.BND1) imageKey = "BoundryPane"; else imageKey = "NullPane"; paneNode.ImageKey = imageKey; diff --git a/File_Format_Library/GUI/BFLYT/LayoutViewer.cs b/File_Format_Library/GUI/BFLYT/LayoutViewer.cs index 6af516c7..1e0216b2 100644 --- a/File_Format_Library/GUI/BFLYT/LayoutViewer.cs +++ b/File_Format_Library/GUI/BFLYT/LayoutViewer.cs @@ -124,11 +124,15 @@ namespace LayoutBXLYT if (pane is BFLYT.PIC1) DrawPicturePane((BFLYT.PIC1)pane); else if (pane is BCLYT.PIC1) - DrawDefaultPane((BCLYT.PIC1)pane); + DrawPicturePane((BCLYT.PIC1)pane); + else if (pane is BRLYT.PIC1) + DrawPicturePane((BRLYT.PIC1)pane); else if (pane is BFLYT.PAN1) DrawDefaultPane((BFLYT.PAN1)pane); else if (pane is BCLYT.PAN1) DrawDefaultPane((BCLYT.PAN1)pane); + else if (pane is BRLYT.PAN1) + DrawDefaultPane((BRLYT.PAN1)pane); } else isRoot = false; @@ -199,7 +203,6 @@ namespace LayoutBXLYT DrawRectangle(pane.CreateRectangle(), TexCoords, Colors); } - int texId = 1; private void DrawPicturePane(BCLYT.PIC1 pane) { Vector2[] TexCoords = new Vector2[] { @@ -239,6 +242,46 @@ namespace LayoutBXLYT GL.BindTexture(TextureTarget.Texture2D, 0); } + private void DrawPicturePane(BRLYT.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, + }; + + 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]); + GL.BindTexture(TextureTarget.Texture2D, RenderTools.uvTestPattern.RenderableTex.TexID); + + 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[] { diff --git a/File_Format_Library/Main.cs b/File_Format_Library/Main.cs index 2a4e795b..3f302d6d 100644 --- a/File_Format_Library/Main.cs +++ b/File_Format_Library/Main.cs @@ -368,6 +368,7 @@ namespace FirstPlugin Formats.Add(typeof(G1T)); Formats.Add(typeof(LayoutBXLYT.BFLYT)); Formats.Add(typeof(LayoutBXLYT.BCLYT)); + Formats.Add(typeof(LayoutBXLYT.BRLYT)); Formats.Add(typeof(ZSI)); Formats.Add(typeof(IGZ_TEX)); Formats.Add(typeof(MOD)); diff --git a/Switch_Toolbox_Library/FileFormats/ASTC/ASTCDecoder.cs b/Switch_Toolbox_Library/FileFormats/ASTC/ASTCDecoder.cs index c05cfbd3..fddf5db5 100644 --- a/Switch_Toolbox_Library/FileFormats/ASTC/ASTCDecoder.cs +++ b/Switch_Toolbox_Library/FileFormats/ASTC/ASTCDecoder.cs @@ -124,8 +124,8 @@ namespace Ryujinx.Graphics.Gal.Texture throw new ASTCDecoderException("Invalid block mode"); } - Console.WriteLine($"BlockWidth {BlockWidth} {BlockHeight} BlockHeight"); - Console.WriteLine($"TexelParams {TexelParams.Width} X {TexelParams.Height}"); + // Console.WriteLine($"BlockWidth {BlockWidth} {BlockHeight} BlockHeight"); + // Console.WriteLine($"TexelParams {TexelParams.Width} X {TexelParams.Height}"); if (TexelParams.VoidExtentLDR) { diff --git a/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs b/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs index 92965213..c67aa50c 100644 --- a/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs +++ b/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.cs @@ -599,6 +599,8 @@ namespace Toolbox.Library.Forms private void treeViewCustom1_DragEnter(object sender, DragEventArgs e) { + if (!Runtime.EnableDragDrop) return; + if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.All; else @@ -615,14 +617,32 @@ namespace Toolbox.Library.Forms if (node is ArchiveFileWrapper) { + treeViewCustom1.DoDragDrop("dummy", DragDropEffects.Copy); + } + else if (node is ArchiveFolderNodeWrapper || node is ArchiveRootNodeWrapper) + { + treeViewCustom1.DoDragDrop("dummy", DragDropEffects.Copy); + } + } + + private void DropFileOutsideApplication(TreeNode node) + { + if (node is ArchiveFileWrapper) + { + Runtime.EnableDragDrop = false; + string fullPath = Write2TempAndGetFullPath(((ArchiveFileWrapper)node).ArchiveFileInfo); DataObject dragObj = new DataObject(); dragObj.SetFileDropList(new System.Collections.Specialized.StringCollection() { fullPath }); treeViewCustom1.DoDragDrop(dragObj, DragDropEffects.Copy); + + Runtime.EnableDragDrop = true; } else if (node is ArchiveFolderNodeWrapper || node is ArchiveRootNodeWrapper) { + Runtime.EnableDragDrop = false; + string[] fullPaths = Write2TempAndGetFullPath(node); DataObject dragObj = new DataObject(); @@ -630,6 +650,8 @@ namespace Toolbox.Library.Forms collection.AddRange(fullPaths); dragObj.SetFileDropList(collection); treeViewCustom1.DoDragDrop(dragObj, DragDropEffects.Copy); + + Runtime.EnableDragDrop = true; } } @@ -670,39 +692,52 @@ namespace Toolbox.Library.Forms private void treeViewCustom1_DragDrop(object sender, DragEventArgs e) { - Point pt = treeViewCustom1.PointToClient(new Point(e.X, e.Y)); - var node = treeViewCustom1.GetNodeAt(pt.X, pt.Y); + if (!Runtime.EnableDragDrop) return; - if (node != null) + Console.WriteLine("test"); + + if (e.Effect == DragDropEffects.Copy) { - treeViewCustom1.SelectedNode = node; + Console.WriteLine("drop"); - bool IsRoot = node is ArchiveRootNodeWrapper; - bool IsFolder = node is ArchiveFolderNodeWrapper; - bool IsFile = node is ArchiveFileWrapper && node.Parent != null; - - if (IsRoot || IsFolder || IsFile) - { - var archiveFile = GetActiveArchive(); - - //Use the parent folder for files if it has any - if (IsFile) - TreeHelper.AddFiles(treeViewCustom1.SelectedNode.Parent, archiveFile, e.Data.GetData(DataFormats.FileDrop) as string[]); - else - TreeHelper.AddFiles(treeViewCustom1.SelectedNode, archiveFile, e.Data.GetData(DataFormats.FileDrop) as string[]); - } + DropFileOutsideApplication(treeViewCustom1.SelectedNode); } - else + else if (e.Effect == DragDropEffects.All) { - Cursor.Current = Cursors.WaitCursor; + Point pt = treeViewCustom1.PointToClient(new Point(e.X, e.Y)); + var node = treeViewCustom1.GetNodeAt(pt.X, pt.Y); - string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); - foreach (string filename in files) + if (node != null) { - ((IMainForm)Runtime.MainForm).OpenFile(filename, Runtime.ObjectEditor.OpenModelsOnOpen); - } + treeViewCustom1.SelectedNode = node; - Cursor.Current = Cursors.Default; + bool IsRoot = node is ArchiveRootNodeWrapper; + bool IsFolder = node is ArchiveFolderNodeWrapper; + bool IsFile = node is ArchiveFileWrapper && node.Parent != null; + + if (IsRoot || IsFolder || IsFile) + { + var archiveFile = GetActiveArchive(); + + //Use the parent folder for files if it has any + if (IsFile) + TreeHelper.AddFiles(treeViewCustom1.SelectedNode.Parent, archiveFile, e.Data.GetData(DataFormats.FileDrop) as string[]); + else + TreeHelper.AddFiles(treeViewCustom1.SelectedNode, archiveFile, e.Data.GetData(DataFormats.FileDrop) as string[]); + } + } + else + { + Cursor.Current = Cursors.WaitCursor; + + string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); + foreach (string filename in files) + { + ((IMainForm)Runtime.MainForm).OpenFile(filename, Runtime.ObjectEditor.OpenModelsOnOpen); + } + + Cursor.Current = Cursors.Default; + } } } diff --git a/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.resx b/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.resx index b3ccea75..22477dcd 100644 --- a/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.resx +++ b/Switch_Toolbox_Library/Forms/Editors/Object Editor/ObjectEditorTree.resx @@ -123,6 +123,9 @@ 17, 17 + + 17, 17 + 166, 17 diff --git a/Switch_Toolbox_Library/IO/STColor.cs b/Switch_Toolbox_Library/IO/Colors/STColor.cs similarity index 100% rename from Switch_Toolbox_Library/IO/STColor.cs rename to Switch_Toolbox_Library/IO/Colors/STColor.cs diff --git a/Switch_Toolbox_Library/IO/Colors/STColor16.cs b/Switch_Toolbox_Library/IO/Colors/STColor16.cs new file mode 100644 index 00000000..68374381 --- /dev/null +++ b/Switch_Toolbox_Library/IO/Colors/STColor16.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Drawing; + +namespace Toolbox.Library +{ + //Class that contains colors and useful color related methods + public class STColor16 + { + public ushort R { get; set; } + public ushort G { get; set; } + public ushort B { get; set; } + public ushort A { get; set; } + + public Color Color + { + get + { + return Color.FromArgb(A, R, G, B); + } + set + { + var color = value; + R = color.R; + G = color.G; + B = color.B; + A = color.A; + } + } + + public static STColor16 FromShorts(ushort[] color) + { + STColor16 col = new STColor16(); + col.R = color[0]; + col.G = color[1]; + col.B = color[2]; + col.A = color[3]; + return col; + } + + public STColor16() + { + R = 255; + G = 255; + B = 255; + A = 255; + } + + public STColor16(ushort r, ushort g, ushort b, ushort a) + { + R = r; + G = g; + B = b; + A = a; + } + + public override string ToString() + { + return String.Format("R:{0} G:{1} B:{2} A:{3}", R, G, B, A); + } + + public string ToHexString() + { + return String.Format("R:{0:X2} G:{1:X2} B:{2:X2} A:{3:X2}", R, G, B, A); + } + + public static STColor8 White + { + get { return new STColor8(255, 255, 255, 255); } + } + } +} diff --git a/Switch_Toolbox_Library/IO/STColor8.cs b/Switch_Toolbox_Library/IO/Colors/STColor8.cs similarity index 100% rename from Switch_Toolbox_Library/IO/STColor8.cs rename to Switch_Toolbox_Library/IO/Colors/STColor8.cs diff --git a/Switch_Toolbox_Library/IO/FileReader.cs b/Switch_Toolbox_Library/IO/FileReader.cs index 39400644..29869101 100644 --- a/Switch_Toolbox_Library/IO/FileReader.cs +++ b/Switch_Toolbox_Library/IO/FileReader.cs @@ -296,6 +296,20 @@ namespace Toolbox.Library.IO return STColor8.FromBytes(ReadBytes(4)); } + public STColor16[] ReadColor16sRGBA(int count) + { + STColor16[] colors = new STColor16[count]; + for (int i = 0; i < count; i++) + colors[i] = STColor16.FromShorts(ReadUInt16s(4)); + + return colors; + } + + public STColor16 ReadColor16RGBA() + { + return STColor16.FromShorts(ReadUInt16s(4)); + } + public STColor[] ReadColorsRGBA(int count) { STColor[] colors = new STColor[count]; diff --git a/Switch_Toolbox_Library/Runtime.cs b/Switch_Toolbox_Library/Runtime.cs index 8558dab3..eb6d09e6 100644 --- a/Switch_Toolbox_Library/Runtime.cs +++ b/Switch_Toolbox_Library/Runtime.cs @@ -18,6 +18,8 @@ namespace Toolbox.Library //Disable loading 3k and higher texture res to prevent slowdown and memory issues public static bool DisableLoadingGLHighResTextures = true; + public static bool EnableDragDrop = true; + public static bool UseSingleInstance = true; public static bool UseDirectXTexDecoder = true; public static bool DEVELOPER_DEBUG_MODE = false; diff --git a/Switch_Toolbox_Library/Texture Decoding/Switch/TegraX1Swizzle.cs b/Switch_Toolbox_Library/Texture Decoding/Switch/TegraX1Swizzle.cs index d740d36d..3d3643f8 100644 --- a/Switch_Toolbox_Library/Texture Decoding/Switch/TegraX1Swizzle.cs +++ b/Switch_Toolbox_Library/Texture Decoding/Switch/TegraX1Swizzle.cs @@ -68,7 +68,7 @@ namespace Toolbox.Library return MipMapSizes; } - public static byte[] GetImageData(STGenericTexture texture, byte[] ImageData, int ArrayLevel, int MipLevel, int target = 1) + public static byte[] GetImageData(STGenericTexture texture, byte[] ImageData, int ArrayLevel, int MipLevel, int target = 1, bool LinearTileMode = false) { uint bpp = STGenericTexture.GetBytesPerPixel(texture.Format); uint blkWidth = STGenericTexture.GetBlockWidth(texture.Format); @@ -81,6 +81,8 @@ namespace Toolbox.Library uint Pitch = 0; uint DataAlignment = 512; uint TileMode = 0; + if (LinearTileMode) + TileMode = 1; int linesPerBlockHeight = (1 << (int)BlockHeightLog2) * 8; @@ -100,6 +102,8 @@ namespace Toolbox.Library uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp; + Console.WriteLine($"size " + size); + if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight) blockHeightShift += 1; @@ -122,7 +126,6 @@ namespace Toolbox.Library Pitch = TegraX1Swizzle.round_up(width__ * bpp, 64); SurfaceSize += Pitch * TegraX1Swizzle.round_up(height__, Math.Max(1, blockHeight >> blockHeightShift) * 8); - Console.WriteLine($"{width} {height} {blkWidth} {blkHeight} {target} {bpp} {TileMode} {(int)Math.Max(0, BlockHeightLog2 - blockHeightShift)} {data_.Length}"); byte[] result = TegraX1Swizzle.deswizzle(width, height, depth, blkWidth, blkHeight, blkDepth, target, bpp, TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), data_); //Create a copy and use that to remove uneeded data byte[] result_ = new byte[size]; diff --git a/Switch_Toolbox_Library/Toolbox_Library.csproj b/Switch_Toolbox_Library/Toolbox_Library.csproj index 696e6939..f812f3e6 100644 --- a/Switch_Toolbox_Library/Toolbox_Library.csproj +++ b/Switch_Toolbox_Library/Toolbox_Library.csproj @@ -300,14 +300,15 @@ + - - + + diff --git a/Toolbox/MainForm.cs b/Toolbox/MainForm.cs index 8849857e..ca66176c 100644 --- a/Toolbox/MainForm.cs +++ b/Toolbox/MainForm.cs @@ -980,6 +980,8 @@ namespace Toolbox private void MainForm_DragEnter(object sender, DragEventArgs e) { + if (!Runtime.EnableDragDrop) return; + if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.All; else @@ -991,6 +993,8 @@ namespace Toolbox private void MainForm_DragDrop(object sender, DragEventArgs e) { + if (!Runtime.EnableDragDrop) return; + Cursor.Current = Cursors.WaitCursor; string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);