More improvements.
Rewrote the compression handling from scatch. It's way easier and cleaner to add new formats code wise as it's handled like file formats. Added wip TVOL support (Touhou Azure Reflections) Added XCI support. Note I plan to improve NSP, XCI, NCA, etc later for exefs exporting. The compression rework now compresses via streams, so files get decompressed properly within archives as streams. Added hyrule warriors bin.gz compression along with archive rebuilding. Note i do not have texture rebuilding done just yet.
This commit is contained in:
parent
4d72a725c5
commit
0c126e4155
@ -258,7 +258,7 @@ namespace FirstPlugin
|
||||
{
|
||||
if (entry.IsCompressed)
|
||||
{
|
||||
return STLibraryCompression.ZSTD.Decompress(entry.CompressedData);
|
||||
return Zstb.SDecompress(entry.CompressedData);
|
||||
}
|
||||
else
|
||||
return entry.CompressedData;
|
||||
@ -266,7 +266,7 @@ namespace FirstPlugin
|
||||
public static void SetASST(FileEntry fileEntry, byte[] data)
|
||||
{
|
||||
if (fileEntry.IsCompressed)
|
||||
fileEntry.CompressedData = STLibraryCompression.ZSTD.Compress(data);
|
||||
fileEntry.CompressedData = Zstb.SCompress(data);
|
||||
else
|
||||
fileEntry.CompressedData = data;
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ namespace FirstPlugin
|
||||
get
|
||||
{
|
||||
if (compressedSize != fileSize)
|
||||
return new MemoryStream(STLibraryCompression.ZSTD.Decompress(stream.ToBytes()));
|
||||
return new MemoryStream(Zstb.SDecompress(stream.ToBytes()));
|
||||
else
|
||||
return stream;
|
||||
}
|
||||
|
@ -115,19 +115,21 @@ namespace FirstPlugin
|
||||
else if (compType == 0x30 || compType == 0x20)
|
||||
{
|
||||
uint decompSize = reader.ReadUInt32();
|
||||
uint compSize = (uint)reader.BaseStream.Length - 14;
|
||||
uint compSize = (uint)reader.BaseStream.Length - 16;
|
||||
|
||||
reader.SeekBegin(14);
|
||||
bool IsGZIP = reader.ReadUInt16() == 0x1F8B;
|
||||
reader.SeekBegin(16);
|
||||
ushort signature = reader.ReadUInt16();
|
||||
bool IsGZIP = signature == 0x1F8B;
|
||||
bool IsZLIB = signature == 0x789C || signature == 0x78DA;
|
||||
|
||||
byte[] filedata = reader.getSection(14, (int)compSize);
|
||||
byte[] filedata = reader.getSection(16, (int)compSize);
|
||||
reader.Close();
|
||||
reader.Dispose();
|
||||
|
||||
if (IsGZIP)
|
||||
data = STLibraryCompression.GZIP.Decompress(filedata);
|
||||
else
|
||||
data = STLibraryCompression.ZLIB.Decompress(filedata);
|
||||
else
|
||||
data = STLibraryCompression.ZLIB.Decompress(filedata, false);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
@ -119,7 +119,7 @@ namespace FirstPlugin
|
||||
get
|
||||
{
|
||||
if (compressedSize != fileSize)
|
||||
return new MemoryStream(STLibraryCompression.ZSTD.Decompress(stream.ToBytes()));
|
||||
return new MemoryStream(Zstb.SDecompress(stream.ToBytes()));
|
||||
else
|
||||
return stream;
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ namespace FirstPlugin
|
||||
{
|
||||
byte[] decomp = null;
|
||||
if (magic == 0xDFF25B82 || magic == 0xFD2FB528)
|
||||
decomp = STLibraryCompression.ZSTD.Decompress(CompressedBlock);
|
||||
decomp = Zstb.SDecompress(CompressedBlock);
|
||||
else if (magic == 0x184D2204 || header.Version >= 0x17)
|
||||
decomp = STLibraryCompression.Type_LZ4.Decompress(CompressedBlock, 0, CompressedBlock.Length,(int)header.DecompressedSize);
|
||||
else
|
||||
@ -273,8 +273,8 @@ namespace FirstPlugin
|
||||
public override IFileFormat OpenFile()
|
||||
{
|
||||
byte[] Data = FileData;
|
||||
var FileFormat = STFileLoader.OpenFileFormat(
|
||||
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), Data, true);
|
||||
var FileFormat = STFileLoader.OpenFileFormat(new MemoryStream(Data),
|
||||
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), true);
|
||||
|
||||
if (FileFormat is DDS)
|
||||
((DDS)FileFormat).SwitchSwizzle = IsSwizzled;
|
||||
@ -346,7 +346,7 @@ namespace FirstPlugin
|
||||
else
|
||||
{
|
||||
stream.Seek((int)Offset + CompOffset, SeekOrigin.Begin);
|
||||
Data.Add(STLibraryCompression.ZSTD.Decompress(stream.ReadBytes((int)CompressedSizes[i])));
|
||||
Data.Add(Zstb.SDecompress(stream.ReadBytes((int)CompressedSizes[i])));
|
||||
}
|
||||
DecompOffset += (int)decompSize;
|
||||
CompOffset += (int)CompressedSizes[i];
|
||||
|
@ -1232,14 +1232,14 @@ namespace FirstPlugin
|
||||
|
||||
string Name = resFile.ExternalFileDict.GetKey(index++);
|
||||
|
||||
//Bfsha changes versioons alot so ignore these for now
|
||||
//Bfsha changes versions alot so ignore these for now
|
||||
if (Utils.GetExtension(Name) == ".bfsha")
|
||||
{
|
||||
externalFilesFolder.AddNode(new ExternalFileData(Name, anim.Data));
|
||||
continue;
|
||||
}
|
||||
|
||||
var file = STFileLoader.OpenFileFormat(Name, anim.Data, false, true);
|
||||
var file = STFileLoader.OpenFileFormat(new MemoryStream(anim.Data), Name, false, true);
|
||||
|
||||
//Only do once. There's usually one bntx embedded but incase there are multiple
|
||||
if (file is BNTX && !IsTexturesReplaced)
|
||||
@ -1305,7 +1305,7 @@ namespace FirstPlugin
|
||||
sfd.Filter = Utils.GetAllFilters(formats);
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
STFileSaver.SaveFileFormat(Tex2, true, 0, CompressionType.Yaz0, sfd.FileName);
|
||||
STFileSaver.SaveFileFormat(Tex2, true,new Yaz0(), 0, sfd.FileName);
|
||||
}
|
||||
else
|
||||
STFileSaver.SaveFileFormat(this, FileName);
|
||||
@ -1419,7 +1419,7 @@ namespace FirstPlugin
|
||||
sfd.Filter = Utils.GetAllFilters(formats);
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
STFileSaver.SaveFileFormat(mem2.ToArray(), Compressed, 0, CompressionType.Yaz0, sfd.FileName);
|
||||
STFileSaver.SaveFileFormat(mem2.ToArray(), Compressed,new Yaz0(), 0, sfd.FileName);
|
||||
}
|
||||
private void Rename(object sender, EventArgs args)
|
||||
{
|
||||
|
@ -153,7 +153,7 @@ namespace Bfres.Structs
|
||||
boneAnim.BaseData = baseData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
animation.OpenAnimationData();
|
||||
}
|
||||
|
@ -85,7 +85,8 @@ namespace FirstPlugin
|
||||
|
||||
if (tglp.SheetDataList.Count > 0)
|
||||
{
|
||||
var bntx = STFileLoader.OpenFileFormat("Sheet_0", Utils.CombineByteArray(tglp.SheetDataList.ToArray()));
|
||||
var bntx = STFileLoader.OpenFileFormat(
|
||||
new MemoryStream(Utils.CombineByteArray(tglp.SheetDataList.ToArray())), "Sheet_0");
|
||||
if (bntx != null)
|
||||
{
|
||||
tglp.BinaryTextureFile = (BNTX)bntx;
|
||||
@ -287,6 +288,8 @@ namespace FirstPlugin
|
||||
return Signature;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public BitmapFont GetBitmapFont()
|
||||
{
|
||||
var FontInfo = FontSection;
|
||||
|
@ -1,353 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using Toolbox.Library;
|
||||
using Toolbox.Library.IO;
|
||||
using Toolbox.Library.Forms;
|
||||
using System.Drawing;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class G1T : TreeNodeFile, IFileFormat, IContextMenuNode, ITextureIconLoader
|
||||
{
|
||||
public FileType FileType { get; set; } = FileType.Image;
|
||||
|
||||
public bool CanSave { get; set; }
|
||||
public string[] Description { get; set; } = new string[] { "G1T Textre" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.g1t" };
|
||||
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, "G1TG") || reader.CheckSignature(4, "GT1G");
|
||||
}
|
||||
}
|
||||
|
||||
public Type[] Types
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
return types.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
Read(new FileReader(stream));
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Save(System.IO.Stream stream)
|
||||
{
|
||||
}
|
||||
|
||||
public List<STGenericTexture> IconTextureList
|
||||
{
|
||||
get
|
||||
{
|
||||
List<STGenericTexture> textures = new List<STGenericTexture>();
|
||||
foreach (STGenericTexture node in Nodes)
|
||||
textures.Add(node);
|
||||
|
||||
return textures;
|
||||
}
|
||||
set { }
|
||||
}
|
||||
|
||||
public GT1Platform Platform;
|
||||
|
||||
public enum GT1Platform
|
||||
{
|
||||
PC,
|
||||
WiiU,
|
||||
Switch,
|
||||
}
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
|
||||
Text = FileName;
|
||||
|
||||
long StartPos = reader.Position;
|
||||
string Magic = reader.ReadString(4);
|
||||
|
||||
if (Magic == "GT1G")
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
|
||||
else
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
|
||||
if (Magic == "GT1G")
|
||||
Platform = GT1Platform.Switch;
|
||||
else
|
||||
Platform = GT1Platform.WiiU;
|
||||
|
||||
string Version = reader.ReadString(4);
|
||||
uint FileSize = reader.ReadUInt32();
|
||||
uint DataOffset = reader.ReadUInt32();
|
||||
uint TextureCount = reader.ReadUInt32();
|
||||
uint unk = reader.ReadUInt32();
|
||||
uint unk2 = reader.ReadUInt32();
|
||||
uint[] unk3s = reader.ReadUInt32s((int)TextureCount);
|
||||
|
||||
for (int i = 0; i < TextureCount; i++)
|
||||
{
|
||||
reader.SeekBegin(StartPos + DataOffset + (i * 4));
|
||||
|
||||
uint InfoOffset = reader.ReadUInt32();
|
||||
|
||||
reader.SeekBegin(DataOffset + InfoOffset);
|
||||
|
||||
byte numMips = reader.ReadByte();
|
||||
byte format = reader.ReadByte();
|
||||
byte texDims = reader.ReadByte();
|
||||
byte unknown3 = reader.ReadByte(); //1
|
||||
byte unknown4 = reader.ReadByte(); //0
|
||||
byte unknown5 = reader.ReadByte(); //1
|
||||
byte unknown6 = reader.ReadByte(); //12
|
||||
byte extraHeader = reader.ReadByte();
|
||||
|
||||
if (reader.ByteOrder == Syroot.BinaryData.ByteOrder.LittleEndian)
|
||||
{
|
||||
numMips = SwapEndianByte(numMips);
|
||||
texDims = SwapEndianByte(texDims);
|
||||
extraHeader = SwapEndianByte(extraHeader);
|
||||
}
|
||||
|
||||
if (extraHeader == 1)
|
||||
{
|
||||
var extSize = reader.ReadInt32();
|
||||
var ext = reader.ReadBytes(extSize - 4);
|
||||
}
|
||||
|
||||
uint Width = (uint)Math.Pow(2, texDims / 16);
|
||||
uint Height = (uint)Math.Pow(2, texDims % 16);
|
||||
|
||||
GITexture tex = new GITexture(this);
|
||||
tex.ImageKey = "texture";
|
||||
tex.SelectedImageKey = tex.ImageKey;
|
||||
tex.Text = $"Texture {i} {format.ToString("x")}";
|
||||
tex.Width = Width;
|
||||
tex.Height = Height;
|
||||
tex.MipCount = numMips;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case 0x00: //ABGR
|
||||
case 0x01: //BGRA 32 bit (no mip maps)
|
||||
case 0x02: //RGBA 32 bit
|
||||
case 0x09:
|
||||
tex.Format = TEX_FORMAT.R8G8B8A8_UNORM;
|
||||
break;
|
||||
case 0x06:
|
||||
case 0x10: //PC and xbox (swizzled)
|
||||
case 0x59:
|
||||
case 0x60: //Swizzled
|
||||
tex.Format = TEX_FORMAT.BC1_UNORM;
|
||||
break;
|
||||
case 0x7:
|
||||
case 0x8:
|
||||
case 0x12: //PC and xbox (swizzled)
|
||||
case 0x5B:
|
||||
case 0x62: //bc1 swizzled
|
||||
tex.Format = TEX_FORMAT.BC3_UNORM;
|
||||
break;
|
||||
case 0x5C:
|
||||
tex.Format = TEX_FORMAT.BC4_UNORM;
|
||||
break;
|
||||
case 0x5D: //DXT5 swizzled or ATI2
|
||||
tex.Format = TEX_FORMAT.BC5_UNORM;
|
||||
break;
|
||||
case 0x5E:
|
||||
tex.Format = TEX_FORMAT.BC6H_UF16; //Uses cubemaps
|
||||
break;
|
||||
case 0x5F:
|
||||
tex.Format = TEX_FORMAT.BC7_UNORM;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unsupported format! " + format.ToString("x"));
|
||||
}
|
||||
|
||||
uint textureSize = (Width * Height * STGenericTexture.GetBytesPerPixel(tex.Format)) / 8;
|
||||
if (format == 0x09)
|
||||
textureSize = (Width * Height * 64) / 8;
|
||||
if (format == 0x01)
|
||||
{
|
||||
textureSize = (Width * Height * 32) / 8;
|
||||
tex.Parameters.DontSwapRG = true;
|
||||
}
|
||||
|
||||
tex.ImageData = reader.ReadBytes((int)textureSize);
|
||||
Nodes.Add(tex);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte SwapEndianByte(byte x)
|
||||
{
|
||||
return (byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4));
|
||||
}
|
||||
|
||||
public virtual ToolStripItem[] GetContextMenuItems()
|
||||
{
|
||||
List<ToolStripItem> Items = new List<ToolStripItem>();
|
||||
Items.Add(new ToolStripMenuItem("Export All", null, ExportAllAction, Keys.Control | Keys.E));
|
||||
return Items.ToArray();
|
||||
}
|
||||
|
||||
private void ExportAllAction(object sender, EventArgs args)
|
||||
{
|
||||
ExportAll();
|
||||
}
|
||||
|
||||
public virtual void ExportAll()
|
||||
{
|
||||
List<string> Formats = new List<string>();
|
||||
Formats.Add("Microsoft DDS (.dds)");
|
||||
Formats.Add("Portable Graphics Network (.png)");
|
||||
Formats.Add("Joint Photographic Experts Group (.jpg)");
|
||||
Formats.Add("Bitmap Image (.bmp)");
|
||||
Formats.Add("Tagged Image File Format (.tiff)");
|
||||
|
||||
FolderSelectDialog sfd = new FolderSelectDialog();
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
string folderPath = sfd.SelectedPath;
|
||||
|
||||
BatchFormatExport form = new BatchFormatExport(Formats);
|
||||
if (form.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
foreach (STGenericTexture tex in Nodes)
|
||||
{
|
||||
if (form.Index == 0)
|
||||
tex.SaveDDS(folderPath + '\\' + tex.Text + ".dds");
|
||||
else if (form.Index == 1)
|
||||
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".png");
|
||||
else if (form.Index == 2)
|
||||
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".jpg");
|
||||
else if (form.Index == 3)
|
||||
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".bmp");
|
||||
else if (form.Index == 4)
|
||||
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".tiff");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class GITexture : STGenericTexture
|
||||
{
|
||||
public G1T ContainerParent;
|
||||
|
||||
public override bool CanEdit { get; set; } = false;
|
||||
|
||||
public byte[] ImageData;
|
||||
|
||||
public override TEX_FORMAT[] SupportedFormats
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TEX_FORMAT[] {
|
||||
TEX_FORMAT.R8G8B8A8_UNORM,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public GITexture(G1T GT1)
|
||||
{
|
||||
ContainerParent = GT1;
|
||||
}
|
||||
|
||||
public override void OnClick(TreeView treeview)
|
||||
{
|
||||
UpdateEditor();
|
||||
}
|
||||
|
||||
private void UpdateEditor()
|
||||
{
|
||||
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
|
||||
if (editor == null)
|
||||
{
|
||||
editor = new ImageEditorBase();
|
||||
editor.Dock = DockStyle.Fill;
|
||||
LibraryGUI.LoadEditor(editor);
|
||||
}
|
||||
|
||||
editor.Text = Text;
|
||||
editor.LoadProperties(GenericProperties);
|
||||
editor.LoadImage(this);
|
||||
}
|
||||
|
||||
public override void SetImageData(Bitmap bitmap, int ArrayLevel)
|
||||
{
|
||||
}
|
||||
|
||||
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
|
||||
{
|
||||
if (ContainerParent.Platform == G1T.GT1Platform.WiiU)
|
||||
{
|
||||
uint bpp = GetBytesPerPixel(Format);
|
||||
|
||||
GX2.GX2Surface surf = new GX2.GX2Surface();
|
||||
surf.bpp = bpp;
|
||||
surf.height = Height;
|
||||
surf.width = Width;
|
||||
surf.aa = (uint)GX2.GX2AAMode.GX2_AA_MODE_1X;
|
||||
surf.alignment = 0;
|
||||
surf.depth = 1;
|
||||
surf.dim = (uint)GX2.GX2SurfaceDimension.DIM_2D;
|
||||
surf.format = (uint)Bfres.Structs.FTEX.ConvertToGx2Format(Format);
|
||||
surf.use = (uint)GX2.GX2SurfaceUse.USE_COLOR_BUFFER;
|
||||
surf.pitch = 0;
|
||||
surf.data = ImageData;
|
||||
surf.numMips = MipCount;
|
||||
surf.mipOffset = new uint[0];
|
||||
surf.mipData = ImageData;
|
||||
surf.tileMode = (uint)GX2.GX2TileMode.MODE_2D_TILED_THIN1;
|
||||
|
||||
// surf.tileMode = (uint)GX2.GX2TileMode.MODE_2D_TILED_THIN1;
|
||||
surf.swizzle = 0;
|
||||
surf.numArray = 1;
|
||||
|
||||
return GX2.Decode(surf, ArrayLevel, MipLevel);
|
||||
}
|
||||
else if (ContainerParent.Platform == G1T.GT1Platform.Switch)
|
||||
{
|
||||
return ImageData;
|
||||
// return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ImageData;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetMipmaps(STGenericTexture tex, byte[] ImageData)
|
||||
{
|
||||
uint width = 0;
|
||||
uint height = 0;
|
||||
|
||||
for (int a = 0; a < tex.ArrayCount; a++)
|
||||
{
|
||||
for (int m = 0; m < tex.MipCount; m++)
|
||||
{
|
||||
width = (uint)Math.Max(1, tex.Width >> m);
|
||||
Height = (uint)Math.Max(1, tex.Height >> m);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
125
File_Format_Library/FileFormats/HyruleWarriors/G1T/G1T.cs
Normal file
125
File_Format_Library/FileFormats/HyruleWarriors/G1T/G1T.cs
Normal file
@ -0,0 +1,125 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using Toolbox.Library;
|
||||
using Toolbox.Library.IO;
|
||||
using Toolbox.Library.Forms;
|
||||
using System.Drawing;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class G1T : TreeNodeFile, IFileFormat, IContextMenuNode, ITextureIconLoader
|
||||
{
|
||||
public FileType FileType { get; set; } = FileType.Image;
|
||||
|
||||
public bool CanSave { get; set; }
|
||||
public string[] Description { get; set; } = new string[] { "G1T Textre" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.g1t" };
|
||||
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, "G1TG") || reader.CheckSignature(4, "GT1G");
|
||||
}
|
||||
}
|
||||
|
||||
public Type[] Types
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
return types.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<STGenericTexture> IconTextureList
|
||||
{
|
||||
get
|
||||
{
|
||||
List<STGenericTexture> textures = new List<STGenericTexture>();
|
||||
foreach (STGenericTexture node in Nodes)
|
||||
textures.Add(node);
|
||||
|
||||
return textures;
|
||||
}
|
||||
set { }
|
||||
}
|
||||
|
||||
public G1TFile G1TFile = new G1TFile();
|
||||
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
Text = FileName;
|
||||
CanSave = true;
|
||||
|
||||
G1TFile.Read(new FileReader(stream));
|
||||
for (int i = 0; i < G1TFile.Textures.Count; i++)
|
||||
Nodes.Add(G1TFile.Textures[i]);
|
||||
}
|
||||
|
||||
public void Save(System.IO.Stream stream)
|
||||
{
|
||||
G1TFile.Write(new FileWriter(stream));
|
||||
}
|
||||
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual ToolStripItem[] GetContextMenuItems()
|
||||
{
|
||||
List<ToolStripItem> Items = new List<ToolStripItem>();
|
||||
Items.Add(new ToolStripMenuItem("Export All", null, ExportAllAction, Keys.Control | Keys.E));
|
||||
return Items.ToArray();
|
||||
}
|
||||
|
||||
private void ExportAllAction(object sender, EventArgs args)
|
||||
{
|
||||
ExportAll();
|
||||
}
|
||||
|
||||
public virtual void ExportAll()
|
||||
{
|
||||
List<string> Formats = new List<string>();
|
||||
Formats.Add("Microsoft DDS (.dds)");
|
||||
Formats.Add("Portable Graphics Network (.png)");
|
||||
Formats.Add("Joint Photographic Experts Group (.jpg)");
|
||||
Formats.Add("Bitmap Image (.bmp)");
|
||||
Formats.Add("Tagged Image File Format (.tiff)");
|
||||
|
||||
FolderSelectDialog sfd = new FolderSelectDialog();
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
string folderPath = sfd.SelectedPath;
|
||||
|
||||
BatchFormatExport form = new BatchFormatExport(Formats);
|
||||
if (form.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
foreach (STGenericTexture tex in Nodes)
|
||||
{
|
||||
if (form.Index == 0)
|
||||
tex.SaveDDS(folderPath + '\\' + tex.Text + ".dds");
|
||||
else if (form.Index == 1)
|
||||
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".png");
|
||||
else if (form.Index == 2)
|
||||
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".jpg");
|
||||
else if (form.Index == 3)
|
||||
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".bmp");
|
||||
else if (form.Index == 4)
|
||||
tex.SaveBitMap(folderPath + '\\' + tex.Text + ".tiff");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
257
File_Format_Library/FileFormats/HyruleWarriors/G1T/G1TFile.cs
Normal file
257
File_Format_Library/FileFormats/HyruleWarriors/G1T/G1TFile.cs
Normal file
@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
using Toolbox.Library.IO;
|
||||
using Toolbox.Library;
|
||||
using Toolbox.Library.Forms;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class G1TFile
|
||||
{
|
||||
public GT1Platform Platform;
|
||||
|
||||
public bool IsBigEndian = false;
|
||||
|
||||
public List<GITextureWrapper> Textures = new List<GITextureWrapper>();
|
||||
|
||||
public enum GT1Platform
|
||||
{
|
||||
PC,
|
||||
WiiU,
|
||||
Switch,
|
||||
}
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
|
||||
long StartPos = reader.Position;
|
||||
string Magic = reader.ReadString(4);
|
||||
|
||||
if (Magic == "GT1G")
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.LittleEndian;
|
||||
else
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
|
||||
IsBigEndian = reader.IsBigEndian;
|
||||
|
||||
if (Magic == "GT1G")
|
||||
Platform = GT1Platform.Switch;
|
||||
else
|
||||
Platform = GT1Platform.WiiU;
|
||||
|
||||
string Version = reader.ReadString(4);
|
||||
uint FileSize = reader.ReadUInt32();
|
||||
uint DataOffset = reader.ReadUInt32();
|
||||
uint TextureCount = reader.ReadUInt32();
|
||||
uint unk = reader.ReadUInt32();
|
||||
uint unk2 = reader.ReadUInt32();
|
||||
uint[] unk3s = reader.ReadUInt32s((int)TextureCount);
|
||||
|
||||
for (int i = 0; i < TextureCount; i++)
|
||||
{
|
||||
reader.SeekBegin(StartPos + DataOffset + (i * 4));
|
||||
|
||||
uint InfoOffset = reader.ReadUInt32();
|
||||
|
||||
reader.SeekBegin(DataOffset + InfoOffset);
|
||||
|
||||
byte numMips = reader.ReadByte();
|
||||
byte format = reader.ReadByte();
|
||||
byte texDims = reader.ReadByte();
|
||||
byte unknown3 = reader.ReadByte(); //1
|
||||
byte unknown4 = reader.ReadByte(); //0
|
||||
byte unknown5 = reader.ReadByte(); //1
|
||||
byte unknown6 = reader.ReadByte(); //12
|
||||
byte extraHeader = reader.ReadByte();
|
||||
|
||||
if (reader.ByteOrder == Syroot.BinaryData.ByteOrder.LittleEndian)
|
||||
{
|
||||
numMips = SwapEndianByte(numMips);
|
||||
texDims = SwapEndianByte(texDims);
|
||||
extraHeader = SwapEndianByte(extraHeader);
|
||||
}
|
||||
|
||||
if (extraHeader == 1)
|
||||
{
|
||||
var extSize = reader.ReadInt32();
|
||||
var ext = reader.ReadBytes(extSize - 4);
|
||||
}
|
||||
|
||||
uint Width = (uint)Math.Pow(2, texDims / 16);
|
||||
uint Height = (uint)Math.Pow(2, texDims % 16);
|
||||
|
||||
GITextureWrapper tex = new GITextureWrapper(this);
|
||||
tex.ImageKey = "texture";
|
||||
tex.SelectedImageKey = tex.ImageKey;
|
||||
tex.Text = $"Texture {i} {format.ToString("x")}";
|
||||
tex.Width = Width;
|
||||
tex.Height = Height;
|
||||
tex.MipCount = numMips;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case 0x00: //ABGR
|
||||
case 0x01: //BGRA 32 bit (no mip maps)
|
||||
case 0x02: //RGBA 32 bit
|
||||
case 0x09:
|
||||
tex.Format = TEX_FORMAT.R8G8B8A8_UNORM;
|
||||
break;
|
||||
case 0x06:
|
||||
case 0x10: //PC and xbox (swizzled)
|
||||
case 0x59:
|
||||
case 0x60: //Swizzled
|
||||
tex.Format = TEX_FORMAT.BC1_UNORM;
|
||||
break;
|
||||
case 0x7:
|
||||
case 0x8:
|
||||
case 0x12: //PC and xbox (swizzled)
|
||||
case 0x5B:
|
||||
case 0x62: //bc1 swizzled
|
||||
tex.Format = TEX_FORMAT.BC3_UNORM;
|
||||
break;
|
||||
case 0x5C:
|
||||
tex.Format = TEX_FORMAT.BC4_UNORM;
|
||||
break;
|
||||
case 0x5D: //DXT5 swizzled or ATI2
|
||||
tex.Format = TEX_FORMAT.BC5_UNORM;
|
||||
break;
|
||||
case 0x5E:
|
||||
tex.Format = TEX_FORMAT.BC6H_UF16; //Uses cubemaps
|
||||
break;
|
||||
case 0x5F:
|
||||
tex.Format = TEX_FORMAT.BC7_UNORM;
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unsupported format! " + format.ToString("x"));
|
||||
}
|
||||
|
||||
uint textureSize = (Width * Height * STGenericTexture.GetBytesPerPixel(tex.Format)) / 8;
|
||||
if (format == 0x09)
|
||||
textureSize = (Width * Height * 64) / 8;
|
||||
if (format == 0x01)
|
||||
{
|
||||
textureSize = (Width * Height * 32) / 8;
|
||||
tex.Parameters.DontSwapRG = true;
|
||||
}
|
||||
|
||||
tex.ImageData = reader.ReadBytes((int)textureSize);
|
||||
Textures.Add(tex);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static byte SwapEndianByte(byte x)
|
||||
{
|
||||
return (byte)(((x & 0x0F) << 4) | ((x & 0xF0) >> 4));
|
||||
}
|
||||
|
||||
|
||||
public class GITextureWrapper : STGenericTexture
|
||||
{
|
||||
public G1TFile ContainerParent;
|
||||
|
||||
public override bool CanEdit { get; set; } = false;
|
||||
|
||||
public byte[] ImageData;
|
||||
|
||||
public override TEX_FORMAT[] SupportedFormats
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TEX_FORMAT[] {
|
||||
TEX_FORMAT.R8G8B8A8_UNORM,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public GITextureWrapper(G1TFile GT1)
|
||||
{
|
||||
ContainerParent = GT1;
|
||||
}
|
||||
|
||||
public override void OnClick(TreeView treeview)
|
||||
{
|
||||
UpdateEditor();
|
||||
}
|
||||
|
||||
private void UpdateEditor()
|
||||
{
|
||||
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
|
||||
if (editor == null)
|
||||
{
|
||||
editor = new ImageEditorBase();
|
||||
editor.Dock = DockStyle.Fill;
|
||||
LibraryGUI.LoadEditor(editor);
|
||||
}
|
||||
|
||||
editor.Text = Text;
|
||||
editor.LoadProperties(GenericProperties);
|
||||
editor.LoadImage(this);
|
||||
}
|
||||
|
||||
public override void SetImageData(Bitmap bitmap, int ArrayLevel)
|
||||
{
|
||||
}
|
||||
|
||||
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
|
||||
{
|
||||
if (ContainerParent.Platform == GT1Platform.WiiU)
|
||||
{
|
||||
uint bpp = GetBytesPerPixel(Format);
|
||||
|
||||
GX2.GX2Surface surf = new GX2.GX2Surface();
|
||||
surf.bpp = bpp;
|
||||
surf.height = Height;
|
||||
surf.width = Width;
|
||||
surf.aa = (uint)GX2.GX2AAMode.GX2_AA_MODE_1X;
|
||||
surf.alignment = 0;
|
||||
surf.depth = 1;
|
||||
surf.dim = (uint)GX2.GX2SurfaceDimension.DIM_2D;
|
||||
surf.format = (uint)Bfres.Structs.FTEX.ConvertToGx2Format(Format);
|
||||
surf.use = (uint)GX2.GX2SurfaceUse.USE_COLOR_BUFFER;
|
||||
surf.pitch = 0;
|
||||
surf.data = ImageData;
|
||||
surf.numMips = MipCount;
|
||||
surf.mipOffset = new uint[0];
|
||||
surf.mipData = ImageData;
|
||||
surf.tileMode = (uint)GX2.GX2TileMode.MODE_2D_TILED_THIN1;
|
||||
|
||||
// surf.tileMode = (uint)GX2.GX2TileMode.MODE_2D_TILED_THIN1;
|
||||
surf.swizzle = 0;
|
||||
surf.numArray = 1;
|
||||
|
||||
return GX2.Decode(surf, ArrayLevel, MipLevel);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ImageData;
|
||||
}
|
||||
}
|
||||
|
||||
private void GetMipmaps(STGenericTexture tex, byte[] ImageData)
|
||||
{
|
||||
uint width = 0;
|
||||
uint height = 0;
|
||||
|
||||
for (int a = 0; a < tex.ArrayCount; a++)
|
||||
{
|
||||
for (int m = 0; m < tex.MipCount; m++)
|
||||
{
|
||||
width = (uint)Math.Max(1, tex.Width >> m);
|
||||
Height = (uint)Math.Max(1, tex.Height >> m);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -61,60 +61,16 @@ namespace FirstPlugin
|
||||
reader.Position = 0;
|
||||
}
|
||||
|
||||
private Stream CheckCompression(Stream stream)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
uint unk = reader.ReadUInt32();
|
||||
try
|
||||
{
|
||||
uint chunkCount = reader.ReadUInt32();
|
||||
uint unk2 = reader.ReadUInt32();
|
||||
uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount); //Not very sure about this
|
||||
|
||||
reader.Align(128);
|
||||
|
||||
List<byte[]> DecompressedChunks = new List<byte[]>();
|
||||
|
||||
//Now search for zlibbed chunks
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
uint size = reader.ReadUInt32();
|
||||
|
||||
long pos = reader.Position;
|
||||
ushort magic = reader.ReadUInt16();
|
||||
|
||||
///Check zlib magic
|
||||
if (magic == 0x78da)
|
||||
{
|
||||
var data = STLibraryCompression.ZLIB.Decompress(reader.getSection((uint)pos, size));
|
||||
DecompressedChunks.Add(data);
|
||||
|
||||
reader.SeekBegin(pos + size); //Seek the compressed size and align it to goto the next chunk
|
||||
reader.Align(128);
|
||||
}
|
||||
else //If the magic check fails, seek back 2. This shouldn't happen, but just incase
|
||||
reader.Seek(-2);
|
||||
}
|
||||
//Return the decompressed stream with all chunks combined
|
||||
return new MemoryStream(Utils.CombineByteArray(DecompressedChunks.ToArray()));
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
public bool isBigEndian = true;
|
||||
|
||||
public void Load(Stream stream)
|
||||
{
|
||||
stream = CheckCompression(stream);
|
||||
CanSave = true;
|
||||
|
||||
using (var reader = new FileReader(stream))
|
||||
{
|
||||
CheckEndianness(reader);
|
||||
isBigEndian = reader.IsBigEndian;
|
||||
|
||||
uint Count = reader.ReadUInt32();
|
||||
|
||||
@ -145,8 +101,9 @@ namespace FirstPlugin
|
||||
case "G1TG": //Textures
|
||||
G1T GITextureU = new G1T();
|
||||
GITextureU.FileName = $"TextureContainer{i}.gt1";
|
||||
GITextureU.Read(new FileReader(fileEntry.FileData));
|
||||
GITextureU.Load(new MemoryStream(fileEntry.FileData));
|
||||
Nodes.Add(GITextureU);
|
||||
fileEntry.FileFormat = GITextureU;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -164,6 +121,21 @@ namespace FirstPlugin
|
||||
|
||||
public void Save(System.IO.Stream stream)
|
||||
{
|
||||
using (var writer = new FileWriter(stream))
|
||||
{
|
||||
writer.SetByteOrder(isBigEndian);
|
||||
writer.Write(files.Count);
|
||||
long pos = writer.Position;
|
||||
writer.Write(new uint[files.Count * 2]);
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
{
|
||||
files[i].SaveFileFormat();
|
||||
|
||||
writer.WriteUint32Offset(pos + (i * 8));
|
||||
writer.Write(files[i].FileData.Length, pos + 4 + (i * 8));
|
||||
writer.Write(files[i].FileData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool AddFile(ArchiveFileInfo archiveFileInfo)
|
||||
|
@ -47,6 +47,8 @@ namespace FirstPlugin
|
||||
|
||||
public void ClearFiles() { files.Clear(); }
|
||||
|
||||
private FileReader DataReader;
|
||||
|
||||
public void Load(System.IO.Stream stream)
|
||||
{
|
||||
using (var reader = new FileReader(stream))
|
||||
@ -65,12 +67,34 @@ namespace FirstPlugin
|
||||
if (entry.Size != 0 && entry.CompFlags == 0)
|
||||
files.Add(entry);
|
||||
}
|
||||
|
||||
DataReader = GetDataFile();
|
||||
SearchData();
|
||||
}
|
||||
}
|
||||
|
||||
private void SearchData()
|
||||
{
|
||||
if (DataReader == null) return;
|
||||
|
||||
DataReader.Position = 0;
|
||||
for (int i = 0; i < files.Count; i++)
|
||||
{
|
||||
DataReader.SeekBegin(files[i].Offset);
|
||||
var magicCheck = DataReader.ReadString(4);
|
||||
Console.WriteLine("MAGIC=" + magicCheck);
|
||||
if (magicCheck == "SARC")
|
||||
files[i].FileName = $"Layout/{files[i].FileName}.szs";
|
||||
else if (magicCheck == "SPKG")
|
||||
files[i].FileName = $"ShaderPackage/{files[i].FileName}.spkg";
|
||||
else
|
||||
files[i].FileName = $"UnknownTypes/{files[i].FileName}.bin";
|
||||
}
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
DataReader?.Dispose();
|
||||
}
|
||||
|
||||
public void Save(System.IO.Stream stream)
|
||||
@ -87,6 +111,35 @@ namespace FirstPlugin
|
||||
return false;
|
||||
}
|
||||
|
||||
public FileReader GetDataFile()
|
||||
{
|
||||
if (DataReader != null) return DataReader;
|
||||
|
||||
if (IFileInfo.ArchiveParent != null)
|
||||
{
|
||||
foreach (var file in IFileInfo.ArchiveParent.Files)
|
||||
{
|
||||
if (file.FileName.Contains("DATA1.bin"))
|
||||
return new FileReader(file.FileDataStream, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string path = "";
|
||||
if (FilePath.Contains("LINKDATA.IDX"))
|
||||
path = FilePath.Replace("IDX", "BIN");
|
||||
if (FilePath.Contains("DATA1.bin"))
|
||||
path = FilePath.Replace("DATA0", "DATA1");
|
||||
|
||||
if (!System.IO.File.Exists(path))
|
||||
return null;
|
||||
|
||||
return new FileReader(path, true);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public class FileEntry : ArchiveFileInfo
|
||||
{
|
||||
private LINKDATA ParentFile;
|
||||
@ -103,6 +156,8 @@ namespace FirstPlugin
|
||||
ParentFile = data;
|
||||
}
|
||||
|
||||
public FileType Type = FileType.Unknown;
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
Offset = reader.ReadUInt64();
|
||||
@ -111,39 +166,18 @@ namespace FirstPlugin
|
||||
CompFlags = reader.ReadUInt64();
|
||||
}
|
||||
|
||||
public enum FileType
|
||||
{
|
||||
Unknown,
|
||||
Shader,
|
||||
Texture,
|
||||
Model,
|
||||
Sarc,
|
||||
}
|
||||
|
||||
public override Stream FileDataStream
|
||||
{
|
||||
get
|
||||
{
|
||||
if (ParentFile.IFileInfo.ArchiveParent != null)
|
||||
{
|
||||
foreach (var file in ParentFile.IFileInfo.ArchiveParent.Files)
|
||||
{
|
||||
if (file.FileName.Contains("DATA1.bin"))
|
||||
{
|
||||
return GetData(new FileReader(file.FileDataStream, true));
|
||||
}
|
||||
}
|
||||
|
||||
return new MemoryStream();
|
||||
}
|
||||
else
|
||||
{
|
||||
string path = "";
|
||||
if (SourcePath.Contains("LINKDATA.IDX"))
|
||||
path = SourcePath.Replace("IDX", "BIN");
|
||||
if (SourcePath.Contains("DATA1.bin"))
|
||||
path = SourcePath.Replace("DATA0", "DATA1");
|
||||
|
||||
if (!System.IO.File.Exists(path))
|
||||
return new MemoryStream();
|
||||
|
||||
using (var reader = new FileReader(path, true))
|
||||
{
|
||||
return GetData(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
get { return GetData(ParentFile.GetDataFile()); }
|
||||
}
|
||||
|
||||
private Stream GetData(FileReader reader)
|
||||
|
@ -88,7 +88,7 @@ namespace FirstPlugin
|
||||
{
|
||||
files.Clear();
|
||||
|
||||
Control = null;
|
||||
Control?.Dispose();
|
||||
}
|
||||
|
||||
public void Save(System.IO.Stream stream)
|
||||
|
@ -99,7 +99,7 @@ namespace FirstPlugin
|
||||
var file = romfs.FileDict[$"/{filePath}"];
|
||||
var stream = romfs.OpenFile(file).AsStream();
|
||||
|
||||
object fileFormat = STFileLoader.OpenFileFormat(text, stream.ToArray(), false, true);
|
||||
object fileFormat = STFileLoader.OpenFileFormat(stream , text, false, true);
|
||||
|
||||
if (fileFormat == null)
|
||||
return;
|
||||
|
@ -1,14 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Toolbox.Library;
|
||||
using Toolbox.Library.IO;
|
||||
using LibHac;
|
||||
using LibHac.IO;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class XCI : IFileFormat, ILeaveOpenOnLoad
|
||||
public class XCI : IFileFormat, IArchiveFile, ILeaveOpenOnLoad
|
||||
{
|
||||
public FileType FileType { get; set; } = FileType.Rom;
|
||||
|
||||
@ -33,16 +35,64 @@ namespace FirstPlugin
|
||||
return Utils.HasExtension(FileName, ".xci");
|
||||
}
|
||||
|
||||
public bool CanAddFiles { get; set; }
|
||||
public bool CanRenameFiles { get; set; }
|
||||
public bool CanReplaceFiles { get; set; }
|
||||
public bool CanDeleteFiles { get; set; }
|
||||
|
||||
public List<NSP.FileEntry> files = new List<NSP.FileEntry>();
|
||||
public IEnumerable<ArchiveFileInfo> Files => files;
|
||||
|
||||
public void ClearFiles() { files.Clear(); }
|
||||
|
||||
Nca Control { get; set; }
|
||||
|
||||
public void Load(System.IO.Stream stream)
|
||||
{
|
||||
string homeFolder = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
|
||||
string KeyFile = Path.Combine(homeFolder, ".switch", "prod.keys");
|
||||
string TitleKeyFile = Path.Combine(homeFolder, ".switch", "title.keys");
|
||||
|
||||
var Keys = ExternalKeys.ReadKeyFile(KeyFile, TitleKeyFile);
|
||||
|
||||
Xci xci = new Xci(Keys, stream.AsStorage());
|
||||
var CnmtNca = new Nca(Keys, xci.SecurePartition.OpenFile(
|
||||
xci.SecurePartition.Files.FirstOrDefault(s => s.Name.Contains(".cnmt.nca"))), false);
|
||||
var CnmtPfs = new Pfs(CnmtNca.OpenSection(0, false, IntegrityCheckLevel.None, true));
|
||||
var Cnmt = new Cnmt(CnmtPfs.OpenFile(CnmtPfs.Files[0]).AsStream());
|
||||
var Program = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Program);
|
||||
var CtrlEntry = Cnmt.ContentEntries.FirstOrDefault(c => c.Type == CnmtContentType.Control);
|
||||
if (CtrlEntry != null)
|
||||
Control = new Nca(Keys, xci.SecurePartition.OpenFile($"{CtrlEntry.NcaId.ToHexString().ToLower()}.nca"), false);
|
||||
var Input = xci.SecurePartition.OpenFile($"{Program.NcaId.ToHexString().ToLower()}.nca").AsStream();
|
||||
|
||||
var Nca = new Nca(Keys, Input.AsStorage(), true);
|
||||
|
||||
Romfs romfs = new Romfs(
|
||||
Nca.OpenSection(Nca.Sections.FirstOrDefault
|
||||
(s => s?.Type == SectionType.Romfs || s?.Type == SectionType.Bktr)
|
||||
.SectionNum, false, IntegrityCheckLevel.None, true));
|
||||
|
||||
for (int i = 0; i < romfs.Files.Count; i++)
|
||||
files.Add(new NSP.FileEntry(romfs, romfs.Files[i]));
|
||||
}
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
Control?.Dispose();
|
||||
}
|
||||
|
||||
public void Save(System.IO.Stream stream)
|
||||
{
|
||||
}
|
||||
|
||||
public bool AddFile(ArchiveFileInfo archiveFileInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool DeleteFile(ArchiveFileInfo archiveFileInfo)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ namespace FirstPlugin
|
||||
|
||||
public override void OnAfterAdded()
|
||||
{
|
||||
if (textures.Count > 0)
|
||||
if (textures.Count > 0 && this.TreeView != null)
|
||||
this.TreeView.SelectedNode = textures[0];
|
||||
}
|
||||
|
||||
|
193
File_Format_Library/FileFormats/Texture/TVOL.cs
Normal file
193
File_Format_Library/FileFormats/Texture/TVOL.cs
Normal file
@ -0,0 +1,193 @@
|
||||
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.IO;
|
||||
using Toolbox.Library.Forms;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public class TVOL : TreeNodeFile, IFileFormat, ILeaveOpenOnLoad
|
||||
{
|
||||
public FileType FileType { get; set; } = FileType.Image;
|
||||
|
||||
public bool CanSave { get; set; }
|
||||
public string[] Description { get; set; } = new string[] { "Texture VOL" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.tvol" };
|
||||
public string FileName { get; set; }
|
||||
public string FilePath { get; set; }
|
||||
public IFileInfo IFileInfo { get; set; }
|
||||
|
||||
public bool Identify(System.IO.Stream stream)
|
||||
{
|
||||
return Utils.GetExtension(FileName) == ".tvol";
|
||||
}
|
||||
|
||||
public List<STGenericTexture> IconTextureList
|
||||
{
|
||||
get
|
||||
{
|
||||
List<STGenericTexture> textures = new List<STGenericTexture>();
|
||||
foreach (STGenericTexture node in Nodes)
|
||||
textures.Add(node);
|
||||
|
||||
return textures;
|
||||
}
|
||||
set { }
|
||||
}
|
||||
|
||||
public Type[] Types
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
return types.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void Load(System.IO.Stream stream)
|
||||
{
|
||||
Text = FileName;
|
||||
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
reader.SetByteOrder(false);
|
||||
|
||||
uint numTextures = reader.ReadUInt32();
|
||||
for (int i = 0; i < numTextures; i++)
|
||||
{
|
||||
uint offset = reader.ReadUInt32();
|
||||
uint size = reader.ReadUInt32();
|
||||
if (size == 0)
|
||||
continue;
|
||||
|
||||
using (reader.TemporarySeek(offset, System.IO.SeekOrigin.Begin))
|
||||
{
|
||||
TextureWrapper entry = new TextureWrapper();
|
||||
entry.ImageKey = "texture";
|
||||
entry.SelectedImageKey = "texture";
|
||||
entry.Format = TEX_FORMAT.BC7_UNORM;
|
||||
entry.Text = reader.ReadZeroTerminatedString();
|
||||
|
||||
reader.SeekBegin(offset + 48);
|
||||
ulong unk = reader.ReadUInt64(); //20
|
||||
ulong unk2 = reader.ReadUInt64(); //36
|
||||
ulong sectionSize = reader.ReadUInt64();
|
||||
ulong unk3 = reader.ReadUInt64(); //16
|
||||
ulong unk4 = reader.ReadUInt64(); //4
|
||||
|
||||
uint unk5 = reader.ReadUInt32(); //C03F
|
||||
ulong unk6 = reader.ReadUInt64(); //32
|
||||
ulong unk7 = reader.ReadUInt64(); //24
|
||||
ulong unk8 = reader.ReadUInt64(); //40
|
||||
ulong imageSize = reader.ReadUInt64();
|
||||
entry.Width = reader.ReadUInt32();
|
||||
entry.Height = reader.ReadUInt32();
|
||||
entry.Depth = reader.ReadUInt32();
|
||||
entry.ArrayCount = reader.ReadUInt32();
|
||||
uint unk9 = reader.ReadUInt32(); //77
|
||||
uint unk10 = reader.ReadUInt32(); //1
|
||||
entry.ImageData = reader.ReadBytes((int)imageSize);
|
||||
Nodes.Add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Save(System.IO.Stream stream)
|
||||
{
|
||||
}
|
||||
|
||||
public class TextureWrapper : STGenericTexture
|
||||
{
|
||||
public byte[] ImageData;
|
||||
|
||||
public TextureWrapper()
|
||||
{
|
||||
}
|
||||
|
||||
private Dictionary<uint, TEX_FORMAT> Formats = new Dictionary<uint, TEX_FORMAT>()
|
||||
{
|
||||
{0x25 , TEX_FORMAT.R8G8B8A8_UNORM},
|
||||
{0x42 , TEX_FORMAT.BC1_UNORM},
|
||||
{0x43, TEX_FORMAT.BC2_UNORM},
|
||||
{0x44, TEX_FORMAT.BC3_UNORM},
|
||||
{0x45, TEX_FORMAT.BC4_UNORM},
|
||||
{0x46 , TEX_FORMAT.BC1_UNORM_SRGB},
|
||||
{0x47 , TEX_FORMAT.BC2_UNORM_SRGB},
|
||||
{0x48 , TEX_FORMAT.BC3_UNORM_SRGB},
|
||||
{0x49, TEX_FORMAT.BC4_SNORM},
|
||||
{0x50, TEX_FORMAT.BC6H_UF16},
|
||||
{0x79, TEX_FORMAT.ASTC_4x4_UNORM},
|
||||
{0x80, TEX_FORMAT.ASTC_8x8_UNORM},
|
||||
{0x87, TEX_FORMAT.ASTC_4x4_SRGB},
|
||||
{0x8E, TEX_FORMAT.ASTC_8x8_SRGB},
|
||||
};
|
||||
|
||||
public override bool CanEdit { get; set; } = false;
|
||||
|
||||
public override TEX_FORMAT[] SupportedFormats
|
||||
{
|
||||
get
|
||||
{
|
||||
return new TEX_FORMAT[]
|
||||
{
|
||||
TEX_FORMAT.B5G6R5_UNORM,
|
||||
TEX_FORMAT.R8G8_UNORM,
|
||||
TEX_FORMAT.B5G5R5A1_UNORM,
|
||||
TEX_FORMAT.B4G4R4A4_UNORM,
|
||||
TEX_FORMAT.LA8,
|
||||
TEX_FORMAT.HIL08,
|
||||
TEX_FORMAT.L8,
|
||||
TEX_FORMAT.A8_UNORM,
|
||||
TEX_FORMAT.LA4,
|
||||
TEX_FORMAT.A4,
|
||||
TEX_FORMAT.ETC1_UNORM,
|
||||
TEX_FORMAT.ETC1_A4,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetImageData(System.Drawing.Bitmap bitmap, int ArrayLevel)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private bool hasShownDialog = false;
|
||||
public override byte[] GetImageData(int ArrayLevel = 0, int MipLevel = 0)
|
||||
{
|
||||
return TegraX1Swizzle.GetImageData(this, ImageData, ArrayLevel, MipLevel, 1);
|
||||
}
|
||||
|
||||
|
||||
public override void OnClick(TreeView treeView)
|
||||
{
|
||||
UpdateEditor();
|
||||
}
|
||||
|
||||
private void UpdateEditor()
|
||||
{
|
||||
ImageEditorBase editor = (ImageEditorBase)LibraryGUI.GetActiveContent(typeof(ImageEditorBase));
|
||||
if (editor == null)
|
||||
{
|
||||
editor = new ImageEditorBase();
|
||||
editor.Dock = DockStyle.Fill;
|
||||
LibraryGUI.LoadEditor(editor);
|
||||
}
|
||||
|
||||
editor.LoadProperties(GenericProperties);
|
||||
editor.LoadImage(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -229,7 +229,8 @@
|
||||
<Compile Include="FileFormats\HyruleWarriors\G1M\G1MEnums.cs" />
|
||||
<Compile Include="FileFormats\HyruleWarriors\G1M\G1MG.cs" />
|
||||
<Compile Include="FileFormats\HyruleWarriors\G1M\G1MS.cs" />
|
||||
<Compile Include="FileFormats\HyruleWarriors\G1T.cs" />
|
||||
<Compile Include="FileFormats\HyruleWarriors\G1T\G1T.cs" />
|
||||
<Compile Include="FileFormats\HyruleWarriors\G1T\G1TFile.cs" />
|
||||
<Compile Include="FileFormats\HyruleWarriors\HWBinGzResource.cs" />
|
||||
<Compile Include="FileFormats\CrashBandicoot\IGA_PAK.cs" />
|
||||
<Compile Include="FileFormats\Archives\LM2\LM2_ChunkTable.cs" />
|
||||
@ -327,6 +328,7 @@
|
||||
<Compile Include="FileFormats\Rom\3DS\RomFSStructure.cs" />
|
||||
<Compile Include="FileFormats\Texture\CTPK.cs" />
|
||||
<Compile Include="FileFormats\Grezzo\CTXB.cs" />
|
||||
<Compile Include="FileFormats\Texture\TVOL.cs" />
|
||||
<Compile Include="FileFormats\Texture\TPL.cs" />
|
||||
<Compile Include="FileFormats\Rom\GCDisk.cs" />
|
||||
<Compile Include="FileFormats\Texture\BTI.cs" />
|
||||
|
15
File_Format_Library/GUI/KeySelection.Designer.cs
generated
15
File_Format_Library/GUI/KeySelection.Designer.cs
generated
@ -109,14 +109,13 @@
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(415, 181);
|
||||
this.Controls.Add(this.setProdKeyPath);
|
||||
this.Controls.Add(this.setTitleKeyPath);
|
||||
this.Controls.Add(this.btnOk);
|
||||
this.Controls.Add(this.stLabel2);
|
||||
this.Controls.Add(this.TextBoxTitleKey);
|
||||
this.Controls.Add(this.stLabel1);
|
||||
this.Controls.Add(this.TextBoxProdKeyPath);
|
||||
this.contentContainer.Controls.Add(this.setProdKeyPath);
|
||||
this.contentContainer.Controls.Add(this.setTitleKeyPath);
|
||||
this.contentContainer.Controls.Add(this.btnOk);
|
||||
this.contentContainer.Controls.Add(this.stLabel2);
|
||||
this.contentContainer.Controls.Add(this.TextBoxTitleKey);
|
||||
this.contentContainer.Controls.Add(this.stLabel1);
|
||||
this.contentContainer.Controls.Add(this.TextBoxProdKeyPath);
|
||||
this.Name = "KeySelectionForm";
|
||||
this.Text = "Select Key Files";
|
||||
this.ResumeLayout(false);
|
||||
|
@ -28,6 +28,7 @@
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
|
||||
this.listViewCustom1 = new Toolbox.Library.Forms.ListViewCustom();
|
||||
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
@ -42,6 +43,7 @@
|
||||
this.stMenuStrip1 = new Toolbox.Library.Forms.STMenuStrip();
|
||||
this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.loadFontToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.stContextMenuStrip1 = new Toolbox.Library.Forms.STContextMenuStrip(this.components);
|
||||
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
|
||||
this.splitContainer1.Panel1.SuspendLayout();
|
||||
this.splitContainer1.Panel2.SuspendLayout();
|
||||
@ -220,6 +222,11 @@
|
||||
this.loadFontToolStripMenuItem.Text = "Load Font";
|
||||
this.loadFontToolStripMenuItem.Click += new System.EventHandler(this.loadFontToolStripMenuItem_Click);
|
||||
//
|
||||
// stContextMenuStrip1
|
||||
//
|
||||
this.stContextMenuStrip1.Name = "stContextMenuStrip1";
|
||||
this.stContextMenuStrip1.Size = new System.Drawing.Size(61, 4);
|
||||
//
|
||||
// MSBTEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
@ -266,5 +273,6 @@
|
||||
private Toolbox.Library.Forms.STMenuStrip stMenuStrip1;
|
||||
private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem loadFontToolStripMenuItem;
|
||||
private Toolbox.Library.Forms.STContextMenuStrip stContextMenuStrip1;
|
||||
}
|
||||
}
|
@ -120,4 +120,7 @@
|
||||
<metadata name="stMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="stContextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>141, 17</value>
|
||||
</metadata>
|
||||
</root>
|
@ -238,7 +238,7 @@ namespace FirstPlugin
|
||||
string ext = System.IO.Path.GetExtension(file.FileName);
|
||||
if (ext == ".bfres")
|
||||
{
|
||||
bfresFiles.Add((BFRES)STFileLoader.OpenFileFormat(file.FileName, file.FileData));
|
||||
bfresFiles.Add((BFRES)STFileLoader.OpenFileFormat(new System.IO.MemoryStream(file.FileData), file.FileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -385,6 +385,8 @@ namespace FirstPlugin
|
||||
Formats.Add(typeof(BCLIM));
|
||||
Formats.Add(typeof(LayoutBXLYT.BFLAN));
|
||||
Formats.Add(typeof(DAT_Bayonetta));
|
||||
Formats.Add(typeof(XCI));
|
||||
Formats.Add(typeof(TVOL));
|
||||
|
||||
// Formats.Add(typeof(MSBP));
|
||||
// Formats.Add(typeof(BFGRP));
|
||||
@ -392,7 +394,6 @@ namespace FirstPlugin
|
||||
//Unfinished wip formats not ready for use
|
||||
if (Runtime.DEVELOPER_DEBUG_MODE)
|
||||
{
|
||||
Formats.Add(typeof(XCI));
|
||||
Formats.Add(typeof(XLINK));
|
||||
Formats.Add(typeof(BFSAR));
|
||||
Formats.Add(typeof(GFA));
|
||||
|
@ -39,7 +39,7 @@ namespace FirstPlugin
|
||||
|
||||
if (bfresData != null)
|
||||
{
|
||||
BFRES bfresFile = (BFRES)STFileLoader.OpenFileFormat(ob.Name, bfresData);
|
||||
BFRES bfresFile = (BFRES)STFileLoader.OpenFileFormat(new MemoryStream(bfresData), ob.Name);
|
||||
bfresFile.BFRESRender.ModelTransform = Transform;
|
||||
|
||||
editor.AddNode(bfresFile);
|
||||
|
@ -21,6 +21,7 @@ namespace Toolbox.Library.IO
|
||||
|
||||
items.Add(new ToolStripMenuItem("Yaz0"));
|
||||
items.Add(new ToolStripMenuItem("Gzip"));
|
||||
items.Add(new ToolStripMenuItem("lZMA"));
|
||||
items.Add(new ToolStripMenuItem("lZ4"));
|
||||
items.Add(new ToolStripMenuItem("lZ4F"));
|
||||
items.Add(new ToolStripMenuItem("ZSTD"));
|
||||
@ -64,89 +65,48 @@ namespace Toolbox.Library.IO
|
||||
private void SetToolStripFunctions(string Name, bool Compress)
|
||||
{
|
||||
if (Name == "Yaz0")
|
||||
OpenFileForCompression(CompressionType.Yaz0, Compress);
|
||||
OpenFileForCompression(new Yaz0(), Compress);
|
||||
else if (Name == "Gzip")
|
||||
OpenFileForCompression(CompressionType.Gzip, Compress);
|
||||
OpenFileForCompression(new Gzip(), Compress);
|
||||
else if (Name == "lZMA")
|
||||
OpenFileForCompression(new LZMA(), Compress);
|
||||
else if (Name == "lZ4")
|
||||
OpenFileForCompression(CompressionType.Lz4, Compress);
|
||||
OpenFileForCompression(new lz4(), Compress);
|
||||
else if (Name == "lZ4F")
|
||||
OpenFileForCompression(CompressionType.Lz4f, Compress);
|
||||
OpenFileForCompression(new LZ4F(), Compress);
|
||||
else if (Name == "ZSTD")
|
||||
OpenFileForCompression(CompressionType.Zstb, Compress);
|
||||
OpenFileForCompression(new Zstb(), Compress);
|
||||
else if (Name == "ZLIB")
|
||||
OpenFileForCompression(CompressionType.Zlib, Compress);
|
||||
OpenFileForCompression(new Zlib(), Compress);
|
||||
else if (Name.Contains("ZLIB_GZ"))
|
||||
OpenFileForCompression(CompressionType.ZlibGz, Compress);
|
||||
OpenFileForCompression(new ZlibGZ(), Compress);
|
||||
else throw new Exception("Unimplimented Type! " + Name);
|
||||
}
|
||||
|
||||
public void CompressData(CompressionType CompressionType, byte[] data)
|
||||
{
|
||||
switch (CompressionType)
|
||||
{
|
||||
case CompressionType.Yaz0:
|
||||
SaveFileForCompression(EveryFileExplorer.YAZ0.Compress(data, Runtime.Yaz0CompressionLevel));
|
||||
break;
|
||||
case CompressionType.Zlib:
|
||||
SaveFileForCompression(STLibraryCompression.ZLIB.Compress(data));
|
||||
break;
|
||||
case CompressionType.Gzip:
|
||||
SaveFileForCompression(STLibraryCompression.GZIP.Compress(data));
|
||||
break;
|
||||
case CompressionType.Zstb:
|
||||
SaveFileForCompression(STLibraryCompression.ZSTD.Compress(data));
|
||||
break;
|
||||
case CompressionType.Lz4f:
|
||||
SaveFileForCompression(STLibraryCompression.Type_LZ4F.Compress(data));
|
||||
break;
|
||||
case CompressionType.Lz4:
|
||||
SaveFileForCompression(STLibraryCompression.Type_LZ4.Compress(data));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
public void DecompressData(CompressionType CompressionType, byte[] data)
|
||||
public void CompressData(ICompressionFormat CompressionFormat, Stream data)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (CompressionType)
|
||||
{
|
||||
case CompressionType.Yaz0:
|
||||
SaveFileForCompression(EveryFileExplorer.YAZ0.Decompress(data));
|
||||
break;
|
||||
case CompressionType.Zlib:
|
||||
SaveFileForCompression(STLibraryCompression.ZLIB.Decompress(data));
|
||||
break;
|
||||
case CompressionType.Gzip:
|
||||
SaveFileForCompression(STLibraryCompression.GZIP.Decompress(data));
|
||||
break;
|
||||
case CompressionType.Zstb:
|
||||
SaveFileForCompression(STLibraryCompression.ZSTD.Decompress(data));
|
||||
break;
|
||||
case CompressionType.Lz4f:
|
||||
using (var reader = new FileReader(data))
|
||||
{
|
||||
reader.Position = 0;
|
||||
int OuSize = reader.ReadInt32();
|
||||
int InSize = data.Length - 4;
|
||||
SaveFileForCompression(STLibraryCompression.Type_LZ4F.Decompress(reader.getSection(4, InSize)));
|
||||
}
|
||||
break;
|
||||
case CompressionType.Lz4:
|
||||
SaveFileForCompression(STLibraryCompression.Type_LZ4.Decompress(data));
|
||||
break;
|
||||
case CompressionType.ZlibGz:
|
||||
SaveFileForCompression(STLibraryCompression.ZLIB_GZ.Decompress(new MemoryStream(data)));
|
||||
break;
|
||||
}
|
||||
SaveFileForCompression(true, data, CompressionFormat);
|
||||
}
|
||||
catch
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"File not compressed with {CompressionType} compression!");
|
||||
MessageBox.Show($"File failed to compress with {CompressionFormat} compression! {ex.ToString()}");
|
||||
}
|
||||
}
|
||||
public void DecompressData(ICompressionFormat CompressionFormat, Stream data)
|
||||
{
|
||||
try
|
||||
{
|
||||
SaveFileForCompression(false, data, CompressionFormat);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show($"File not compressed with {CompressionFormat} compression! {ex.ToString()}");
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenFileForCompression(CompressionType compressionType, bool Compress)
|
||||
private void OpenFileForCompression(ICompressionFormat compressionFormat, bool Compress)
|
||||
{
|
||||
OpenFileDialog ofd = new OpenFileDialog();
|
||||
ofd.Filter = "All files(*.*)|*.*";
|
||||
@ -158,14 +118,14 @@ namespace Toolbox.Library.IO
|
||||
foreach (string file in ofd.FileNames)
|
||||
{
|
||||
if (Compress)
|
||||
CompressData(compressionType, File.ReadAllBytes(ofd.FileName));
|
||||
CompressData(compressionFormat, File.OpenRead(ofd.FileName));
|
||||
else
|
||||
DecompressData(compressionType, File.ReadAllBytes(ofd.FileName));
|
||||
DecompressData(compressionFormat, File.OpenRead(ofd.FileName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveFileForCompression(Stream data)
|
||||
private void SaveFileForCompression(bool Compress, Stream data, ICompressionFormat compressionFormat)
|
||||
{
|
||||
SaveFileDialog sfd = new SaveFileDialog();
|
||||
sfd.Filter = "All files(*.*)|*.*";
|
||||
@ -173,21 +133,13 @@ namespace Toolbox.Library.IO
|
||||
Cursor.Current = Cursors.Default;
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
data.ExportToFile(sfd.FileName);
|
||||
if (Compress)
|
||||
compressionFormat.Compress(data).ExportToFile(sfd.FileName);
|
||||
else
|
||||
compressionFormat.Decompress(data).ExportToFile(sfd.FileName);
|
||||
|
||||
MessageBox.Show($"File has been saved to {sfd.FileName}", "Save Notification");
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveFileForCompression(byte[] data)
|
||||
{
|
||||
SaveFileDialog sfd = new SaveFileDialog();
|
||||
sfd.Filter = "All files(*.*)|*.*";
|
||||
|
||||
Cursor.Current = Cursors.Default;
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
STFileSaver.SaveFileFormat(data, true, 0, CompressionType.None, sfd.FileName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
64
Switch_Toolbox_Library/Compression/Formats/Gzip.cs
Normal file
64
Switch_Toolbox_Library/Compression/Formats/Gzip.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using Toolbox.Library.IO;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
public class Gzip : ICompressionFormat
|
||||
{
|
||||
public string[] Description { get; set; } = new string[] { "GZIP Compressed" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.gzip", };
|
||||
|
||||
private long startPosition = 0;
|
||||
|
||||
private bool IsSonicWinterOlypmics = false;
|
||||
|
||||
public override string ToString() { return "Gzip"; }
|
||||
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
reader.SetByteOrder(true);
|
||||
|
||||
ushort magicNumber = reader.ReadUInt16();
|
||||
|
||||
reader.Position = 0;
|
||||
string magicSig = reader.ReadString(4);
|
||||
IsSonicWinterOlypmics = magicSig == "ZLIB";
|
||||
if (IsSonicWinterOlypmics)
|
||||
startPosition = 64;
|
||||
|
||||
return magicNumber == 0x1f8b || IsSonicWinterOlypmics;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanCompress { get; } = true;
|
||||
|
||||
public Stream Decompress(Stream stream)
|
||||
{
|
||||
stream.Position = startPosition;
|
||||
|
||||
var mem = new System.IO.MemoryStream();
|
||||
using (GZipStream source = new GZipStream(stream, CompressionMode.Decompress, false))
|
||||
{
|
||||
source.CopyTo(mem);
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
|
||||
public Stream Compress(Stream stream)
|
||||
{
|
||||
MemoryStream mem = new MemoryStream();
|
||||
using (GZipStream gzip = new GZipStream(mem, CompressionMode.Compress, true))
|
||||
{
|
||||
stream.CopyTo(gzip);
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
}
|
||||
}
|
60
Switch_Toolbox_Library/Compression/Formats/LZ4F.cs
Normal file
60
Switch_Toolbox_Library/Compression/Formats/LZ4F.cs
Normal file
@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using Toolbox.Library.IO;
|
||||
using K4os.Compression.LZ4.Streams;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
public class LZ4F : ICompressionFormat
|
||||
{
|
||||
public string[] Description { get; set; } = new string[] { "LZ4F Compression" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.cmp", "*.lz4f" };
|
||||
|
||||
public override string ToString() { return "LZ4F"; }
|
||||
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
uint DecompressedSize = reader.ReadUInt32();
|
||||
uint magicCheck = reader.ReadUInt32();
|
||||
|
||||
bool LZ4FDefault = magicCheck == 0x184D2204;
|
||||
|
||||
return LZ4FDefault;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanCompress { get; } = true;
|
||||
|
||||
public Stream Decompress(Stream stream)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
reader.Position = 0;
|
||||
int OuSize = reader.ReadInt32();
|
||||
int InSize = (int)stream.Length - 4;
|
||||
var dec = STLibraryCompression.Type_LZ4F.Decompress(reader.getSection(4, InSize));
|
||||
return new MemoryStream(dec);
|
||||
}
|
||||
}
|
||||
|
||||
public Stream Compress(Stream stream)
|
||||
{
|
||||
var mem = new MemoryStream();
|
||||
using (var writer = new FileWriter(mem, true))
|
||||
{
|
||||
writer.Write((uint)stream.Length);
|
||||
byte[] buffer = LZ4.Frame.LZ4Frame.Compress(stream,
|
||||
LZ4.Frame.LZ4MaxBlockSize.MB1, true, true, false, true, false);
|
||||
|
||||
writer.Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
}
|
||||
}
|
69
Switch_Toolbox_Library/Compression/Formats/LZMA.cs
Normal file
69
Switch_Toolbox_Library/Compression/Formats/LZMA.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using Toolbox.Library.IO;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
public class LZMA : ICompressionFormat
|
||||
{
|
||||
public string[] Description { get; set; } = new string[] { "LZMA Compressed" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.lzma", };
|
||||
|
||||
public override string ToString() { return "LZMA"; }
|
||||
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
return reader.CheckSignature(4,"LZMA", 1);
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanCompress { get; } = true;
|
||||
|
||||
public Stream Decompress(Stream stream)
|
||||
{
|
||||
using (var reader = new FileReader(stream))
|
||||
{
|
||||
reader.SetByteOrder(true);
|
||||
|
||||
var output = new System.IO.MemoryStream();
|
||||
if (reader.CheckSignature(4, "LZMA", 1))
|
||||
{
|
||||
byte unk = reader.ReadByte();
|
||||
uint magic = reader.ReadUInt32();
|
||||
ushort unk2 = reader.ReadUInt16();
|
||||
}
|
||||
|
||||
uint decompressedSize = reader.ReadUInt32();
|
||||
var properties = reader.ReadBytes(5);
|
||||
|
||||
var compressedSize = stream.Length - 16;
|
||||
var copressedBytes = reader.ReadBytes((int)compressedSize);
|
||||
|
||||
SevenZip.Compression.LZMA.Decoder decode = new SevenZip.Compression.LZMA.Decoder();
|
||||
decode.SetDecoderProperties(properties);
|
||||
|
||||
|
||||
MemoryStream ms = new MemoryStream(copressedBytes);
|
||||
decode.Code(ms, output, compressedSize, decompressedSize, null);
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
public Stream Compress(Stream stream)
|
||||
{
|
||||
MemoryStream mem = new MemoryStream();
|
||||
using (GZipStream gzip = new GZipStream(mem, CompressionMode.Compress, true))
|
||||
{
|
||||
stream.CopyTo(gzip);
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ namespace Toolbox.Library
|
||||
public string[] Description { get; set; } = new string[] { "LZSS Compression" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.lzs", "*.lzss" };
|
||||
|
||||
public bool Identify(Stream stream)
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
@ -13,7 +13,7 @@ namespace Toolbox.Library
|
||||
public string[] Description { get; set; } = new string[] { "MIO0" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.mio0" };
|
||||
|
||||
public bool Identify(Stream stream)
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
@ -15,7 +15,7 @@ namespace Toolbox.Library
|
||||
public string[] Description { get; set; } = new string[] { "Yay0" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.yay0" };
|
||||
|
||||
public bool Identify(Stream stream)
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
@ -13,7 +13,9 @@ namespace Toolbox.Library
|
||||
public string[] Description { get; set; } = new string[] { "Yaz0" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.yaz0", "*.szs",};
|
||||
|
||||
public bool Identify(Stream stream)
|
||||
public override string ToString() { return "Yaz0"; }
|
||||
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
@ -13,7 +13,7 @@ namespace Toolbox.Library
|
||||
public string[] Description { get; set; } = new string[] { "ZLIB Compression (ZCMP)" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.cmp" };
|
||||
|
||||
public bool Identify(Stream stream)
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
63
Switch_Toolbox_Library/Compression/Formats/Zlib.cs
Normal file
63
Switch_Toolbox_Library/Compression/Formats/Zlib.cs
Normal file
@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using Toolbox.Library.IO;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
public class Zlib : ICompressionFormat
|
||||
{
|
||||
public string[] Description { get; set; } = new string[] { "ZLIB Compressed" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.z", "*.zlib", };
|
||||
|
||||
private long startPosition = 0;
|
||||
|
||||
public override string ToString() { return "Zlib"; }
|
||||
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
startPosition = stream.Position;
|
||||
|
||||
reader.SetByteOrder(true);
|
||||
|
||||
ushort magicNumber = reader.ReadUInt16();
|
||||
|
||||
// reader.Position = stream.Position + 4;
|
||||
ushort magicNumber2 = reader.ReadUInt16();
|
||||
|
||||
//Check 2 cases which the file is zlibbed.
|
||||
//One is that it is compressed with magic at start
|
||||
//Another is a size (uint) then magic
|
||||
bool IsValid = magicNumber == 0x789C || magicNumber == 0x78DA;
|
||||
bool IsValid2 = magicNumber2 == 0x789C || magicNumber2 == 0x78DA;
|
||||
if (IsValid2)
|
||||
startPosition = stream.Position + 4;
|
||||
|
||||
return IsValid || IsValid2;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanCompress { get; } = true;
|
||||
|
||||
public Stream Decompress(Stream stream)
|
||||
{
|
||||
stream.Position = startPosition;
|
||||
|
||||
var data = STLibraryCompression.ZLIB.Decompress(stream.ToArray());
|
||||
return new MemoryStream(data);
|
||||
}
|
||||
|
||||
public Stream Compress(Stream stream)
|
||||
{
|
||||
stream.Position = startPosition;
|
||||
|
||||
var data = STLibraryCompression.ZLIB.Compress(stream.ToArray());
|
||||
return new MemoryStream(data);
|
||||
}
|
||||
}
|
||||
}
|
38
Switch_Toolbox_Library/Compression/Formats/ZlibGZ.cs
Normal file
38
Switch_Toolbox_Library/Compression/Formats/ZlibGZ.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using Toolbox.Library.IO;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
public class ZlibGZ : ICompressionFormat
|
||||
{
|
||||
public bool IsBigEndian = true;
|
||||
|
||||
public string[] Description { get; set; } = new string[] { "ZLIB GZ" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.gz", };
|
||||
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
if (Utils.GetExtension(fileName) != ".gz")
|
||||
return false;
|
||||
|
||||
return STLibraryCompression.ZLIB_GZ.IsCompressed(stream);
|
||||
}
|
||||
|
||||
public bool CanCompress { get; } = true;
|
||||
|
||||
public Stream Decompress(Stream stream)
|
||||
{
|
||||
return STLibraryCompression.ZLIB_GZ.Decompress(stream);
|
||||
}
|
||||
|
||||
public Stream Compress(Stream stream)
|
||||
{
|
||||
return STLibraryCompression.ZLIB_GZ.Compress(stream, IsBigEndian);
|
||||
}
|
||||
}
|
||||
}
|
61
Switch_Toolbox_Library/Compression/Formats/Zstb.cs
Normal file
61
Switch_Toolbox_Library/Compression/Formats/Zstb.cs
Normal file
@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Threading.Tasks;
|
||||
using Toolbox.Library.IO;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
public class Zstb : ICompressionFormat
|
||||
{
|
||||
public string[] Description { get; set; } = new string[] { "ZSTD" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.zstd", };
|
||||
|
||||
public override string ToString() { return "ZSTD"; }
|
||||
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
uint magic = reader.ReadUInt32();
|
||||
return magic == 0x28B52FFD || magic == 0xFD2FB528;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanCompress { get; } = true;
|
||||
|
||||
public Stream Decompress(Stream stream)
|
||||
{
|
||||
return new MemoryStream(SDecompress(stream.ToArray()));
|
||||
}
|
||||
|
||||
public Stream Compress(Stream stream)
|
||||
{
|
||||
return new MemoryStream(SCompress(stream.ToArray()));
|
||||
}
|
||||
|
||||
public static byte[] SDecompress(byte[] b)
|
||||
{
|
||||
using (var decompressor = new ZstdNet.Decompressor())
|
||||
{
|
||||
return decompressor.Unwrap(b);
|
||||
}
|
||||
}
|
||||
public static byte[] SDecompress(byte[] b, int MaxDecompressedSize)
|
||||
{
|
||||
using (var decompressor = new ZstdNet.Decompressor())
|
||||
{
|
||||
return decompressor.Unwrap(b, MaxDecompressedSize);
|
||||
}
|
||||
}
|
||||
public static byte[] SCompress(byte[] b)
|
||||
{
|
||||
using (var compressor = new ZstdNet.Compressor())
|
||||
{
|
||||
return compressor.Wrap(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -9,17 +9,21 @@ using K4os.Compression.LZ4.Streams;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
public class LZ4F : ICompressionFormat
|
||||
public class lz4 : ICompressionFormat
|
||||
{
|
||||
public string[] Description { get; set; } = new string[] { "LZ4F Compression" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.cmp", "*.lz4f" };
|
||||
public string[] Description { get; set; } = new string[] { "LZ4 Compression" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.lz4" };
|
||||
|
||||
public bool Identify(Stream stream)
|
||||
public override string ToString() { return "lz4"; }
|
||||
|
||||
public bool Identify(Stream stream, string fileName)
|
||||
{
|
||||
return false;
|
||||
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
uint DecompressedSize = reader.ReadUInt32();
|
||||
uint magicCheck = reader.ReadUInt32();
|
||||
uint magicCheck = reader.ReadUInt32();
|
||||
|
||||
bool LZ4FDefault = magicCheck == 0x184D2204;
|
||||
|
||||
@ -44,16 +48,11 @@ namespace Toolbox.Library
|
||||
public Stream Compress(Stream stream)
|
||||
{
|
||||
var mem = new MemoryStream();
|
||||
using (var writer = new FileWriter(mem))
|
||||
using (var source = LZ4Stream.Encode(stream, null, true))
|
||||
{
|
||||
var data = stream.ToArray();
|
||||
writer.Write(data.Length);
|
||||
byte[] buffer = LZ4.Frame.LZ4Frame.Compress(new MemoryStream(data),
|
||||
LZ4.Frame.LZ4MaxBlockSize.MB1, true, true, false, true, false);
|
||||
|
||||
writer.Write(buffer, 0, buffer.Length);
|
||||
source.CopyTo(mem);
|
||||
}
|
||||
return stream;
|
||||
return mem;
|
||||
}
|
||||
}
|
||||
}
|
@ -20,44 +20,15 @@ namespace Toolbox.Library.IO
|
||||
if (format.IFileInfo != null)
|
||||
Alignment = format.IFileInfo.Alignment;
|
||||
|
||||
switch (format.IFileInfo.CompressionType)
|
||||
{
|
||||
case CompressionType.Yaz0:
|
||||
return EveryFileExplorer.YAZ0.Compress(data, 3, (uint)Alignment);
|
||||
case CompressionType.Zstb:
|
||||
return ZSTD.Compress(data);
|
||||
case CompressionType.Zlib:
|
||||
return ZLIB.Compress(data);
|
||||
case CompressionType.None:
|
||||
return data;
|
||||
default:
|
||||
return data;
|
||||
}
|
||||
var FileCompression = format.IFileInfo.FileCompression;
|
||||
if (FileCompression == null) return data;
|
||||
|
||||
return FileCompression.Compress(new MemoryStream(data)).ToArray();
|
||||
}
|
||||
|
||||
public class ZSTD
|
||||
{
|
||||
public static byte[] Decompress(byte[] b)
|
||||
{
|
||||
using (var decompressor = new ZstdNet.Decompressor())
|
||||
{
|
||||
return decompressor.Unwrap(b);
|
||||
}
|
||||
}
|
||||
public static byte[] Decompress(byte[] b, int MaxDecompressedSize)
|
||||
{
|
||||
using (var decompressor = new ZstdNet.Decompressor())
|
||||
{
|
||||
return decompressor.Unwrap(b, MaxDecompressedSize);
|
||||
}
|
||||
}
|
||||
public static byte[] Compress(byte[] b)
|
||||
{
|
||||
using (var compressor = new ZstdNet.Compressor())
|
||||
{
|
||||
return compressor.Wrap(b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -65,27 +36,29 @@ namespace Toolbox.Library.IO
|
||||
{
|
||||
public static bool IsCompressed(Stream stream)
|
||||
{
|
||||
if (stream.Length < 32) return false;
|
||||
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
reader.Position = 0;
|
||||
uint chunkSize = reader.ReadUInt32();
|
||||
uint chunkCount = reader.ReadUInt32();
|
||||
uint unk = reader.ReadUInt32();
|
||||
if (reader.BaseStream.Length > 4 + (chunkCount * 4))
|
||||
uint decompressedSize = reader.ReadUInt32();
|
||||
if (reader.BaseStream.Length > 8 + (chunkCount * 4) + 128)
|
||||
{
|
||||
uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount); //Not very sure about this
|
||||
uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount);
|
||||
reader.Align(128);
|
||||
|
||||
while (!reader.EndOfStream)
|
||||
{
|
||||
uint size = reader.ReadUInt32();
|
||||
//Now search for zlibbed chunks
|
||||
uint size = reader.ReadUInt32();
|
||||
ushort magic = reader.ReadUInt16();
|
||||
|
||||
long pos = reader.Position;
|
||||
ushort magic = reader.ReadUInt16();
|
||||
|
||||
reader.Position = 0;
|
||||
if (magic == 0x78da)
|
||||
return true;
|
||||
}
|
||||
reader.Position = 0;
|
||||
if (magic == 0x78da)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
reader.Position = 0;
|
||||
@ -99,11 +72,11 @@ namespace Toolbox.Library.IO
|
||||
using (var reader = new FileReader(stream, true))
|
||||
{
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
uint unk = reader.ReadUInt32();
|
||||
try
|
||||
{
|
||||
uint chunkSize = reader.ReadUInt32();
|
||||
uint chunkCount = reader.ReadUInt32();
|
||||
uint unk2 = reader.ReadUInt32();
|
||||
uint decompressedSize = reader.ReadUInt32();
|
||||
uint[] chunkSizes = reader.ReadUInt32s((int)chunkCount); //Not very sure about this
|
||||
|
||||
reader.Align(128);
|
||||
@ -141,11 +114,54 @@ namespace Toolbox.Library.IO
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Stream Compress(Stream stream, bool isBigEndian = true)
|
||||
{
|
||||
uint decompSize = (uint)stream.Length;
|
||||
uint[] section_sizes;
|
||||
uint sectionCount = 0;
|
||||
|
||||
var mem = new MemoryStream();
|
||||
using (var reader = new FileReader(stream, true))
|
||||
using (var writer = new FileWriter(mem, true))
|
||||
{
|
||||
writer.SetByteOrder(isBigEndian);
|
||||
|
||||
if (!(decompSize % 0x10000 != 0))
|
||||
sectionCount = decompSize / 0x10000;
|
||||
else
|
||||
sectionCount = (decompSize / 0x10000) + 1;
|
||||
|
||||
writer.Write(0x10000);
|
||||
writer.Write(sectionCount);
|
||||
writer.Write(decompSize);
|
||||
writer.Write(new uint[sectionCount]);
|
||||
writer.Align(128);
|
||||
|
||||
reader.SeekBegin(0);
|
||||
section_sizes = new uint[sectionCount];
|
||||
for (int i = 0; i < sectionCount; i++)
|
||||
{
|
||||
byte[] chunk = ZLIB.Compress(reader.ReadBytes(0x10000));
|
||||
|
||||
section_sizes[i] = (uint)chunk.Length;
|
||||
|
||||
writer.Write(chunk.Length);
|
||||
writer.Write(chunk);
|
||||
writer.Align(128);
|
||||
}
|
||||
|
||||
writer.SeekBegin(12);
|
||||
for (int i = 0; i < sectionCount; i++)
|
||||
writer.Write(section_sizes[i] + 4);
|
||||
}
|
||||
return mem;
|
||||
}
|
||||
}
|
||||
|
||||
public class ZLIB
|
||||
{
|
||||
public static byte[] Decompress(byte[] b)
|
||||
public static byte[] Decompress(byte[] b, bool hasMagic = true)
|
||||
{
|
||||
using (var br = new FileReader(new MemoryStream(b), true))
|
||||
{
|
||||
@ -156,7 +172,8 @@ namespace Toolbox.Library.IO
|
||||
else
|
||||
{
|
||||
var ms = new System.IO.MemoryStream();
|
||||
br.BaseStream.Position = 2;
|
||||
if (hasMagic)
|
||||
br.Position = 2;
|
||||
using (var ds = new DeflateStream(new MemoryStream(br.ReadBytes((int)br.BaseStream.Length - 6)), CompressionMode.Decompress))
|
||||
ds.CopyTo(ms);
|
||||
return ms.ToArray();
|
||||
@ -231,8 +248,11 @@ namespace Toolbox.Library.IO
|
||||
//Mario Tennis Aces Custom compression
|
||||
public class MTA_CUSTOM
|
||||
{
|
||||
[DllImport("Lib/LibTennis.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void DecompressBuffer(IntPtr output, IntPtr input, uint len);
|
||||
[DllImport("Lib/LibTennis32.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void DecompressBuffer32(IntPtr output, IntPtr input, uint len);
|
||||
|
||||
[DllImport("Lib/LibTennis64.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern void DecompressBuffer64(IntPtr output, IntPtr input, uint len);
|
||||
|
||||
public unsafe byte[] Decompress(byte[] input, uint decompressedLength)
|
||||
{
|
||||
@ -240,8 +260,10 @@ namespace Toolbox.Library.IO
|
||||
{
|
||||
fixed (byte* inputPtr = input)
|
||||
{
|
||||
DecompressBuffer((IntPtr)outputPtr, (IntPtr)inputPtr, decompressedLength);
|
||||
|
||||
if (Environment.Is64BitProcess)
|
||||
DecompressBuffer64((IntPtr)outputPtr, (IntPtr)inputPtr, decompressedLength);
|
||||
else
|
||||
DecompressBuffer32((IntPtr)outputPtr, (IntPtr)inputPtr, decompressedLength);
|
||||
// Decompress(outputPtr, inputPtr, decompressedLength);
|
||||
}
|
||||
|
||||
@ -277,9 +299,7 @@ namespace Toolbox.Library.IO
|
||||
for (int i = 0; i < 8; i++)
|
||||
*output++ = *data++;
|
||||
|
||||
var checkFinished = CheckFinished(data, end);
|
||||
data = checkFinished.data;
|
||||
end = checkFinished.end;
|
||||
CheckFinished(ref data, ref end);
|
||||
}
|
||||
|
||||
flag |= 0x800000;
|
||||
@ -302,11 +322,7 @@ namespace Toolbox.Library.IO
|
||||
flag <<= 1;
|
||||
|
||||
if (flag == 0)
|
||||
{
|
||||
var checkFinished2 = CheckFinished(data, end);
|
||||
data = checkFinished2.data;
|
||||
end = checkFinished2.end;
|
||||
}
|
||||
CheckFinished(ref data, ref end);
|
||||
|
||||
int op_ofs = (data[0] >> 4) | (data[1] << 4);
|
||||
int op_len = data[0] & 0xF;
|
||||
@ -329,14 +345,7 @@ namespace Toolbox.Library.IO
|
||||
op_len = op_len_ext + add_len;
|
||||
|
||||
if (op_ofs >= 2)
|
||||
{
|
||||
var loop1Data = Loop1(flag, op_len, chunk, data, output);
|
||||
flag = loop1Data.flag;
|
||||
op_len = loop1Data.op_len;
|
||||
chunk = loop1Data.chunk;
|
||||
data = loop1Data.data;
|
||||
output = loop1Data.output;
|
||||
}
|
||||
Loop1(ref flag, ref op_len, ref chunk, ref data, ref output);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -344,41 +353,19 @@ namespace Toolbox.Library.IO
|
||||
op_len = op_len_ext;
|
||||
if (op_ofs >= 2)
|
||||
{
|
||||
var loop1Data = Loop1(flag, op_len, chunk, data, output);
|
||||
flag = loop1Data.flag;
|
||||
op_len = loop1Data.op_len;
|
||||
chunk = loop1Data.chunk;
|
||||
data = loop1Data.data;
|
||||
output = loop1Data.output;
|
||||
Loop1(ref flag, ref op_len, ref chunk, ref data, ref output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var loop2Data2 = Loop2(flag, op_len, data, output, chunk);
|
||||
flag = loop2Data2.flag;
|
||||
op_len = loop2Data2.op_len;
|
||||
chunk = loop2Data2.chunk;
|
||||
data = loop2Data2.data;
|
||||
output = loop2Data2.output;
|
||||
Loop2(ref flag, ref op_len, ref data, ref output, ref chunk);
|
||||
}
|
||||
}
|
||||
|
||||
var endOp = EndOperation(data, end);
|
||||
data = endOp.data;
|
||||
end = endOp.end;
|
||||
EndOperation(ref data, ref end);
|
||||
}
|
||||
|
||||
private unsafe class Data
|
||||
{
|
||||
public uint flag;
|
||||
public int op_len;
|
||||
public byte* chunk;
|
||||
public byte* data;
|
||||
public byte* output;
|
||||
public byte* end;
|
||||
}
|
||||
|
||||
unsafe Data Loop1(uint flag, int op_len, byte* chunk, byte* data, byte* output)
|
||||
unsafe void Loop1(ref uint flag, ref int op_len, ref byte* chunk, ref byte* data, ref byte* output)
|
||||
{
|
||||
if ((((byte)*chunk ^ (byte)*output) & 1) == 0)
|
||||
{
|
||||
@ -436,10 +423,10 @@ namespace Toolbox.Library.IO
|
||||
}
|
||||
}
|
||||
|
||||
return Loop2(flag, op_len, data, output, chunk);
|
||||
Loop2(ref flag, ref op_len, ref data, ref output, ref chunk);
|
||||
}
|
||||
|
||||
unsafe Data Loop2(uint flag, int op_len, byte* data, byte* output, byte* chunk)
|
||||
unsafe void Loop2(ref uint flag, ref int op_len, ref byte* data, ref byte* output, ref byte* chunk)
|
||||
{
|
||||
int masked_len = op_len & 7;
|
||||
byte* out_ptr = output;
|
||||
@ -468,42 +455,21 @@ namespace Toolbox.Library.IO
|
||||
flag <<= 1;
|
||||
*output++ = *data++;
|
||||
}
|
||||
|
||||
return new Data()
|
||||
{
|
||||
flag = flag,
|
||||
op_len = op_len,
|
||||
data = data,
|
||||
output = output,
|
||||
chunk = chunk,
|
||||
};
|
||||
}
|
||||
|
||||
unsafe Data CheckFinished(byte* data, byte* end)
|
||||
unsafe void CheckFinished(ref byte* data, ref byte* end)
|
||||
{
|
||||
if (data >= end)
|
||||
return EndOperation(data, end);
|
||||
|
||||
return new Data()
|
||||
{
|
||||
data = data,
|
||||
end = end,
|
||||
};
|
||||
EndOperation(ref data, ref end);
|
||||
}
|
||||
|
||||
unsafe Data EndOperation(byte* data, byte* end)
|
||||
unsafe void EndOperation(ref byte* data, ref byte* end)
|
||||
{
|
||||
byte* ext = end + 0x20;
|
||||
if (data < ext)
|
||||
do
|
||||
*end-- = *--ext;
|
||||
while (data < ext);
|
||||
|
||||
return new Data()
|
||||
{
|
||||
data = data,
|
||||
end = end,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,6 @@ namespace Toolbox.Library
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Invalid hex format.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -26,37 +26,94 @@ namespace Toolbox.Library
|
||||
Dictionary<string, Vertex> VertexSkinSources = new Dictionary<string, Vertex>();
|
||||
Dictionary<string, Matrix4> MatrixSkinSources = new Dictionary<string, Matrix4>();
|
||||
|
||||
private Matrix4 GlobalTransform = Matrix4.Identity;
|
||||
public bool LoadFile(string FileName)
|
||||
{
|
||||
GlobalTransform = Matrix4.Identity;
|
||||
|
||||
COLLADA collada = COLLADA.Load(FileName);
|
||||
|
||||
//Check axis up
|
||||
if (collada.asset != null)
|
||||
{
|
||||
switch (collada.asset.up_axis)
|
||||
{
|
||||
case UpAxisType.X_UP:
|
||||
GlobalTransform = Matrix4.CreateRotationX(90);
|
||||
break;
|
||||
case UpAxisType.Y_UP:
|
||||
GlobalTransform = Matrix4.CreateRotationY(90);
|
||||
break;
|
||||
case UpAxisType.Z_UP:
|
||||
GlobalTransform = Matrix4.CreateRotationZ(90);
|
||||
break;
|
||||
}
|
||||
|
||||
if (collada.asset.unit != null)
|
||||
{
|
||||
var amount = collada.asset.unit.meter;
|
||||
var type = collada.asset.unit.name;
|
||||
if (type == "meter")
|
||||
{
|
||||
|
||||
}
|
||||
else if (type == "centimeter")
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var item in collada.Items)
|
||||
{
|
||||
if (item is library_geometries)
|
||||
{
|
||||
LoadGeometry((library_geometries)item);
|
||||
}
|
||||
if (item is library_images)
|
||||
LoadImages((library_images)item);
|
||||
if (item is library_controllers)
|
||||
LoadControllers((library_controllers)item);
|
||||
if (item is library_nodes)
|
||||
LoadNodes((library_nodes)item);
|
||||
if (item is library_visual_scenes)
|
||||
LoadVisualScenes((library_visual_scenes)item);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void SetControllers(COLLADA collada)
|
||||
private void LoadVisualScenes(library_visual_scenes nodes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void LoadNodes(library_nodes nodes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void LoadControllers(library_controllers controllers)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void LoadGeometry(library_geometries Geometries)
|
||||
private void LoadMaterials(library_materials materials)
|
||||
{
|
||||
foreach (var geom in Geometries.geometry)
|
||||
|
||||
}
|
||||
|
||||
private void LoadImages(library_images images)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void LoadGeometry(library_geometries geometries)
|
||||
{
|
||||
foreach (var geom in geometries.geometry)
|
||||
{
|
||||
var mesh = geom.Item as mesh;
|
||||
if (mesh == null)
|
||||
continue;
|
||||
|
||||
Console.WriteLine(geom.name);
|
||||
|
||||
foreach (var source in mesh.source)
|
||||
{
|
||||
var float_array = source.Item as float_array;
|
||||
@ -71,6 +128,11 @@ namespace Toolbox.Library
|
||||
}
|
||||
}
|
||||
|
||||
public bool ExportFile(string FileName, List<STGenericObject> meshes, STSkeleton skeleton = null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<STGenericObject> CreateGenericObjects(string Name, library_geometries Geometries)
|
||||
{
|
||||
List<STGenericObject> objects = new List<STGenericObject>();
|
||||
|
@ -22,7 +22,7 @@ namespace Toolbox.Library
|
||||
public Dictionary<string, uint> NameTables { get; set; }
|
||||
public Dictionary<uint, uint> Crc32Tables { get; set; }
|
||||
|
||||
private int ParseSize(string FilePath, byte[] Data = null, bool IsYaz0Compressed = false, bool Force = false)
|
||||
private int ParseSize(string FilePath, System.IO.Stream Data = null, bool IsYaz0Compressed = false, bool Force = false)
|
||||
{
|
||||
var size = new RSTB.SizeCalculator().CalculateFileSize(FilePath, Data, IsWiiU, IsYaz0Compressed, Force);
|
||||
if (size == 0)
|
||||
@ -36,7 +36,7 @@ namespace Toolbox.Library
|
||||
return size;
|
||||
}
|
||||
|
||||
public void SetEntry(string FileName, byte[] Data = null, bool IsYaz0Compressed = false, bool Force = false)
|
||||
public void SetEntry(string FileName, System.IO.Stream Data = null, bool IsYaz0Compressed = false, bool Force = false)
|
||||
{
|
||||
uint OldSize = GetSize(FileName);
|
||||
uint NewSize = (uint)ParseSize(FileName, Data, IsYaz0Compressed, Force) + 8192; //Add an additional set of bytes for some room
|
||||
@ -264,12 +264,12 @@ namespace Toolbox.Library
|
||||
float.TryParse(value, out output);
|
||||
}
|
||||
|
||||
public int CalculateFileSize(string FileName, byte[] Data, bool IsWiiU, bool IsYaz0Compressed, bool Force)
|
||||
public int CalculateFileSize(string FileName, System.IO.Stream Data, bool IsWiiU, bool IsYaz0Compressed, bool Force)
|
||||
{
|
||||
return CalculateFileSizeByExtension(FileName, Data, IsWiiU, System.IO.Path.GetExtension(FileName), IsYaz0Compressed, Force);
|
||||
}
|
||||
|
||||
private int CalculateFileSizeByExtension(string FileName, byte[] Data, bool WiiU, string Ext, bool IsYaz0Compressed, bool Force = false)
|
||||
private int CalculateFileSizeByExtension(string FileName, System.IO.Stream Data, bool WiiU, string Ext, bool IsYaz0Compressed, bool Force = false)
|
||||
{
|
||||
int Size = 0;
|
||||
if (System.IO.File.Exists(FileName))
|
||||
@ -292,7 +292,7 @@ namespace Toolbox.Library
|
||||
{
|
||||
if (IsYaz0Compressed)
|
||||
{
|
||||
using (var reader = new FileReader(new System.IO.MemoryStream(Data)))
|
||||
using (var reader = new FileReader(Data, true))
|
||||
{
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
reader.Seek(4, System.IO.SeekOrigin.Begin);
|
||||
@ -301,11 +301,11 @@ namespace Toolbox.Library
|
||||
}
|
||||
else
|
||||
{
|
||||
Size = Data.Length;
|
||||
Size = (int)Data.Length;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] FileData = Data;
|
||||
byte[] FileData = Data.ToBytes();
|
||||
|
||||
Size = (Size + 31) & -32;
|
||||
string ActualExt = Ext.Replace(".s", ".").Remove(0,1);
|
||||
@ -317,7 +317,7 @@ namespace Toolbox.Library
|
||||
if (System.IO.File.Exists(FileName))
|
||||
FileData = EveryFileExplorer.YAZ0.Decompress(FileName);
|
||||
else if (Data != null)
|
||||
FileData = EveryFileExplorer.YAZ0.Decompress(Data);
|
||||
FileData = EveryFileExplorer.YAZ0.Decompress(FileData);
|
||||
}
|
||||
|
||||
if (WiiU)
|
||||
|
@ -50,7 +50,7 @@ namespace Toolbox.Library
|
||||
private IFileFormat OpenFile()
|
||||
{
|
||||
return STFileLoader.OpenFileFormat(new FileStream(filePath, FileMode.Open, FileAccess.Read),
|
||||
filePath, null, true);
|
||||
filePath, true);
|
||||
}
|
||||
|
||||
public override void OnDoubleMouseClick(TreeView treeview)
|
||||
|
16
Switch_Toolbox_Library/FileSystem/VirtualFileTreeNode.cs
Normal file
16
Switch_Toolbox_Library/FileSystem/VirtualFileTreeNode.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// A class that generates treenodes on expand based on it's children
|
||||
/// </summary>
|
||||
public class VirtualFileTreeNode
|
||||
{
|
||||
|
||||
}
|
||||
}
|
15
Switch_Toolbox_Library/FileSystem/VirtualTreeNode.cs
Normal file
15
Switch_Toolbox_Library/FileSystem/VirtualTreeNode.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Toolbox.Library
|
||||
{
|
||||
public class VirtualTreeNode
|
||||
{
|
||||
public VirtualTreeNode Parent;
|
||||
|
||||
public List<VirtualTreeNode> Children;
|
||||
}
|
||||
}
|
@ -23,7 +23,16 @@ namespace Toolbox.Library
|
||||
public static Type[] GetCompressionFormats()
|
||||
{
|
||||
List<Type> Formats = new List<Type>();
|
||||
Formats.Add(typeof(Gzip));
|
||||
Formats.Add(typeof(lz4));
|
||||
Formats.Add(typeof(LZ4F));
|
||||
Formats.Add(typeof(LZSS));
|
||||
Formats.Add(typeof(YAY0));
|
||||
Formats.Add(typeof(Yaz0));
|
||||
Formats.Add(typeof(Zlib));
|
||||
Formats.Add(typeof(ZlibGZ));
|
||||
Formats.Add(typeof(Zstb));
|
||||
|
||||
return Formats.ToArray();
|
||||
}
|
||||
}
|
||||
|
@ -226,6 +226,7 @@ namespace Toolbox.Library
|
||||
v.uv2 = (v.uv2 * Scale) + Translate;
|
||||
}
|
||||
}
|
||||
|
||||
public void CalculateTangentBitangent(bool UseUVLayer2)
|
||||
{
|
||||
if (vertices.Count < 3)
|
||||
|
@ -27,6 +27,7 @@ namespace Toolbox.Library.IO
|
||||
{
|
||||
using (var fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Write))
|
||||
{
|
||||
stream.Position = 0;
|
||||
stream.CopyTo(fileStream);
|
||||
}
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ namespace Toolbox.Library.IO
|
||||
this.Position = 0;
|
||||
}
|
||||
|
||||
public FileReader(string fileName)
|
||||
: this(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
public FileReader(string fileName, bool leaveOpen = false)
|
||||
: this(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), leaveOpen)
|
||||
{
|
||||
this.Position = 0;
|
||||
}
|
||||
@ -30,6 +30,8 @@ namespace Toolbox.Library.IO
|
||||
this.Position = 0;
|
||||
}
|
||||
|
||||
public bool IsBigEndian => ByteOrder == ByteOrder.BigEndian;
|
||||
|
||||
//Checks signature (no stream advancement)
|
||||
public bool CheckSignature(int length, string Identifier, long position = 0)
|
||||
{
|
||||
|
@ -100,6 +100,20 @@ namespace Toolbox.Library.IO
|
||||
SeekBegin(pos + fixedSize);
|
||||
}
|
||||
|
||||
public void Write(object value, long pos)
|
||||
{
|
||||
using (TemporarySeek(pos, SeekOrigin.Begin)) {
|
||||
if (value is uint) Write((uint)value);
|
||||
else if (value is int) Write((int)value);
|
||||
else if (value is long) Write((long)value);
|
||||
else if (value is ulong) Write((ulong)value);
|
||||
else if (value is ushort) Write((ushort)value);
|
||||
else if (value is short) Write((short)value);
|
||||
else if (value is sbyte) Write((sbyte)value);
|
||||
else if (value is byte) Write((byte)value);
|
||||
}
|
||||
}
|
||||
|
||||
//Writes the total size of a section as a uint.
|
||||
public void WriteSectionSizeU32(long position, long startPosition, long endPosition)
|
||||
{
|
||||
|
@ -20,10 +20,10 @@ namespace Toolbox.Library.IO
|
||||
/// <param name="Compressed">If the file is being compressed or not</param>
|
||||
/// <param name="CompType">The type of <see cref="CompressionType"/> being used</param>
|
||||
/// <returns></returns>
|
||||
public static TreeNode GetNodeFileFormat(string FileName, byte[] data = null, bool InArchive = false,
|
||||
TreeNode archiveNode = null, bool LeaveStreamOpen = false, bool Compressed = false, CompressionType CompType = 0)
|
||||
public static TreeNode GetNodeFileFormat(string FileName, bool InArchive = false,
|
||||
bool LeaveStreamOpen = false, bool Compressed = false, ICompressionFormat CompressionFormat = null)
|
||||
{
|
||||
IFileFormat format = OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode);
|
||||
IFileFormat format = OpenFileFormat(FileName, LeaveStreamOpen, InArchive);
|
||||
|
||||
if (format is TreeNode)
|
||||
return (TreeNode)format;
|
||||
@ -76,7 +76,7 @@ namespace Toolbox.Library.IO
|
||||
if (fileFormat.Identify(stream) && fileFormat.GetType() == type)
|
||||
{
|
||||
fileFormat.IFileInfo = new IFileInfo();
|
||||
return OpenFileFormat(FileName, data);
|
||||
return OpenFileFormat(new MemoryStream(data), FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,7 +97,7 @@ namespace Toolbox.Library.IO
|
||||
foreach (IFileFormat fileFormat in FileManager.GetFileFormats())
|
||||
{
|
||||
if (fileFormat.GetType() == FileType)
|
||||
return OpenFileFormat(FileName, data);
|
||||
return OpenFileFormat(stream, FileName);
|
||||
}
|
||||
|
||||
return null;
|
||||
@ -139,9 +139,9 @@ namespace Toolbox.Library.IO
|
||||
if (MagicHex == 0x28B52FFD || MagicHex == 0xFD2FB528)
|
||||
{
|
||||
if (data != null)
|
||||
return STLibraryCompression.ZSTD.Decompress(data);
|
||||
return Zstb.SDecompress(data);
|
||||
else
|
||||
return STLibraryCompression.ZSTD.Decompress(File.ReadAllBytes(FileName));
|
||||
return Zstb.SDecompress(File.ReadAllBytes(FileName));
|
||||
}
|
||||
|
||||
return data;
|
||||
@ -157,17 +157,11 @@ namespace Toolbox.Library.IO
|
||||
/// <param name="Compressed">If the file is being compressed or not</param>
|
||||
/// <param name="CompType">The type of <see cref="CompressionType"/> being used</param>
|
||||
/// <returns></returns>
|
||||
public static IFileFormat OpenFileFormat(string FileName, byte[] data = null, bool LeaveStreamOpen = false, bool InArchive = false,
|
||||
TreeNode archiveNode = null, bool Compressed = false, CompressionType CompType = 0, uint DecompressedSize = 0, uint CompressedSize = 0)
|
||||
public static IFileFormat OpenFileFormat(string FileName, bool LeaveStreamOpen = false, bool InArchive = false,
|
||||
bool Compressed = false, ICompressionFormat CompressionFormat = null, uint DecompressedSize = 0, uint CompressedSize = 0)
|
||||
{
|
||||
Stream stream;
|
||||
if (data != null)
|
||||
stream = new MemoryStream(data);
|
||||
else
|
||||
stream = File.OpenRead(FileName);
|
||||
|
||||
return OpenFileFormat(stream, FileName, data, LeaveStreamOpen, InArchive,
|
||||
archiveNode, Compressed, CompType, DecompressedSize, CompressedSize);
|
||||
return OpenFileFormat(File.OpenRead(FileName), FileName, LeaveStreamOpen, InArchive,
|
||||
Compressed, CompressionFormat, DecompressedSize, CompressedSize);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -176,185 +170,37 @@ namespace Toolbox.Library.IO
|
||||
/// <param name="FileName">The name of the file</param>
|
||||
/// <param name="data">The byte array of the data</param>
|
||||
/// <param name="InArchive">If the file is in an archive so it can be saved back</param>
|
||||
/// <param name="archiveNode">The node being replaced from an archive</param>
|
||||
/// <param name="Compressed">If the file is being compressed or not</param>
|
||||
/// <param name="CompType">The type of <see cref="CompressionType"/> being used</param>
|
||||
/// <param name="CompressionFormat">The type of <see cref="ICompressionFormat"/> being used</param>
|
||||
/// <returns></returns>
|
||||
public static IFileFormat OpenFileFormat(Stream stream, string FileName, byte[] data = null, bool LeaveStreamOpen = false, bool InArchive = false,
|
||||
TreeNode archiveNode = null, bool Compressed = false, CompressionType CompType = 0, uint DecompressedSize = 0, uint CompressedSize = 0)
|
||||
public static IFileFormat OpenFileFormat(Stream stream, string FileName, bool LeaveStreamOpen = false, bool InArchive = false,
|
||||
bool Compressed = false, ICompressionFormat CompressionFormat = null, long DecompressedSize = 0, long CompressedSize = 0)
|
||||
{
|
||||
uint DecompressedFileSize = 0;
|
||||
uint CompressedFileSize = 0;
|
||||
if (!Compressed)
|
||||
DecompressedSize = stream.Length;
|
||||
|
||||
using (var fileReader = new FileReader(stream, true))
|
||||
long streamStartPos = stream.Position;
|
||||
|
||||
//Check all supported compression formats and decompress. Then loop back
|
||||
if (!Compressed)
|
||||
{
|
||||
if (CompType == CompressionType.None)
|
||||
DecompressedFileSize = (uint)fileReader.BaseStream.Length;
|
||||
if (CompType != CompressionType.None)
|
||||
CompressedFileSize = (uint)fileReader.BaseStream.Length;
|
||||
|
||||
if (fileReader.BaseStream.Length <= 4)
|
||||
{
|
||||
fileReader.Close();
|
||||
fileReader.Dispose();
|
||||
return null;
|
||||
}
|
||||
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
fileReader.ByteOrder = ByteOrder.BigEndian;
|
||||
uint MagicHex = fileReader.ReadUInt32();
|
||||
|
||||
string Magic = fileReader.ReadMagic(0, 4);
|
||||
|
||||
fileReader.Position = 0;
|
||||
ushort MagicHex2 = fileReader.ReadUInt16();
|
||||
|
||||
//Another hacky magic check if decomp size is first
|
||||
fileReader.Position = 4;
|
||||
ushort MagicHex3 = fileReader.ReadUInt16();
|
||||
|
||||
//Note this method will soon be how all compression formats are handled rather than being checked here
|
||||
foreach (ICompressionFormat compressionFormat in FileManager.GetCompressionFormats())
|
||||
{
|
||||
if (compressionFormat.Identify(stream))
|
||||
stream.Position = streamStartPos;
|
||||
if (compressionFormat.Identify(stream, FileName))
|
||||
{
|
||||
stream.Position = streamStartPos;
|
||||
|
||||
stream = compressionFormat.Decompress(stream);
|
||||
CompressedSize = stream.Length;
|
||||
|
||||
return OpenFileFormat(stream, FileName, LeaveStreamOpen, InArchive,
|
||||
true, compressionFormat, DecompressedSize, CompressedSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (Magic == "Yaz0")
|
||||
{
|
||||
data = EveryFileExplorer.YAZ0.Decompress(stream.ToArray());
|
||||
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Yaz0, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (Path.GetExtension(FileName) == ".cbtex")
|
||||
{
|
||||
fileReader.Position = 0;
|
||||
byte compType = fileReader.ReadByte();
|
||||
if (compType == 0x50)
|
||||
{
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
fileReader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
|
||||
fileReader.Seek(4, System.IO.SeekOrigin.Begin);
|
||||
uint decompSize = fileReader.ReadUInt32();
|
||||
uint compSize = (uint)fileReader.BaseStream.Length - 8;
|
||||
|
||||
var comp = new STLibraryCompression.MTA_CUSTOM();
|
||||
data = comp.Decompress(data, decompSize);
|
||||
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.MarioTennisCustom, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
fileReader.Position = 0;
|
||||
}
|
||||
if (Path.GetExtension(FileName) == ".lz")
|
||||
{
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
data = LZ77_WII.Decompress(fileReader.getSection(16, data.Length - 16));
|
||||
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Yaz0, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (MagicHex == 0x28B52FFD || MagicHex == 0xFD2FB528)
|
||||
{
|
||||
if (data != null)
|
||||
data = STLibraryCompression.ZSTD.Decompress(fileReader.getSection(0, data.Length));
|
||||
else
|
||||
data = STLibraryCompression.ZSTD.Decompress(File.ReadAllBytes(FileName));
|
||||
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Zstb, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (Magic == "ZCMP" || MagicHex2 == 0x789C || MagicHex2 == 0x78DA || Path.GetExtension(FileName) == ".z" && CompType == CompressionType.None)
|
||||
{
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
data = STLibraryCompression.ZLIB.Decompress(data);
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (MagicHex3 == 0x789C || MagicHex3 == 0x78DA && CompType == CompressionType.None)
|
||||
{
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
fileReader.Position = 0;
|
||||
int OuSize = fileReader.ReadInt32();
|
||||
int InSize = data.Length - 4;
|
||||
data = STLibraryCompression.ZLIB.Decompress(fileReader.getSection(4, InSize));
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (Path.GetExtension(FileName) == ".carc" && CompType == CompressionType.None)
|
||||
{
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
data = STLibraryCompression.ZLIB.Decompress(fileReader.getSection(0x10, data.Length - 0x10));
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (Magic == "ZLIB")
|
||||
{
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
data = STLibraryCompression.GZIP.Decompress(fileReader.getSection(64, data.Length - 64));
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (MagicHex == 0x1f8b0808 || MagicHex2 == 0x1f8b && CompType == CompressionType.None)
|
||||
{
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
data = STLibraryCompression.GZIP.Decompress(data);
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Gzip, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (MagicHex == 0x184D2204)
|
||||
{
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
data = STLibraryCompression.Type_LZ4.Decompress(data);
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Lz4, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (Path.GetExtension(FileName) == ".lz" && CompType == CompressionType.None)
|
||||
{
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
data = STLibraryCompression.LZ77.Decompress(fileReader.getSection(16, data.Length - 16));
|
||||
return OpenFileFormat(FileName, data, LeaveStreamOpen, InArchive, archiveNode, true,
|
||||
CompressionType.Zlib, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
if (Path.GetExtension(FileName) == ".cmp" && CompType == CompressionType.None)
|
||||
{
|
||||
if (stream != null)
|
||||
data = stream.ToArray();
|
||||
if (data == null)
|
||||
data = File.ReadAllBytes(FileName);
|
||||
|
||||
fileReader.Position = 0;
|
||||
int OuSize = fileReader.ReadInt32();
|
||||
int InSize = data.Length - 4;
|
||||
data = STLibraryCompression.Type_LZ4F.Decompress(fileReader.getSection(4, InSize));
|
||||
|
||||
return OpenFileFormat(FileName, data, InArchive, LeaveStreamOpen, archiveNode, true,
|
||||
CompressionType.Lz4f, DecompressedFileSize, CompressedFileSize);
|
||||
}
|
||||
}
|
||||
|
||||
stream.Position = streamStartPos;
|
||||
foreach (IFileFormat fileFormat in FileManager.GetFileFormats())
|
||||
{
|
||||
//Set the file name so we can check it's extension in the identifier.
|
||||
@ -365,9 +211,9 @@ namespace Toolbox.Library.IO
|
||||
if (fileFormat.Identify(stream))
|
||||
{
|
||||
fileFormat.IFileInfo = new IFileInfo();
|
||||
fileFormat.IFileInfo.DecompressedSize = DecompressedFileSize;
|
||||
fileFormat.IFileInfo.CompressedSize = CompressedFileSize;
|
||||
return SetFileFormat(fileFormat, FileName, stream, LeaveStreamOpen, InArchive, archiveNode, Compressed, CompType);
|
||||
fileFormat.IFileInfo.DecompressedSize = (uint)DecompressedSize;
|
||||
fileFormat.IFileInfo.CompressedSize = (uint)CompressedSize;
|
||||
return SetFileFormat(fileFormat, FileName, stream, LeaveStreamOpen, InArchive, Compressed, CompressionFormat);
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,27 +221,15 @@ namespace Toolbox.Library.IO
|
||||
}
|
||||
|
||||
private static IFileFormat SetFileFormat(IFileFormat fileFormat, string FileName, Stream stream, bool LeaveStreamOpen = false, bool InArchive = false,
|
||||
TreeNode archiveNode = null, bool Compressed = false, CompressionType CompType = 0)
|
||||
bool Compressed = false, ICompressionFormat FileCompression = null)
|
||||
{
|
||||
fileFormat.IFileInfo.CompressionType = CompType;
|
||||
fileFormat.IFileInfo.FileCompression = FileCompression;
|
||||
fileFormat.IFileInfo.FileIsCompressed = Compressed;
|
||||
fileFormat.FileName = Path.GetFileName(FileName);
|
||||
fileFormat.FilePath = FileName;
|
||||
fileFormat.IFileInfo.InArchive = InArchive;
|
||||
fileFormat.IFileInfo.FileIsCompressed = Compressed;
|
||||
if (Compressed)
|
||||
fileFormat.IFileInfo.CompressionType = CompType;
|
||||
|
||||
fileFormat.Load(stream);
|
||||
if (fileFormat is TreeNode)
|
||||
{
|
||||
if (archiveNode != null)
|
||||
{
|
||||
((TreeNode)fileFormat).Text = archiveNode.Text;
|
||||
((TreeNode)fileFormat).ImageKey = archiveNode.ImageKey;
|
||||
((TreeNode)fileFormat).SelectedImageKey = archiveNode.SelectedImageKey;
|
||||
}
|
||||
}
|
||||
//After file has been loaded and read, we'll dispose unless left open
|
||||
|
||||
if (fileFormat is ILeaveOpenOnLoad) {
|
||||
|
@ -33,25 +33,28 @@ namespace Toolbox.Library.IO
|
||||
//Also make compression require streams
|
||||
var mem = new System.IO.MemoryStream();
|
||||
FileFormat.Save(mem);
|
||||
mem = new System.IO.MemoryStream(mem.ToArray());
|
||||
|
||||
byte[] data = mem.ToArray();
|
||||
FileFormat.IFileInfo.DecompressedSize = (uint)data.Length;
|
||||
FileFormat.IFileInfo.DecompressedSize = (uint)mem.Length;
|
||||
|
||||
data = CompressFileFormat(data,
|
||||
var finalStream = CompressFileFormat(
|
||||
FileFormat.IFileInfo.FileCompression,
|
||||
mem,
|
||||
FileFormat.IFileInfo.FileIsCompressed,
|
||||
FileFormat.IFileInfo.Alignment,
|
||||
FileFormat.IFileInfo.CompressionType,
|
||||
FileName,
|
||||
EnableDialog);
|
||||
|
||||
FileFormat.IFileInfo.CompressedSize = (uint)data.Length;
|
||||
FileFormat.IFileInfo.CompressedSize = (uint)finalStream.Length;
|
||||
finalStream.ExportToFile(FileName);
|
||||
|
||||
File.WriteAllBytes(FileName, data);
|
||||
|
||||
DetailsLog += "\n" + SatisfyFileTables(FileFormat, FileName, data,
|
||||
DetailsLog += "\n" + SatisfyFileTables(FileFormat, FileName, finalStream,
|
||||
FileFormat.IFileInfo.DecompressedSize,
|
||||
FileFormat.IFileInfo.CompressedSize,
|
||||
FileFormat.IFileInfo.FileIsCompressed);
|
||||
|
||||
finalStream.Flush();
|
||||
finalStream.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -88,7 +91,7 @@ namespace Toolbox.Library.IO
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
|
||||
private static string SatisfyFileTables(IFileFormat FileFormat, string FilePath, byte[] Data, uint DecompressedSize, uint CompressedSize, bool IsYaz0Compressed)
|
||||
private static string SatisfyFileTables(IFileFormat FileFormat, string FilePath, Stream Data, uint DecompressedSize, uint CompressedSize, bool IsYaz0Compressed)
|
||||
{
|
||||
string FileLog = "";
|
||||
|
||||
@ -210,39 +213,45 @@ namespace Toolbox.Library.IO
|
||||
|
||||
|
||||
|
||||
public static void SaveFileFormat(byte[] data, bool FileIsCompressed, int Alignment,
|
||||
CompressionType CompressionType, string FileName, bool EnableDialog = true, string DetailsLog = "")
|
||||
public static void SaveFileFormat(byte[] data, bool FileIsCompressed, ICompressionFormat CompressionFormat,
|
||||
int Alignment, string FileName, bool EnableDialog = true, string DetailsLog = "")
|
||||
{
|
||||
uint DecompressedSize = (uint)data.Length;
|
||||
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
byte[] FinalData = CompressFileFormat(data, FileIsCompressed, Alignment, CompressionType, FileName, EnableDialog);
|
||||
File.WriteAllBytes(FileName, FinalData);
|
||||
Stream FinalData = CompressFileFormat(CompressionFormat, new MemoryStream(data), FileIsCompressed, Alignment, FileName, EnableDialog);
|
||||
FinalData.ExportToFile(FileName);
|
||||
|
||||
uint CompressedSize = (uint)FinalData.Length;
|
||||
|
||||
DetailsLog += "\n" + SatisfyFileTables(null, FileName, data,
|
||||
DetailsLog += "\n" + SatisfyFileTables(null, FileName, new MemoryStream(data),
|
||||
DecompressedSize,
|
||||
CompressedSize,
|
||||
FileIsCompressed);
|
||||
|
||||
FinalData.Flush();
|
||||
FinalData.Close();
|
||||
|
||||
MessageBox.Show($"File has been saved to {FileName}", "Save Notification");
|
||||
|
||||
// STSaveLogDialog.Show($"File has been saved to {FileName}", "Save Notification", DetailsLog);
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
|
||||
private static byte[] CompressFileFormat(byte[] data, bool FileIsCompressed, int Alignment,
|
||||
CompressionType CompressionType, string FileName, bool EnableDialog = true)
|
||||
private static Stream CompressFileFormat(ICompressionFormat compressionFormat, Stream data, bool FileIsCompressed, int Alignment,
|
||||
string FileName, bool EnableDialog = true)
|
||||
{
|
||||
string extension = Path.GetExtension(FileName);
|
||||
|
||||
if (extension == ".szs" || extension == ".sbfres")
|
||||
{
|
||||
FileIsCompressed = true;
|
||||
CompressionType = CompressionType.Yaz0;
|
||||
compressionFormat = new Yaz0();
|
||||
}
|
||||
|
||||
if (compressionFormat == null)
|
||||
return data;
|
||||
|
||||
bool CompressFile = false;
|
||||
if (EnableDialog && FileIsCompressed)
|
||||
{
|
||||
@ -250,38 +259,17 @@ namespace Toolbox.Library.IO
|
||||
CompressFile = true;
|
||||
else
|
||||
{
|
||||
DialogResult save = MessageBox.Show($"Compress file with {CompressionType}?", "File Save", MessageBoxButtons.YesNo);
|
||||
DialogResult save = MessageBox.Show($"Compress file with {compressionFormat}?", "File Save", MessageBoxButtons.YesNo);
|
||||
CompressFile = (save == DialogResult.Yes);
|
||||
}
|
||||
}
|
||||
else if (FileIsCompressed)
|
||||
CompressFile = true;
|
||||
|
||||
Console.WriteLine($"FileIsCompressed {FileIsCompressed} CompressFile {CompressFile} CompressionType {CompressionType}");
|
||||
Console.WriteLine($"FileIsCompressed {FileIsCompressed} CompressFile {CompressFile} CompressionType {compressionFormat}");
|
||||
|
||||
if (CompressFile)
|
||||
{
|
||||
switch (CompressionType)
|
||||
{
|
||||
case CompressionType.Yaz0:
|
||||
return EveryFileExplorer.YAZ0.Compress(data, Runtime.Yaz0CompressionLevel, (uint)Alignment);
|
||||
case CompressionType.Zstb:
|
||||
return STLibraryCompression.ZSTD.Compress(data);
|
||||
case CompressionType.Lz4:
|
||||
return STLibraryCompression.Type_LZ4.Compress(data);
|
||||
case CompressionType.Lz4f:
|
||||
return STLibraryCompression.Type_LZ4F.Compress(data);
|
||||
case CompressionType.Gzip:
|
||||
return STLibraryCompression.GZIP.Compress(data);
|
||||
case CompressionType.Zlib:
|
||||
return STLibraryCompression.ZLIB.Compress(data, 2);
|
||||
case CompressionType.None:
|
||||
return data;
|
||||
default:
|
||||
MessageBox.Show($"Compression Type {CompressionType} not supported!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return compressionFormat.Compress(data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
@ -85,12 +85,12 @@ namespace Toolbox.Library
|
||||
if (FileDataStream != null)
|
||||
{
|
||||
return STFileLoader.OpenFileFormat(FileDataStream,
|
||||
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), null, true, true);
|
||||
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), true, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
return STFileLoader.OpenFileFormat(
|
||||
IOExtensions.RemoveIllegaleFolderNameCharacters(FileName), FileData, false, true);
|
||||
return STFileLoader.OpenFileFormat(new MemoryStream(FileData),
|
||||
IOExtensions.RemoveIllegaleFolderNameCharacters( FileName), false, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ namespace Toolbox.Library
|
||||
string[] Description { get; set; }
|
||||
string[] Extension { get; set; }
|
||||
|
||||
bool Identify(Stream stream);
|
||||
bool Identify(Stream stream, string fileName);
|
||||
bool CanCompress { get; }
|
||||
|
||||
Stream Decompress(Stream stream);
|
||||
|
@ -56,7 +56,7 @@ namespace Toolbox.Library
|
||||
}
|
||||
public class IFileInfo
|
||||
{
|
||||
public CompressionType CompressionType { get; set; }
|
||||
public ICompressionFormat FileCompression { get; set; }
|
||||
public IArchiveFile ArchiveParent { get; set; }
|
||||
public bool FileIsCompressed { get; set; }
|
||||
public bool FileIsEdited { get; set; }
|
||||
|
@ -218,23 +218,31 @@
|
||||
<Compile Include="Compression\7ZIP\LZ\LzBinTree.cs" />
|
||||
<Compile Include="Compression\7ZIP\LZ\LzInWindow.cs" />
|
||||
<Compile Include="Compression\7ZIP\LZ\LzOutWindow.cs" />
|
||||
<Compile Include="Compression\LZ4F.cs" />
|
||||
<Compile Include="Compression\Formats\Gzip.cs" />
|
||||
<Compile Include="Compression\Formats\lz4.cs" />
|
||||
<Compile Include="Compression\Formats\LZ4F.cs" />
|
||||
<Compile Include="Compression\Formats\LZMA.cs" />
|
||||
<Compile Include="Compression\Formats\ZlibGZ.cs" />
|
||||
<Compile Include="Compression\Formats\Zstb.cs" />
|
||||
<Compile Include="Compression\LZ77_WII.cs" />
|
||||
<Compile Include="Compression\7ZIP\LZMA\LzmaBase.cs" />
|
||||
<Compile Include="Compression\7ZIP\LZMA\LzmaDecoder.cs" />
|
||||
<Compile Include="Compression\7ZIP\LZMA\LzmaEncoder.cs" />
|
||||
<Compile Include="Compression\LZSS.cs" />
|
||||
<Compile Include="Compression\MIO0.cs" />
|
||||
<Compile Include="Compression\Formats\LZSS.cs" />
|
||||
<Compile Include="Compression\Formats\MIO0.cs" />
|
||||
<Compile Include="Compression\7ZIP\RangeCoder\RangeCoder.cs" />
|
||||
<Compile Include="Compression\7ZIP\RangeCoder\RangeCoderBit.cs" />
|
||||
<Compile Include="Compression\7ZIP\RangeCoder\RangeCoderBitTree.cs" />
|
||||
<Compile Include="Compression\STLibraryCompression.cs" />
|
||||
<Compile Include="Compression\Yay0.cs" />
|
||||
<Compile Include="Compression\Yaz0.cs" />
|
||||
<Compile Include="Compression\ZCMP.cs" />
|
||||
<Compile Include="Compression\Formats\Yay0.cs" />
|
||||
<Compile Include="Compression\Formats\Yaz0.cs" />
|
||||
<Compile Include="Compression\Formats\ZCMP.cs" />
|
||||
<Compile Include="Compression\Formats\Zlib.cs" />
|
||||
<Compile Include="Config.cs" />
|
||||
<Compile Include="Enums\CompressionType.cs" />
|
||||
<Compile Include="FileFormats\DDS\RGBAPixelDecoder.cs" />
|
||||
<Compile Include="FileSystem\VirtualFileTreeNode.cs" />
|
||||
<Compile Include="FileSystem\VirtualTreeNode.cs" />
|
||||
<Compile Include="Forms\ColorAlphaBox.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
BIN
Toolbox/Lib/LibTennis64.dll
Normal file
BIN
Toolbox/Lib/LibTennis64.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -29,7 +29,6 @@ void main()
|
||||
if (debugShading == 0)
|
||||
{
|
||||
vec4 colorBlend = textureMap0 * whiteColor;
|
||||
vec3 blackBlend = (vec3(1) - textureMap0.rgb) + blackColor.rgb;
|
||||
fragColor = vertexColor0 * colorBlend;
|
||||
}
|
||||
else if (debugShading == 5)
|
||||
|
@ -21,9 +21,12 @@ void main()
|
||||
|
||||
if (debugShading == 0)
|
||||
{
|
||||
vec4 colorBlend = textureMap0 * whiteColor;
|
||||
vec3 blackBlend = (vec3(1) - textureMap0.rgb) + blackColor.rgb;
|
||||
gl_FragColor = gl_Color * colorBlend;
|
||||
vec3 whiteInterpolation = mix(textureMap0.rgb, whiteColor.rgb, vec3(1));
|
||||
vec3 blackInterpolation = mix(vec3(1) - textureMap0.rgb, blackColor.rgb, vec3(1));
|
||||
|
||||
vec3 colorBlend = textureMap0.rgb * whiteColor.rgb;
|
||||
float alpha = textureMap0.a * whiteColor.a;
|
||||
gl_FragColor = gl_Color * vec4(colorBlend,alpha);
|
||||
}
|
||||
else if (debugShading == 5)
|
||||
gl_FragColor = vec4(textureMap0.rgb, 1);
|
||||
|
@ -406,7 +406,10 @@
|
||||
<Content Include="Lib\LibHac.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Lib\LibTennis.dll">
|
||||
<Content Include="Lib\LibTennis32.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Lib\LibTennis64.dll">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Lib\Licenses\7ZIP LZMA LICENSE.txt">
|
||||
|
Loading…
Reference in New Issue
Block a user