Cleanup with new open/save methods. Also add gtx rebuilding.
This commit is contained in:
parent
364c9ceeed
commit
d96f4dec43
@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Switch_Toolbox;
|
||||
using System.Windows.Forms;
|
||||
using Switch_Toolbox.Library;
|
||||
using Switch_Toolbox.Library.IO;
|
||||
using BarsLib;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using VGAudio.Formats;
|
||||
@ -190,10 +190,28 @@ namespace FirstPlugin
|
||||
|
||||
Nodes[1].Nodes.Add(node);
|
||||
}
|
||||
|
||||
ContextMenu = new ContextMenu();
|
||||
MenuItem save = new MenuItem("Save");
|
||||
ContextMenu.MenuItems.Add(save);
|
||||
save.Click += Save;
|
||||
}
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
}
|
||||
private void Save(object sender, EventArgs args)
|
||||
{
|
||||
List<IFileFormat> formats = new List<IFileFormat>();
|
||||
|
||||
SaveFileDialog sfd = new SaveFileDialog();
|
||||
sfd.Filter = Utils.GetAllFilters(formats);
|
||||
sfd.FileName = FileName;
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
STFileSaver.SaveFileFormat(this, sfd.FileName);
|
||||
}
|
||||
}
|
||||
public byte[] Save()
|
||||
{
|
||||
|
@ -8,7 +8,6 @@ using System.Windows.Forms;
|
||||
using Switch_Toolbox.Library;
|
||||
using System.IO;
|
||||
using BezelEngineArchive_Lib;
|
||||
using ZstdNet;
|
||||
using Switch_Toolbox.Library.IO;
|
||||
using Switch_Toolbox.Library.Forms;
|
||||
|
||||
@ -79,23 +78,23 @@ namespace FirstPlugin
|
||||
bea.FileName = file;
|
||||
bea.Load();
|
||||
|
||||
foreach (var asset in beaFile.FileList.Values)
|
||||
foreach (FileEntry asset in bea.Nodes)
|
||||
{
|
||||
if (Path.GetExtension(asset.FileName) == ".lua")
|
||||
if (Path.GetExtension(asset.FullName) == ".lua")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(Path.GetDirectoryName($"{folderPath}/{beaFile.Name}/{asset.FileName}")))
|
||||
if (!String.IsNullOrWhiteSpace(Path.GetDirectoryName($"{folderPath}/{bea.Name}/{asset.FullName}")))
|
||||
{
|
||||
if (!File.Exists(asset.FileName))
|
||||
if (!File.Exists(asset.FullName))
|
||||
{
|
||||
if (!Directory.Exists($"{folderPath}/{beaFile.Name}/{asset.FileName}"))
|
||||
if (!Directory.Exists($"{folderPath}/{bea.Name}/{asset.FullName}"))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName($"{folderPath}/{beaFile.Name}/{asset.FileName}"));
|
||||
Directory.CreateDirectory(Path.GetDirectoryName($"{folderPath}/{bea.Name}/{asset.FullName}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
File.WriteAllBytes($"{folderPath}/{beaFile.Name}/{asset.FileName}", GetASSTData(asset.FileName));
|
||||
File.WriteAllBytes($"{folderPath}/{bea.Name}/{asset.FullName}", GetASSTData(asset));
|
||||
}
|
||||
catch
|
||||
{
|
||||
@ -121,6 +120,17 @@ namespace FirstPlugin
|
||||
|
||||
beaFile = new BezelEngineArchive(new MemoryStream(Data));
|
||||
FillTreeNodes(this, beaFile.FileList);
|
||||
|
||||
ContextMenu = new ContextMenu();
|
||||
MenuItem save = new MenuItem("Save");
|
||||
ContextMenu.MenuItems.Add(save);
|
||||
save.Click += Save;
|
||||
MenuItem previewFiles = new MenuItem("Preview Window");
|
||||
ContextMenu.MenuItems.Add(previewFiles);
|
||||
previewFiles.Click += PreviewWindow;
|
||||
MenuItem exportAll = new MenuItem("Export All");
|
||||
ContextMenu.MenuItems.Add(exportAll);
|
||||
exportAll.Click += ExportAll;
|
||||
}
|
||||
public void Unload()
|
||||
{
|
||||
@ -137,207 +147,156 @@ namespace FirstPlugin
|
||||
yield return child;
|
||||
}
|
||||
}
|
||||
private void Save(object sender, EventArgs args)
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
List<IFileFormat> formats = new List<IFileFormat>();
|
||||
formats.Add(this);
|
||||
|
||||
SaveFileDialog sfd = new SaveFileDialog();
|
||||
sfd.Filter = Utils.GetAllFilters(formats);
|
||||
sfd.FileName = FileName;
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
STFileSaver.SaveFileFormat(this, sfd.FileName);
|
||||
}
|
||||
GC.Collect();
|
||||
}
|
||||
public byte[] Save()
|
||||
{
|
||||
beaFile.FileList.Clear();
|
||||
beaFile.FileDictionary.Clear();
|
||||
|
||||
foreach (TreeNode node in Collect(Nodes))
|
||||
{
|
||||
if (node is FileEntry)
|
||||
if (node is TreeNodeFile && node != this)
|
||||
{
|
||||
Console.WriteLine(node);
|
||||
if (((FileEntry)node).FileHandle != null)
|
||||
IFileFormat fileFormat = (IFileFormat)node;
|
||||
if (fileFormat != null)
|
||||
{
|
||||
Console.WriteLine("Saving FileHandle");
|
||||
SaveFileEntryData((FileEntry)node);
|
||||
byte[] uncomrompressedData = fileFormat.Data;
|
||||
|
||||
//Save any active files in the editor if supported
|
||||
if (fileFormat.CanSave)
|
||||
uncomrompressedData = fileFormat.Save();
|
||||
|
||||
//Create a new asset entry
|
||||
ASST asset = new ASST();
|
||||
asset.unk = 2;
|
||||
asset.unk2 = 2;
|
||||
asset.UncompressedSize = uncomrompressedData.LongLength;
|
||||
|
||||
if (fileFormat.FileIsCompressed)
|
||||
asset.FileData = STLibraryCompression.ZSTD.Compress(uncomrompressedData);
|
||||
else
|
||||
asset.FileData = fileFormat.Data;
|
||||
|
||||
asset.FileName = fileFormat.FilePath;
|
||||
beaFile.FileList.Add(fileFormat.FilePath, asset);
|
||||
beaFile.FileDictionary.Add(fileFormat.FilePath);
|
||||
}
|
||||
}
|
||||
else if (node is FileEntry)
|
||||
{
|
||||
ASST asset = new ASST();
|
||||
asset.unk = ((FileEntry)node).unk1;
|
||||
asset.unk2 = ((FileEntry)node).unk2;
|
||||
asset.FileName = ((FileEntry)node).FullName;
|
||||
asset.FileData = ((FileEntry)node).data;
|
||||
byte[] uncomp = GetASSTData((FileEntry)node);
|
||||
asset.UncompressedSize = uncomp.Length;
|
||||
beaFile.FileList.Add(asset.FileName, asset);
|
||||
beaFile.FileDictionary.Add(asset.FileName);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryStream mem = new MemoryStream();
|
||||
beaFile.Save(mem);
|
||||
return mem.ToArray();
|
||||
}
|
||||
|
||||
|
||||
public class RootNode : TreeNodeFile
|
||||
private void ExportAll(object sender, EventArgs args)
|
||||
{
|
||||
public RootNode(string n, IFileFormat format)
|
||||
{
|
||||
Text = n;
|
||||
FolderSelectDialog fsd = new FolderSelectDialog();
|
||||
|
||||
ContextMenu = new ContextMenu();
|
||||
MenuItem previewFiles = new MenuItem("Preview Window");
|
||||
ContextMenu.MenuItems.Add(previewFiles);
|
||||
previewFiles.Click += PreviewWindow;
|
||||
MenuItem exportAll = new MenuItem("Export All");
|
||||
ContextMenu.MenuItems.Add(exportAll);
|
||||
exportAll.Click += ExportAll;
|
||||
if (fsd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
progressBar = new ProgressBarWindow();
|
||||
progressBar.Task = "Extracing Files...";
|
||||
progressBar.Refresh();
|
||||
progressBar.Value = 0;
|
||||
progressBar.StartPosition = FormStartPosition.CenterScreen;
|
||||
progressBar.Show();
|
||||
|
||||
ExportAll(fsd.SelectedPath, progressBar);
|
||||
}
|
||||
public override void OnClick(TreeView treeview)
|
||||
}
|
||||
private void ExportAll(string Folder, ProgressBarWindow progressBar)
|
||||
{
|
||||
int Curfile = 0;
|
||||
foreach (FileEntry asst in Nodes)
|
||||
{
|
||||
int value = (Curfile * 100) / beaFile.FileList.Count;
|
||||
progressBar.Value = value;
|
||||
progressBar.Refresh();
|
||||
|
||||
}
|
||||
private void ExportAll(object sender, EventArgs args)
|
||||
{
|
||||
FolderSelectDialog fsd = new FolderSelectDialog();
|
||||
|
||||
if (fsd.ShowDialog() == DialogResult.OK)
|
||||
try
|
||||
{
|
||||
progressBar = new ProgressBarWindow();
|
||||
progressBar.Task = "Extracing Files...";
|
||||
progressBar.Refresh();
|
||||
progressBar.Value = 0;
|
||||
progressBar.StartPosition = FormStartPosition.CenterScreen;
|
||||
progressBar.Show();
|
||||
|
||||
ExportAll(fsd.SelectedPath, progressBar);
|
||||
}
|
||||
}
|
||||
private void ExportAll(string Folder, ProgressBarWindow progressBar)
|
||||
{
|
||||
|
||||
int Curfile = 0;
|
||||
foreach (ASST asst in beaFile.FileList.Values)
|
||||
{
|
||||
int value = (Curfile * 100) / beaFile.FileList.Count;
|
||||
progressBar.Value = value;
|
||||
progressBar.Refresh();
|
||||
|
||||
try
|
||||
if (!String.IsNullOrWhiteSpace(Path.GetDirectoryName($"{Folder}/{beaFile.Name}/{asst.FullName}")))
|
||||
{
|
||||
if (!String.IsNullOrWhiteSpace(Path.GetDirectoryName($"{Folder}/{beaFile.Name}/{asst.FileName}")))
|
||||
if (!File.Exists(asst.FullName))
|
||||
{
|
||||
if (!File.Exists(asst.FileName))
|
||||
if (!Directory.Exists($"{Folder}/{beaFile.Name}/{asst.FullName}"))
|
||||
{
|
||||
if (!Directory.Exists($"{Folder}/{beaFile.Name}/{asst.FileName}"))
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName($"{Folder}/{beaFile.Name}/{asst.FileName}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
File.WriteAllBytes($"{Folder}/{beaFile.Name}/{asst.FileName}", GetASSTData(asst.FileName));
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Curfile++;
|
||||
if (value == 99)
|
||||
value = 100;
|
||||
progressBar.Value = value;
|
||||
progressBar.Refresh();
|
||||
}
|
||||
}
|
||||
private void CallRecursive(TreeView treeView)
|
||||
{
|
||||
// Print each node recursively.
|
||||
TreeNodeCollection nodes = treeView.Nodes;
|
||||
foreach (TreeNode n in nodes)
|
||||
{
|
||||
PrintRecursive(n);
|
||||
}
|
||||
}
|
||||
private void PrintRecursive(TreeNode treeNode)
|
||||
{
|
||||
if (treeNode is FileEntry)
|
||||
{
|
||||
FileEntry file = (FileEntry)treeNode;
|
||||
|
||||
if (file.ImageKey == "bntx")
|
||||
OpenFile(file.Name, GetASSTData(file.FullName), TreeView);
|
||||
|
||||
if (file.ImageKey == "bntx")
|
||||
Console.WriteLine(file.Name);
|
||||
// if (file.ImageKey == "bfres")
|
||||
// OpenFile(file.Name, GetASSTData(file.FullName), TreeView);
|
||||
}
|
||||
|
||||
// Print each node recursively.
|
||||
foreach (TreeNode tn in treeNode.Nodes)
|
||||
{
|
||||
PrintRecursive(tn);
|
||||
}
|
||||
}
|
||||
|
||||
public void PreviewWindow(object sender, EventArgs args)
|
||||
{
|
||||
PreviewFormatList previewFormatList = new PreviewFormatList();
|
||||
|
||||
if (previewFormatList.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
CallRecursive(TreeView);
|
||||
Console.WriteLine("Loaded files");
|
||||
Console.WriteLine(PluginRuntime.bntxContainers.Count);
|
||||
PreviewEditor previewWindow = new PreviewEditor();
|
||||
previewWindow.Show();
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenFile(string FileName, byte[] data, TreeView treeView, bool Compressed = false, CompressionType CompType = CompressionType.None)
|
||||
{
|
||||
|
||||
FileReader f = new FileReader(data);
|
||||
string Magic = f.ReadMagic(0, 4);
|
||||
string Magic2 = f.ReadMagic(0, 2);
|
||||
|
||||
//Determine if the file is compressed or not
|
||||
if (Magic == "Yaz0")
|
||||
{
|
||||
data = EveryFileExplorer.YAZ0.Decompress(data);
|
||||
OpenFile(FileName, data, treeView, true, CompressionType.Yaz0);
|
||||
return;
|
||||
}
|
||||
if (Magic == "ZLIB")
|
||||
{
|
||||
data = FileReader.InflateZLIB(f.getSection(64, data.Length - 64));
|
||||
OpenFile(FileName, data, treeView, true, CompressionType.Zlib);
|
||||
return;
|
||||
}
|
||||
|
||||
f.Dispose();
|
||||
f.Close();
|
||||
|
||||
IFileFormat[] SupportedFormats = FileManager.GetFileFormats();
|
||||
|
||||
foreach (IFileFormat format in SupportedFormats)
|
||||
{
|
||||
if (format.Magic == Magic || format.Magic == Magic2)
|
||||
{
|
||||
format.CompressionType = CompType;
|
||||
format.FileIsCompressed = Compressed;
|
||||
format.Data = data;
|
||||
format.FileName = Path.GetFileName(FileName);
|
||||
format.Load();
|
||||
format.FilePath = FileName;
|
||||
|
||||
if (format is TreeNode)
|
||||
{
|
||||
((TreeNode)format).Text = Text;
|
||||
((TreeNode)format).ImageKey = ImageKey;
|
||||
((TreeNode)format).SelectedImageKey = SelectedImageKey;
|
||||
|
||||
Nodes.Add(((TreeNode)format));
|
||||
}
|
||||
}
|
||||
if (format.Magic == String.Empty) //Load by extension if magic isn't defined
|
||||
{
|
||||
foreach (string ext in format.Extension)
|
||||
{
|
||||
if (ext.Remove(0, 1) == Path.GetExtension(FileName))
|
||||
{
|
||||
format.Load();
|
||||
Directory.CreateDirectory(Path.GetDirectoryName($"{Folder}/{beaFile.Name}/{asst.FullName}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
File.WriteAllBytes($"{Folder}/{beaFile.Name}/{asst.FullName}", GetASSTData(asst));
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SupportedFormats = null;
|
||||
data = null;
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
Curfile++;
|
||||
if (value == 99)
|
||||
value = 100;
|
||||
progressBar.Value = value;
|
||||
progressBar.Refresh();
|
||||
}
|
||||
}
|
||||
private void CallRecursive(TreeView treeView)
|
||||
{
|
||||
// Print each node recursively.
|
||||
TreeNodeCollection nodes = treeView.Nodes;
|
||||
foreach (TreeNode n in nodes)
|
||||
{
|
||||
PrintRecursive(n);
|
||||
}
|
||||
}
|
||||
private void PrintRecursive(TreeNode treeNode)
|
||||
{
|
||||
// Print each node recursively.
|
||||
foreach (TreeNode tn in treeNode.Nodes)
|
||||
{
|
||||
PrintRecursive(tn);
|
||||
}
|
||||
}
|
||||
|
||||
public void PreviewWindow(object sender, EventArgs args)
|
||||
{
|
||||
PreviewFormatList previewFormatList = new PreviewFormatList();
|
||||
|
||||
if (previewFormatList.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
CallRecursive(TreeView);
|
||||
Console.WriteLine("Loaded files");
|
||||
Console.WriteLine(PluginRuntime.bntxContainers.Count);
|
||||
PreviewEditor previewWindow = new PreviewEditor();
|
||||
previewWindow.Show();
|
||||
}
|
||||
}
|
||||
public bool Compressed;
|
||||
public class FolderEntry : TreeNode
|
||||
{
|
||||
@ -371,6 +330,10 @@ namespace FirstPlugin
|
||||
|
||||
public string FullName;
|
||||
public IFileFormat FileHandle; //Load file instance to save later if possible
|
||||
public byte[] data;
|
||||
public ushort unk1;
|
||||
public ushort unk2;
|
||||
public bool IsCompressed;
|
||||
|
||||
private void Export(object sender, EventArgs args)
|
||||
{
|
||||
@ -381,7 +344,7 @@ namespace FirstPlugin
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
File.WriteAllBytes(sfd.FileName, GetASSTData(FullName));
|
||||
File.WriteAllBytes(sfd.FileName, GetASSTData(this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,77 +357,18 @@ namespace FirstPlugin
|
||||
|
||||
if (ofd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
SetASST(File.ReadAllBytes(ofd.FileName), FullName);
|
||||
SetASST(this, File.ReadAllBytes(ofd.FileName));
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnClick(TreeView treeView)
|
||||
public override void OnDoubleMouseClick(TreeView treeview)
|
||||
{
|
||||
if (beaFile != null)
|
||||
if (GetASSTData(this) != null)
|
||||
{
|
||||
if (GetASSTData(FullName) != null)
|
||||
OpenFile(Name, GetASSTData(FullName), treeView);
|
||||
}
|
||||
}
|
||||
TreeNode node = STFileLoader.GetNodeFileFormat(FullName, GetASSTData(this), true, "", this, IsCompressed, CompressionType.Zstb);
|
||||
|
||||
public void OpenFile(string FileName, byte[] data, TreeView treeView, bool Compressed = false, CompressionType CompType = CompressionType.None)
|
||||
{
|
||||
|
||||
FileReader f = new FileReader(data);
|
||||
string Magic = f.ReadMagic(0, 4);
|
||||
string Magic2 = f.ReadMagic(0, 2);
|
||||
|
||||
//Determine if the file is compressed or not
|
||||
if (Magic == "Yaz0")
|
||||
{
|
||||
data = EveryFileExplorer.YAZ0.Decompress(data);
|
||||
OpenFile(FileName, data, treeView, true, CompressionType.Yaz0);
|
||||
return;
|
||||
}
|
||||
if (Magic == "ZLIB")
|
||||
{
|
||||
data = FileReader.InflateZLIB(f.getSection(64, data.Length - 64));
|
||||
OpenFile(FileName, data, treeView, true, CompressionType.Zlib);
|
||||
return;
|
||||
}
|
||||
|
||||
f.Dispose();
|
||||
f.Close();
|
||||
|
||||
IFileFormat[] SupportedFormats = FileManager.GetFileFormats();
|
||||
|
||||
foreach (IFileFormat format in SupportedFormats)
|
||||
{
|
||||
if (format.Magic == Magic || format.Magic == Magic2)
|
||||
{
|
||||
FileHandle = format;
|
||||
|
||||
format.CompressionType = CompType;
|
||||
format.FileIsCompressed = Compressed;
|
||||
format.Data = data;
|
||||
format.FileName = Path.GetFileName(FileName);
|
||||
format.Load();
|
||||
format.FilePath = FileName;
|
||||
|
||||
if (format is TreeNode)
|
||||
{
|
||||
((TreeNode)format).Text = Text;
|
||||
((TreeNode)format).ImageKey = ImageKey;
|
||||
((TreeNode)format).SelectedImageKey = SelectedImageKey;
|
||||
|
||||
Nodes.Add(((TreeNode)format));
|
||||
}
|
||||
}
|
||||
if (format.Magic == String.Empty) //Load by extension if magic isn't defined
|
||||
{
|
||||
foreach (string ext in format.Extension)
|
||||
{
|
||||
if (ext.Remove(0, 1) == Path.GetExtension(FileName))
|
||||
{
|
||||
format.Load();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (node != null)
|
||||
ReplaceNode(this.Parent, this, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -476,58 +380,19 @@ namespace FirstPlugin
|
||||
node.Nodes.Insert(index, NewNode);
|
||||
}
|
||||
|
||||
public static byte[] GetASSTData(string path)
|
||||
public static byte[] GetASSTData(FileEntry entry)
|
||||
{
|
||||
if (beaFile.FileList.ContainsKey(path))
|
||||
{
|
||||
if (beaFile.FileList[path].UncompressedSize == beaFile.FileList[path].FileData.Length)
|
||||
{
|
||||
return beaFile.FileList[path].FileData;
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var decompressor = new Decompressor())
|
||||
{
|
||||
return decompressor.Unwrap(beaFile.FileList[path].FileData);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
if (entry.IsCompressed)
|
||||
return STLibraryCompression.ZSTD.Decompress(entry.data);
|
||||
else
|
||||
return entry.data;
|
||||
}
|
||||
public static void SetASST(byte[] data, string path)
|
||||
public static void SetASST(FileEntry fileEntry, byte[] data)
|
||||
{
|
||||
if (beaFile.FileList.ContainsKey(path))
|
||||
{
|
||||
ASST asst = beaFile.FileList[path];
|
||||
Console.WriteLine(path + " A match!");
|
||||
|
||||
asst.UncompressedSize = data.Length;
|
||||
|
||||
if (asst.IsCompressed)
|
||||
{
|
||||
using (var compressor = new Compressor())
|
||||
{
|
||||
asst.FileData = compressor.Wrap(data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
asst.FileData = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SaveFileEntryData(FileEntry entry)
|
||||
{
|
||||
IFileFormat file = entry.FileHandle;
|
||||
if (beaFile.FileList.ContainsKey(entry.FullName))
|
||||
{
|
||||
if (file.CanSave)
|
||||
{
|
||||
SetASST(file.Save(), entry.FullName);
|
||||
}
|
||||
}
|
||||
if (fileEntry.IsCompressed)
|
||||
fileEntry.data = STLibraryCompression.ZSTD.Compress(data);
|
||||
else
|
||||
fileEntry.data = data;
|
||||
}
|
||||
|
||||
void FillTreeNodes(TreeNode root, Dictionary<string, ASST> files)
|
||||
@ -561,7 +426,7 @@ namespace FirstPlugin
|
||||
|
||||
var temp = new TreeNode(parentName, 0, 0);
|
||||
if (rootIndex == roots.Length - 1)
|
||||
temp = SetupFileEntry(node.Value.FileData, parentName, node.Value.FileName, node.Value.IsCompressed);
|
||||
temp = SetupFileEntry(node.Value,parentName, node.Value.FileName, node.Value.IsCompressed);
|
||||
else
|
||||
temp = SetupFolderEntry(temp);
|
||||
|
||||
@ -608,21 +473,25 @@ namespace FirstPlugin
|
||||
return finalList;
|
||||
}
|
||||
|
||||
public FileEntry SetupFileEntry(byte[] data, string name, string fullName, bool IsCompressed)
|
||||
public FileEntry SetupFileEntry(ASST asset,string name, string fullName, bool IsCompressed)
|
||||
{
|
||||
FileEntry fileEntry = new FileEntry();
|
||||
fileEntry.FullName = fullName;
|
||||
fileEntry.Name = name;
|
||||
fileEntry.Text = name;
|
||||
fileEntry.unk1 = asset.unk;
|
||||
fileEntry.unk2 = asset.unk2;
|
||||
fileEntry.IsCompressed = IsCompressed;
|
||||
fileEntry.data = asset.FileData;
|
||||
|
||||
//Now check magic
|
||||
//Todo clean this part up
|
||||
byte[] data = asset.FileData;
|
||||
if (IsCompressed)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var decompressor = new Decompressor())
|
||||
{
|
||||
data = decompressor.Unwrap(data);
|
||||
}
|
||||
data = STLibraryCompression.ZSTD.Decompress(asset.FileData);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
@ -16,9 +16,6 @@ namespace FirstPlugin
|
||||
{
|
||||
public class BFRES : TreeNodeFile, IFileFormat
|
||||
{
|
||||
private static BFRES _instance;
|
||||
public static BFRES Instance { get { return _instance == null ? _instance = new BFRES() : _instance; } }
|
||||
|
||||
public bool CanSave { get; set; } = false;
|
||||
public bool FileIsEdited { get; set; } = false;
|
||||
public bool FileIsCompressed { get; set; } = false;
|
||||
@ -43,15 +40,12 @@ namespace FirstPlugin
|
||||
public bool UseEditMenu { get; set; } = false;
|
||||
public int Alignment { get; set; } = 0;
|
||||
public string FilePath { get; set; }
|
||||
private bool isWiiU;
|
||||
public bool IsWiiU
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Data == null)
|
||||
return false;
|
||||
if (isWiiU)
|
||||
return true;
|
||||
|
||||
using (FileReader reader = new FileReader(new MemoryStream(Data)))
|
||||
{
|
||||
@ -317,8 +311,7 @@ namespace FirstPlugin
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
SaveCompressFile(Save(), sfd.FileName, Alignment);
|
||||
STFileSaver.SaveFileFormat(this, sfd.FileName, Alignment);
|
||||
}
|
||||
}
|
||||
private void Rename(object sender, EventArgs args)
|
||||
@ -442,32 +435,6 @@ namespace FirstPlugin
|
||||
fbnvFolder.Nodes.Add(boneVis);
|
||||
}
|
||||
}
|
||||
private void SaveCompressFile(byte[] data, string FileName, int Alignment = 0, bool EnableDialog = true)
|
||||
{
|
||||
if (EnableDialog && CompressionType != CompressionType.None)
|
||||
{
|
||||
DialogResult save = MessageBox.Show($"Compress file as {CompressionType}?", "File Save", MessageBoxButtons.YesNo);
|
||||
|
||||
if (save == DialogResult.Yes)
|
||||
{
|
||||
switch (CompressionType)
|
||||
{
|
||||
case CompressionType.Yaz0:
|
||||
data = EveryFileExplorer.YAZ0.Compress(data, Runtime.Yaz0CompressionLevel, (uint)Alignment);
|
||||
break;
|
||||
case CompressionType.Lz4f:
|
||||
data = STLibraryCompression.Type_LZ4F.Compress(data);
|
||||
break;
|
||||
case CompressionType.Lz4:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
File.WriteAllBytes(FileName, data);
|
||||
MessageBox.Show($"File has been saved to {FileName}");
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
|
||||
private void SaveSwitch(MemoryStream mem)
|
||||
{
|
||||
var resFile = BFRESRender.ResFileNode.resFile;
|
||||
@ -531,7 +498,7 @@ namespace FirstPlugin
|
||||
// resFileU.SceneAnims.Clear();
|
||||
// resFileU.ShapeAnims.Clear();
|
||||
// resFileU.BoneVisibilityAnims.Clear();
|
||||
// resFileU.Textures.Clear();
|
||||
resFileU.Textures.Clear();
|
||||
|
||||
|
||||
int CurMdl = 0;
|
||||
@ -540,6 +507,14 @@ namespace FirstPlugin
|
||||
foreach (FMDL model in Nodes["FMDL"].Nodes)
|
||||
resFileU.Models.Add(model.Text, BfresWiiU.SetModel(model));
|
||||
}
|
||||
if (Nodes.ContainsKey("FTEX"))
|
||||
{
|
||||
foreach (FTEX tex in Nodes["FTEX"].Nodes)
|
||||
resFileU.Textures.Add(tex.Text, tex.texture);
|
||||
}
|
||||
else
|
||||
throw new Exception("Failed to find textures");
|
||||
|
||||
ErrorCheck();
|
||||
resFileU.Save(mem);
|
||||
}
|
||||
|
@ -143,7 +143,7 @@ namespace Bfres.Structs
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
if (BFRES.Instance.IsWiiU)
|
||||
if (GetResFileU() != null)
|
||||
MaterialU.Export(sfd.FileName, GetResFileU());
|
||||
else
|
||||
Material.Export(sfd.FileName, GetResFile());
|
||||
@ -156,7 +156,7 @@ namespace Bfres.Structs
|
||||
|
||||
if (ofd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
if (BFRES.Instance.IsWiiU)
|
||||
if (GetResFileU() != null)
|
||||
{
|
||||
MaterialU.Import(ofd.FileName, GetResFileU());
|
||||
MaterialU.Name = Text;
|
||||
|
@ -81,6 +81,14 @@ namespace Bfres.Structs
|
||||
return ((BFRES)Parent.Parent).BFRESRender.models;
|
||||
}
|
||||
|
||||
public bool IsWiiU
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetResFileU() != null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public FMDL()
|
||||
{
|
||||
@ -121,7 +129,7 @@ namespace Bfres.Structs
|
||||
if (HasNormals)
|
||||
shp.SmoothNormals();
|
||||
|
||||
shp.SaveVertexBuffer();
|
||||
shp.SaveVertexBuffer(IsWiiU);
|
||||
}
|
||||
UpdateVertexData();
|
||||
Cursor.Current = Cursors.Default;
|
||||
@ -135,7 +143,7 @@ namespace Bfres.Structs
|
||||
if (HasNormals)
|
||||
shp.CalculateNormals();
|
||||
|
||||
shp.SaveVertexBuffer();
|
||||
shp.SaveVertexBuffer(IsWiiU);
|
||||
}
|
||||
UpdateVertexData();
|
||||
Cursor.Current = Cursors.Default;
|
||||
@ -196,7 +204,7 @@ namespace Bfres.Structs
|
||||
}
|
||||
|
||||
shp.CalculateTangentBitangent();
|
||||
shp.SaveVertexBuffer();
|
||||
shp.SaveVertexBuffer(IsWiiU);
|
||||
}
|
||||
|
||||
UpdateVertexData();
|
||||
@ -356,6 +364,8 @@ namespace Bfres.Structs
|
||||
//Function addes shapes, vertices and meshes
|
||||
public void AddOjects(string FileName, bool Replace = true)
|
||||
{
|
||||
bool IsWiiU = (GetResFileU() != null);
|
||||
|
||||
int MatStartIndex = materials.Count;
|
||||
string ext = System.IO.Path.GetExtension(FileName);
|
||||
ext = ext.ToLower();
|
||||
@ -442,8 +452,8 @@ namespace Bfres.Structs
|
||||
shape.CreateIndexList(obj, this);
|
||||
shape.VertexSkinCount = obj.GetMaxSkinInfluenceCount();
|
||||
shape.ApplyImportSettings(csvsettings, GetMaterial(shape.MaterialIndex));
|
||||
shape.SaveShape();
|
||||
shape.SaveVertexBuffer();
|
||||
shape.SaveShape(IsWiiU);
|
||||
shape.SaveVertexBuffer(IsWiiU);
|
||||
shape.BoneIndices = new List<ushort>();
|
||||
|
||||
Nodes["FshpFolder"].Nodes.Add(shape);
|
||||
@ -472,7 +482,7 @@ namespace Bfres.Structs
|
||||
}
|
||||
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
if (!BFRES.Instance.IsWiiU && Replace)
|
||||
if (Replace)
|
||||
{
|
||||
materials.Clear();
|
||||
Nodes["FmatFolder"].Nodes.Clear();
|
||||
@ -483,18 +493,18 @@ namespace Bfres.Structs
|
||||
FMAT fmat = new FMAT();
|
||||
if (settings.ExternalMaterialPath != string.Empty)
|
||||
{
|
||||
if (!BFRES.Instance.IsWiiU)
|
||||
{
|
||||
fmat.Material = new Material();
|
||||
fmat.Material.Import(settings.ExternalMaterialPath);
|
||||
fmat.ReadMaterial(fmat.Material);
|
||||
}
|
||||
else
|
||||
if (GetResFileU() != null)
|
||||
{
|
||||
fmat.MaterialU = new ResU.Material();
|
||||
fmat.MaterialU.Import(settings.ExternalMaterialPath, GetResFileU());
|
||||
BfresWiiU.ReadMaterial(fmat, fmat.MaterialU);
|
||||
}
|
||||
else
|
||||
{
|
||||
fmat.Material = new Material();
|
||||
fmat.Material.Import(settings.ExternalMaterialPath);
|
||||
fmat.ReadMaterial(fmat.Material);
|
||||
}
|
||||
}
|
||||
|
||||
fmat.Text = mat.Text;
|
||||
@ -583,7 +593,7 @@ namespace Bfres.Structs
|
||||
materials.Add(fmat.Text, fmat);
|
||||
Nodes["FmatFolder"].Nodes.Add(fmat);
|
||||
|
||||
if (BFRES.Instance.IsWiiU)
|
||||
if (GetResFileU() != null)
|
||||
{
|
||||
fmat.MaterialU.Name = Text;
|
||||
fmat.SetMaterial(fmat.MaterialU);
|
||||
@ -612,8 +622,8 @@ namespace Bfres.Structs
|
||||
shape.CreateBoneList(obj, this);
|
||||
shape.CreateIndexList(obj, this);
|
||||
shape.ApplyImportSettings(settings, GetMaterial(shape.MaterialIndex));
|
||||
shape.SaveShape();
|
||||
shape.SaveVertexBuffer();
|
||||
shape.SaveShape(IsWiiU);
|
||||
shape.SaveVertexBuffer(IsWiiU);
|
||||
shape.BoneIndices = new List<ushort>();
|
||||
|
||||
List<string> keyList = shapes.Select(o => o.Text).ToList();
|
||||
|
@ -92,6 +92,14 @@ namespace Bfres.Structs
|
||||
}
|
||||
public class FSHP : STGenericObject
|
||||
{
|
||||
public bool IsWiiU
|
||||
{
|
||||
get
|
||||
{
|
||||
return GetResFileU() != null;
|
||||
}
|
||||
}
|
||||
|
||||
public FSHP()
|
||||
{
|
||||
Checked = true;
|
||||
@ -188,7 +196,7 @@ namespace Bfres.Structs
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
SmoothNormals();
|
||||
SaveVertexBuffer();
|
||||
SaveVertexBuffer(IsWiiU);
|
||||
UpdateVertexData();
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
@ -196,7 +204,7 @@ namespace Bfres.Structs
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
CalculateNormals();
|
||||
SaveVertexBuffer();
|
||||
SaveVertexBuffer(IsWiiU);
|
||||
UpdateVertexData();
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
@ -279,8 +287,6 @@ namespace Bfres.Structs
|
||||
param.ValueFloat = new float[] { 1, 1, 1, 1 };
|
||||
break;
|
||||
case "gsys_bake_st0":
|
||||
param.ValueFloat = new float[] { 1, 1, 0, 0 };
|
||||
break;
|
||||
case "gsys_bake_st1":
|
||||
param.ValueFloat = new float[] { 1, 1, 0, 0 };
|
||||
break;
|
||||
@ -346,7 +352,7 @@ namespace Bfres.Structs
|
||||
}
|
||||
|
||||
CalculateTangentBitangent();
|
||||
SaveVertexBuffer();
|
||||
SaveVertexBuffer(IsWiiU);
|
||||
UpdateVertexData();
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
@ -371,7 +377,7 @@ namespace Bfres.Structs
|
||||
}
|
||||
|
||||
FlipUvsVertical();
|
||||
SaveVertexBuffer();
|
||||
SaveVertexBuffer(IsWiiU);
|
||||
UpdateVertexData();
|
||||
}
|
||||
public void FlipUvsHorizontal(object sender, EventArgs args)
|
||||
@ -383,7 +389,7 @@ namespace Bfres.Structs
|
||||
}
|
||||
|
||||
FlipUvsHorizontal();
|
||||
SaveVertexBuffer();
|
||||
SaveVertexBuffer(IsWiiU);
|
||||
UpdateVertexData();
|
||||
}
|
||||
public void ExportMaterials(object sender, EventArgs args)
|
||||
@ -445,6 +451,8 @@ namespace Bfres.Structs
|
||||
}
|
||||
public void Replace(object sender, EventArgs args)
|
||||
{
|
||||
bool IsWiiU = (GetResFileU() != null);
|
||||
|
||||
OpenFileDialog ofd = new OpenFileDialog();
|
||||
ofd.Filter = "Supported Formats|*.bfobj;*.fbx;*.dae; *.obj;|" +
|
||||
"Bfres Object (shape/vertices) |*.bfobj|" +
|
||||
@ -494,8 +502,8 @@ namespace Bfres.Structs
|
||||
vertexAttributes = settings.CreateNewAttributes();
|
||||
lodMeshes = obj.lodMeshes;
|
||||
CreateNewBoundingBoxes();
|
||||
SaveShape();
|
||||
SaveVertexBuffer();
|
||||
SaveShape(IsWiiU);
|
||||
SaveVertexBuffer(IsWiiU);
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
}
|
||||
@ -609,7 +617,7 @@ namespace Bfres.Structs
|
||||
|
||||
private void UpdateShaderAssignAttributes(FMAT material)
|
||||
{
|
||||
material.shaderassign.samplers.Clear();
|
||||
material.shaderassign.attributes.Clear();
|
||||
foreach (VertexAttribute att in vertexAttributes)
|
||||
{
|
||||
material.shaderassign.attributes.Add(att.Name, att.Name);
|
||||
@ -656,12 +664,12 @@ namespace Bfres.Structs
|
||||
return (ResUGX2.GX2AttribFormat)System.Enum.Parse(typeof(ResUGX2.GX2AttribFormat), type.ToString());
|
||||
}
|
||||
}
|
||||
public void SaveShape()
|
||||
public void SaveShape(bool IsWiiU)
|
||||
{
|
||||
if (!BFRES.Instance.IsWiiU)
|
||||
Shape = BfresSwitch.SaveShape(this);
|
||||
else
|
||||
if (IsWiiU)
|
||||
ShapeU = BfresWiiU.SaveShape(this);
|
||||
else
|
||||
Shape = BfresSwitch.SaveShape(this);
|
||||
}
|
||||
public IList<ushort> GetIndices()
|
||||
{
|
||||
@ -683,9 +691,9 @@ namespace Bfres.Structs
|
||||
else
|
||||
return Vector3.TransformNormal(position, trans);
|
||||
}
|
||||
public void SaveVertexBuffer()
|
||||
public void SaveVertexBuffer(bool IsWiiU)
|
||||
{
|
||||
if (BFRES.Instance.IsWiiU)
|
||||
if (IsWiiU)
|
||||
{
|
||||
BfresWiiU.SaveVertexBuffer(this);
|
||||
return;
|
||||
|
@ -53,8 +53,6 @@ namespace FirstPlugin
|
||||
SetMaterial(mat, mat.Material);
|
||||
model.Materials.Add(mat.Material);
|
||||
}
|
||||
|
||||
|
||||
return model;
|
||||
}
|
||||
public static void Read(BFRESRender renderer, ResFile resFile, TreeNode ResFileNode)
|
||||
|
@ -35,11 +35,6 @@ namespace FirstPlugin
|
||||
foreach (var shape in duplicates)
|
||||
shape.Text += i++;
|
||||
|
||||
foreach (FMAT mat in fmdl.materials.Values)
|
||||
{
|
||||
SetMaterial(mat, mat.MaterialU);
|
||||
model.Materials.Add(mat.Text, mat.MaterialU);
|
||||
}
|
||||
foreach (FSHP shape in fmdl.shapes)
|
||||
{
|
||||
BFRES.CheckMissingTextures(shape);
|
||||
@ -52,6 +47,12 @@ namespace FirstPlugin
|
||||
|
||||
BFRES.SetShaderAssignAttributes(shape.GetMaterial().shaderassign, shape);
|
||||
}
|
||||
|
||||
foreach (FMAT mat in fmdl.materials.Values)
|
||||
{
|
||||
SetMaterial(mat, mat.MaterialU);
|
||||
model.Materials.Add(mat.Text, mat.MaterialU);
|
||||
}
|
||||
return model;
|
||||
}
|
||||
public static void Read(BFRESRender renderer, ResFile resFile, TreeNode ResFileNode)
|
||||
@ -377,6 +378,11 @@ namespace FirstPlugin
|
||||
m.ReadShaderParams(mat);
|
||||
m.MaterialU = mat;
|
||||
m.ReadTextureRefs(mat);
|
||||
m.ReadRenderState(mat.RenderState);
|
||||
}
|
||||
public static void ReadRenderState(this FMAT m, RenderState renderState)
|
||||
{
|
||||
|
||||
}
|
||||
public static void ReadTextureRefs(this FMAT m, Material mat)
|
||||
{
|
||||
@ -399,6 +405,14 @@ namespace FirstPlugin
|
||||
texture.wrapModeW = (int)mat.Samplers[id].TexSampler.ClampZ;
|
||||
mat.Samplers.TryGetKey(mat.Samplers[id], out texture.SamplerName);
|
||||
|
||||
if (mat.Samplers[id].TexSampler.MinFilter == GX2TexXYFilterType.Bilinear)
|
||||
{
|
||||
texture.magFilter = 0;
|
||||
}
|
||||
if (mat.Samplers[id].TexSampler.MagFilter == GX2TexXYFilterType.Bilinear)
|
||||
{
|
||||
|
||||
}
|
||||
if (Runtime.activeGame == Runtime.ActiveGame.MK8D)
|
||||
{
|
||||
if (texture.SamplerName == "_a0")
|
||||
@ -727,6 +741,7 @@ namespace FirstPlugin
|
||||
foreach (var att in shd.attributes)
|
||||
mat.ShaderAssign.AttribAssigns.Add(att.Key, att.Value);
|
||||
}
|
||||
|
||||
public static Shape SaveShape(FSHP fshp)
|
||||
{
|
||||
Shape ShapeU = new Shape();
|
||||
|
@ -74,23 +74,9 @@ namespace FirstPlugin
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
SaveCompressFile(Save(), sfd.FileName, IFileInfo.Alignment);
|
||||
STFileSaver.SaveFileFormat(this, sfd.FileName, IFileInfo.Alignment);
|
||||
}
|
||||
}
|
||||
private void SaveCompressFile(byte[] data, string FileName, int Alignment = 0, bool EnableDialog = true)
|
||||
{
|
||||
if (EnableDialog)
|
||||
{
|
||||
DialogResult save = MessageBox.Show("Compress file?", "File Save", MessageBoxButtons.YesNo);
|
||||
|
||||
if (save == DialogResult.Yes)
|
||||
data = EveryFileExplorer.YAZ0.Compress(data, 3, (uint)Alignment);
|
||||
}
|
||||
File.WriteAllBytes(FileName, data);
|
||||
MessageBox.Show($"File has been saved to {FileName}");
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
|
||||
private void PreviewWindow(object sender, EventArgs args)
|
||||
{
|
||||
@ -114,19 +100,6 @@ namespace FirstPlugin
|
||||
}
|
||||
private void PrintRecursive(TreeNode treeNode)
|
||||
{
|
||||
if (treeNode is FileEntry)
|
||||
{
|
||||
FileEntry file = (FileEntry)treeNode;
|
||||
|
||||
if (file.ImageKey == "bntx")
|
||||
OpenFile(file.Name, file.data, file);
|
||||
|
||||
if (file.ImageKey == "bntx")
|
||||
Console.WriteLine(file.Name);
|
||||
// if (file.ImageKey == "bfres")
|
||||
// OpenFile(file.Name, GetASSTData(file.FullName), TreeView);
|
||||
}
|
||||
|
||||
// Print each node recursively.
|
||||
foreach (TreeNode tn in treeNode.Nodes)
|
||||
{
|
||||
|
@ -69,33 +69,6 @@ namespace FirstPlugin
|
||||
{
|
||||
return Data;
|
||||
}
|
||||
|
||||
private static void SaveCompressFile(byte[] data, string FileName, CompressionType CompressionType, int Alignment = 0, bool EnableDialog = true)
|
||||
{
|
||||
if (EnableDialog && CompressionType != CompressionType.None)
|
||||
{
|
||||
DialogResult save = MessageBox.Show($"Compress file as {CompressionType}?", "File Save", MessageBoxButtons.YesNo);
|
||||
|
||||
if (save == DialogResult.Yes)
|
||||
{
|
||||
switch (CompressionType)
|
||||
{
|
||||
case CompressionType.Yaz0:
|
||||
data = EveryFileExplorer.YAZ0.Compress(data, Runtime.Yaz0CompressionLevel, (uint)Alignment);
|
||||
break;
|
||||
case CompressionType.Lz4f:
|
||||
data = STLibraryCompression.Type_LZ4F.Compress(data);
|
||||
break;
|
||||
case CompressionType.Lz4:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
File.WriteAllBytes(FileName, data);
|
||||
MessageBox.Show($"File has been saved to {FileName}");
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
|
||||
public enum GameSet : ushort
|
||||
{
|
||||
MarioOdyssey = 0x0,
|
||||
@ -165,9 +138,7 @@ namespace FirstPlugin
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
|
||||
int Alignment = IFileInfo.Alignment;
|
||||
SaveCompressFile(Save(), sfd.FileName, CompressionType, Alignment);
|
||||
STFileSaver.SaveFileFormat(this, sfd.FileName, IFileInfo.Alignment);
|
||||
}
|
||||
}
|
||||
public void Export(object sender, EventArgs args)
|
||||
|
@ -106,10 +106,10 @@ namespace FirstPlugin
|
||||
Console.WriteLine("Saving " + node);
|
||||
SaveFileEntryData((SarcEntry)node);
|
||||
}
|
||||
if (node is TreeNodeFile && node != this)
|
||||
else if (node is TreeNodeFile && node != this)
|
||||
{
|
||||
IFileFormat fileFormat = (IFileFormat)node;
|
||||
if (fileFormat != null && fileFormat.IFileInfo.ArchiveHash == SarcHash)
|
||||
if (fileFormat != null && fileFormat.IFileInfo != null && fileFormat.IFileInfo.ArchiveHash == SarcHash)
|
||||
{
|
||||
sarcData.Files.Add(SetSarcPath(node, this),
|
||||
STLibraryCompression.CompressFile(fileFormat.Save(), fileFormat));
|
||||
@ -168,23 +168,9 @@ namespace FirstPlugin
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
SaveCompressFile(Save(), sfd.FileName, IFileInfo.Alignment);
|
||||
STFileSaver.SaveFileFormat(this, sfd.FileName, IFileInfo.Alignment);
|
||||
}
|
||||
}
|
||||
private void SaveCompressFile(byte[] data, string FileName, int Alignment = 0, bool EnableDialog = true)
|
||||
{
|
||||
if (EnableDialog)
|
||||
{
|
||||
DialogResult save = MessageBox.Show("Compress file?", "File Save", MessageBoxButtons.YesNo);
|
||||
|
||||
if (save == DialogResult.Yes)
|
||||
data = EveryFileExplorer.YAZ0.Compress(data, 3, (uint)Alignment);
|
||||
}
|
||||
File.WriteAllBytes(FileName, data);
|
||||
MessageBox.Show($"File has been saved to {FileName}");
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
private void CallRecursive(TreeView treeView)
|
||||
{
|
||||
// Print each node recursively.
|
||||
@ -243,7 +229,10 @@ namespace FirstPlugin
|
||||
}
|
||||
public override void OnDoubleMouseClick(TreeView treeView)
|
||||
{
|
||||
ReplaceNode(this.Parent, this, OpenFile(Name, Data, this));
|
||||
TreeNode node = STFileLoader.GetNodeFileFormat(FullName, Data, true, sarcHash, this);
|
||||
|
||||
if (node != null)
|
||||
ReplaceNode(this.Parent, this, node);
|
||||
}
|
||||
|
||||
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
@ -368,75 +357,6 @@ namespace FirstPlugin
|
||||
return finalList;
|
||||
}
|
||||
|
||||
public static TreeNode OpenFile(string FileName, byte[] data, SarcEntry sarcEntry, bool Compressed = false, CompressionType CompType = 0)
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
FileReader fileReader = new FileReader(data);
|
||||
string Magic4 = fileReader.ReadMagic(0, 4);
|
||||
string Magic2 = fileReader.ReadMagic(0, 2);
|
||||
if (Magic4 == "Yaz0")
|
||||
{
|
||||
data = EveryFileExplorer.YAZ0.Decompress(data);
|
||||
return OpenFile(FileName, data, sarcEntry, true, (CompressionType)1);
|
||||
}
|
||||
if (Magic4 == "ZLIB")
|
||||
{
|
||||
data = FileReader.InflateZLIB(fileReader.getSection(64, data.Length - 64));
|
||||
return OpenFile(FileName, data, sarcEntry, true, (CompressionType)2);
|
||||
}
|
||||
fileReader.Dispose();
|
||||
fileReader.Close();
|
||||
foreach (IFileFormat fileFormat in FileManager.GetFileFormats())
|
||||
{
|
||||
if (fileFormat.Magic == Magic4 || fileFormat.Magic == Magic2)
|
||||
{
|
||||
fileFormat.CompressionType = CompType;
|
||||
fileFormat.FileIsCompressed = Compressed;
|
||||
fileFormat.Data = data;
|
||||
fileFormat.Load();
|
||||
fileFormat.FileName = Path.GetFileName(FileName);
|
||||
fileFormat.FilePath = FileName;
|
||||
fileFormat.IFileInfo = new IFileInfo();
|
||||
fileFormat.IFileInfo.ArchiveHash = sarcEntry.sarcHash;
|
||||
fileFormat.IFileInfo.InArchive = true;
|
||||
|
||||
if (fileFormat is TreeNode)
|
||||
{
|
||||
((TreeNode)fileFormat).Text = sarcEntry.Text;
|
||||
((TreeNode)fileFormat).ImageKey = sarcEntry.ImageKey;
|
||||
((TreeNode)fileFormat).SelectedImageKey = sarcEntry.SelectedImageKey;
|
||||
return (TreeNode)fileFormat;
|
||||
}
|
||||
}
|
||||
if (fileFormat.Magic == string.Empty)
|
||||
{
|
||||
foreach (string str3 in fileFormat.Extension)
|
||||
{
|
||||
if (str3.Remove(0, 1) == Path.GetExtension(FileName))
|
||||
{
|
||||
fileFormat.Data = data;
|
||||
fileFormat.Load();
|
||||
fileFormat.FileName = Path.GetFileName(FileName);
|
||||
fileFormat.FilePath = FileName;
|
||||
fileFormat.IFileInfo = new IFileInfo();
|
||||
fileFormat.IFileInfo.ArchiveHash = sarcEntry.sarcHash;
|
||||
fileFormat.IFileInfo.InArchive = true;
|
||||
|
||||
if (fileFormat is TreeNode)
|
||||
{
|
||||
((TreeNode)fileFormat).Text = sarcEntry.Text;
|
||||
((TreeNode)fileFormat).ImageKey = sarcEntry.ImageKey;
|
||||
((TreeNode)fileFormat).SelectedImageKey = sarcEntry.SelectedImageKey;
|
||||
return (TreeNode)fileFormat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (TreeNode)null;
|
||||
}
|
||||
|
||||
|
||||
public SarcEntry SetupFileEntry(byte[] data, string name, string fullName, string SarchHash)
|
||||
{
|
||||
SarcEntry sarcEntry = new SarcEntry();
|
||||
|
@ -687,7 +687,7 @@ namespace FirstPlugin
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
File.WriteAllBytes(sfd.FileName, Save());
|
||||
STFileSaver.SaveFileFormat(this, sfd.FileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -836,13 +836,37 @@ namespace FirstPlugin
|
||||
return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, true);
|
||||
|
||||
byte[] d = null;
|
||||
if (IsCompressedFormat(Format))
|
||||
d = DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, GetCompressedDXGI_FORMAT(Format));
|
||||
else if (IsAtscFormat(Format))
|
||||
d = null;
|
||||
else
|
||||
d = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, GetUncompressedDXGI_FORMAT(Format));
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (IsCompressedFormat(Format))
|
||||
d = DDSCompressor.DecompressBlock(data, (int)Width, (int)Height, GetCompressedDXGI_FORMAT(Format));
|
||||
else if (IsAtscFormat(Format))
|
||||
d = null;
|
||||
else
|
||||
d = DDSCompressor.DecodePixelBlock(data, (int)Width, (int)Height, GetUncompressedDXGI_FORMAT(Format));
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (Format == SurfaceFormat.BC1_UNORM)
|
||||
return DDSCompressor.DecompressBC1(data, (int)Width, (int)Height, false);
|
||||
else if (Format == SurfaceFormat.BC1_SRGB)
|
||||
return DDSCompressor.DecompressBC1(data, (int)Width, (int)Height, true);
|
||||
else if (Format == SurfaceFormat.BC3_SRGB)
|
||||
return DDSCompressor.DecompressBC3(data, (int)Width, (int)Height, false);
|
||||
else if (Format == SurfaceFormat.BC3_UNORM)
|
||||
return DDSCompressor.DecompressBC3(data, (int)Width, (int)Height, true);
|
||||
else if (Format == SurfaceFormat.BC4_UNORM)
|
||||
return DDSCompressor.DecompressBC4(data, (int)Width, (int)Height, false);
|
||||
else if (Format == SurfaceFormat.BC4_SNORM)
|
||||
return DDSCompressor.DecompressBC4(data, (int)Width, (int)Height, true);
|
||||
else if (Format == SurfaceFormat.BC5_UNORM)
|
||||
return DDSCompressor.DecompressBC5(data, (int)Width, (int)Height, false);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (d != null)
|
||||
{
|
||||
decomp = BitmapExtension.GetBitmap(d, (int)Width, (int)Height);
|
||||
@ -882,11 +906,11 @@ namespace FirstPlugin
|
||||
switch (Format)
|
||||
{
|
||||
case SurfaceFormat.BC1_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM;
|
||||
case SurfaceFormat.BC1_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB;
|
||||
case SurfaceFormat.BC1_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM;
|
||||
case SurfaceFormat.BC2_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM;
|
||||
case SurfaceFormat.BC2_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB;
|
||||
case SurfaceFormat.BC2_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM;
|
||||
case SurfaceFormat.BC3_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM;
|
||||
case SurfaceFormat.BC3_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB;
|
||||
case SurfaceFormat.BC3_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM;
|
||||
case SurfaceFormat.BC4_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM;
|
||||
case SurfaceFormat.BC4_SNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM;
|
||||
case SurfaceFormat.BC5_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM;
|
||||
@ -894,7 +918,7 @@ namespace FirstPlugin
|
||||
case SurfaceFormat.BC6_UFLOAT: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16;
|
||||
case SurfaceFormat.BC6_FLOAT: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16;
|
||||
case SurfaceFormat.BC7_UNORM: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM;
|
||||
case SurfaceFormat.BC7_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB;
|
||||
case SurfaceFormat.BC7_SRGB: return DDS.DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM;
|
||||
case SurfaceFormat.Invalid: throw new Exception("Invalid Format");
|
||||
default:
|
||||
throw new Exception($"Cannot convert format {Format}");
|
||||
|
@ -22,7 +22,7 @@ namespace FirstPlugin
|
||||
public FTEXContainer()
|
||||
{
|
||||
Text = "Textures";
|
||||
Name = "FTEXCONT";
|
||||
Name = "FTEX";
|
||||
|
||||
ContextMenu = new ContextMenu();
|
||||
MenuItem importTex = new MenuItem("Import");
|
||||
@ -44,9 +44,6 @@ namespace FirstPlugin
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnClick(TreeView treeview)
|
||||
{
|
||||
}
|
||||
public void RemoveTexture(FTEX textureData)
|
||||
{
|
||||
Nodes.Remove(textureData);
|
||||
@ -299,19 +296,27 @@ namespace FirstPlugin
|
||||
tex.Dim = (GX2SurfaceDim)surf.dim;
|
||||
tex.Use = (GX2SurfaceUse)surf.use;
|
||||
tex.TileMode = (GX2TileMode)surf.tileMode;
|
||||
tex.Swizzle = (uint)surf.swizzle;
|
||||
tex.Pitch = (uint)surf.pitch;
|
||||
tex.Depth = (uint)surf.depth;
|
||||
tex.MipCount = (uint)surf.numMips;
|
||||
tex.MipOffsets = surf.mipOffset;
|
||||
tex.Height = (uint)surf.height;
|
||||
tex.Width = (uint)surf.width;
|
||||
tex.Regs = new uint[0];
|
||||
tex.Swizzle = surf.swizzle;
|
||||
tex.Pitch = surf.pitch;
|
||||
tex.Depth = surf.depth;
|
||||
tex.MipCount = surf.numMips;
|
||||
|
||||
tex.MipOffsets = new uint[13];
|
||||
for (int i = 0; i < 13; i++)
|
||||
{
|
||||
if (i < surf.mipOffset.Length)
|
||||
tex.MipOffsets[i] = surf.mipOffset[i];
|
||||
}
|
||||
tex.Height = surf.height;
|
||||
tex.Width = surf.width;
|
||||
tex.Regs = new uint[5];
|
||||
tex.ArrayLength = 1;
|
||||
var channels = SetChannelsByFormat((GX2SurfaceFormat)surf.format);
|
||||
tex.CompSelR = channels[0];
|
||||
tex.CompSelG = channels[1];
|
||||
tex.CompSelB = channels[2];
|
||||
tex.CompSelA = channels[3];
|
||||
tex.UserData = new ResDict<UserData>();
|
||||
return tex;
|
||||
}
|
||||
private void Rename(object sender, EventArgs args)
|
||||
@ -357,6 +362,8 @@ namespace FirstPlugin
|
||||
SelectedImageKey = "Texture";
|
||||
Text = tex.Name;
|
||||
|
||||
texture = tex;
|
||||
|
||||
renderedTex = new RenderableTex();
|
||||
renderedTex.width = (int)tex.Width;
|
||||
renderedTex.height = (int)tex.Height;
|
||||
@ -400,6 +407,8 @@ namespace FirstPlugin
|
||||
renderedTex.mipmaps.Add(mips);
|
||||
|
||||
renderedTex.data = renderedTex.mipmaps[0][0];
|
||||
|
||||
LoadOpenGLTexture();
|
||||
}
|
||||
public static GX2CompSel[] SetChannelsByFormat(GX2SurfaceFormat Format)
|
||||
{
|
||||
|
@ -1,181 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using Switch_Toolbox.Library;
|
||||
using Switch_Toolbox.Library.IO;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public enum BlockType : uint
|
||||
{
|
||||
Invalid = 0x00,
|
||||
EndOfFile = 0x01,
|
||||
AlignData = 0x02,
|
||||
VertexShaderHeader = 0x03,
|
||||
VertexShaderProgram = 0x05,
|
||||
PixelShaderHeader = 0x06,
|
||||
PixelShaderProgram = 0x07,
|
||||
GeometryShaderHeader = 0x08,
|
||||
GeometryShaderProgram = 0x09,
|
||||
}
|
||||
|
||||
public class GTXFile : TreeNode, IFileFormat
|
||||
{
|
||||
public bool CanSave { get; set; } = false;
|
||||
public bool FileIsEdited { get; set; } = false;
|
||||
public bool FileIsCompressed { get; set; } = false;
|
||||
public string[] Description { get; set; } = new string[] { "GTX" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.gtx" };
|
||||
public string Magic { get; set; } = "Gfx2 ";
|
||||
public CompressionType CompressionType { get; set; } = CompressionType.None;
|
||||
public byte[] Data { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public bool IsActive { get; set; } = false;
|
||||
public bool UseEditMenu { get; set; } = false;
|
||||
public string FilePath { get; set; }
|
||||
public IFileInfo IFileInfo { get; set; }
|
||||
|
||||
public Type[] Types
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
return types.ToArray();
|
||||
}
|
||||
}
|
||||
private GTXHeader header;
|
||||
private GTXDataBlock block;
|
||||
|
||||
public void Load()
|
||||
{
|
||||
CanSave = true;
|
||||
|
||||
ReadGx2(new FileReader(Data));
|
||||
|
||||
|
||||
ContextMenu = new ContextMenu();
|
||||
MenuItem save = new MenuItem("Save");
|
||||
ContextMenu.MenuItems.Add(save);
|
||||
save.Click += Save;
|
||||
}
|
||||
private void Save(object sender, EventArgs args)
|
||||
{
|
||||
Save();
|
||||
}
|
||||
private void ReadGx2(FileReader reader)
|
||||
{
|
||||
header = new GTXHeader();
|
||||
header.Read(reader);
|
||||
|
||||
}
|
||||
public void Unload()
|
||||
{
|
||||
|
||||
}
|
||||
public byte[] Save()
|
||||
{
|
||||
System.IO.MemoryStream mem = new System.IO.MemoryStream();
|
||||
return mem.ToArray();
|
||||
}
|
||||
public class GTXHeader
|
||||
{
|
||||
public uint MajorVersion;
|
||||
public uint MinorVersion;
|
||||
public uint GpuVersion;
|
||||
public uint AlignMode;
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
string Signature = reader.ReadString(4, Encoding.ASCII);
|
||||
if (Signature != "Gfx2")
|
||||
throw new Exception($"Invalid signature {Signature}! Expected Gfx2.");
|
||||
|
||||
uint HeaderSize = reader.ReadUInt32();
|
||||
MajorVersion = reader.ReadUInt32();
|
||||
MinorVersion = reader.ReadUInt32();
|
||||
GpuVersion = reader.ReadUInt32();
|
||||
AlignMode = reader.ReadUInt32();
|
||||
}
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
writer.WriteSignature("Gfx2");
|
||||
writer.Write(MajorVersion);
|
||||
writer.Write(MinorVersion);
|
||||
writer.Write(GpuVersion);
|
||||
writer.Write(AlignMode);
|
||||
}
|
||||
}
|
||||
public class GTXDataBlock
|
||||
{
|
||||
public uint HeaderSize;
|
||||
public uint MajorVersion;
|
||||
public uint MinorVersion;
|
||||
public BlockType BlockType;
|
||||
public uint Identifier;
|
||||
public uint index;
|
||||
public uint DataSize;
|
||||
|
||||
public void Read(FileReader reader, GTXHeader header)
|
||||
{
|
||||
string Signature = reader.ReadString(4, Encoding.ASCII);
|
||||
if (Signature != "BLK")
|
||||
throw new Exception($"Invalid signature {Signature}! Expected BLK.");
|
||||
|
||||
HeaderSize = reader.ReadUInt32();
|
||||
MajorVersion = reader.ReadUInt32(); //Must be 0x01 for 6.x.x
|
||||
MinorVersion = reader.ReadUInt32(); //Must be 0x00 for 6.x.x
|
||||
BlockType = reader.ReadEnum<BlockType>(false);
|
||||
DataSize = reader.ReadUInt32();
|
||||
Identifier = reader.ReadUInt32();
|
||||
index = reader.ReadUInt32();
|
||||
}
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
writer.WriteSignature("BLK");
|
||||
writer.Write(HeaderSize);
|
||||
writer.Write(MajorVersion);
|
||||
writer.Write(MinorVersion);
|
||||
writer.Write(BlockType, true);
|
||||
writer.Write(DataSize);
|
||||
writer.Write(Identifier);
|
||||
writer.Write(index);
|
||||
}
|
||||
}
|
||||
public class TextureInfo
|
||||
{
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
|
||||
}
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class GTX
|
||||
{
|
||||
//Some enums and parts from https://github.com/jam1garner/Smash-Forge/blob/master/Smash%20Forge/Filetypes/Textures/GTX.cs
|
||||
//Todo. Add swizzling back
|
||||
public struct GX2Surface
|
||||
public class GX2Surface
|
||||
{
|
||||
public uint dim;
|
||||
public uint width;
|
||||
public uint height;
|
||||
public uint depth;
|
||||
public uint numMips;
|
||||
public uint firstSlice;
|
||||
public uint numSlices;
|
||||
public uint format;
|
||||
public uint aa;
|
||||
public uint use;
|
||||
public int resourceFlags;
|
||||
public uint imageSize;
|
||||
public uint imagePtr;
|
||||
public int pMem;
|
||||
public int MemPtr;
|
||||
public uint mipSize;
|
||||
public uint mipPtr;
|
||||
public uint tileMode;
|
||||
@ -183,15 +30,18 @@ namespace FirstPlugin
|
||||
public uint alignment;
|
||||
public uint pitch;
|
||||
public uint bpp;
|
||||
public uint imageCount;
|
||||
public uint firstMip;
|
||||
|
||||
public byte[] data;
|
||||
public byte[] mipData;
|
||||
|
||||
public uint[] mipOffset;
|
||||
public byte[] compSel;
|
||||
public uint[] texRegs;
|
||||
};
|
||||
|
||||
public static int m_configFlags = 4;
|
||||
public static int ADDR_OK = 0;
|
||||
|
||||
public static uint expPitch = 0;
|
||||
public static uint expHeight = 0;
|
||||
@ -579,6 +429,27 @@ namespace FirstPlugin
|
||||
|
||||
public static List<byte[]> Decode(GX2Surface tex)
|
||||
{
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("// ----- GX2Surface Decode Info ----- ");
|
||||
Console.WriteLine(" dim = " + tex.dim);
|
||||
Console.WriteLine(" width = " + tex.width);
|
||||
Console.WriteLine(" height = " + tex.height);
|
||||
Console.WriteLine(" depth = " + tex.depth);
|
||||
Console.WriteLine(" numMips = " + tex.numMips);
|
||||
Console.WriteLine(" format = " + tex.format);
|
||||
Console.WriteLine(" aa = " + tex.aa);
|
||||
Console.WriteLine(" use = " + tex.use);
|
||||
Console.WriteLine(" imageSize = " + tex.imageSize);
|
||||
Console.WriteLine(" mipSize = " + tex.mipSize);
|
||||
Console.WriteLine(" tileMode = " + tex.tileMode);
|
||||
Console.WriteLine(" swizzle = " + tex.swizzle);
|
||||
Console.WriteLine(" alignment = " + tex.alignment);
|
||||
Console.WriteLine(" pitch = " + tex.pitch);
|
||||
Console.WriteLine(" bits per pixel = " + (tex.bpp << 3));
|
||||
Console.WriteLine(" bytes per pixel = " + tex.bpp);
|
||||
Console.WriteLine(" data size = " + tex.data.Length);
|
||||
Console.WriteLine(" realSize = " + tex.imageSize);
|
||||
|
||||
uint blkWidth, blkHeight;
|
||||
if (IsFormatBCN((GX2SurfaceFormat)tex.format))
|
||||
{
|
||||
@ -594,7 +465,6 @@ namespace FirstPlugin
|
||||
byte[] data = tex.data;
|
||||
|
||||
var surfInfo = getSurfaceInfo((GX2SurfaceFormat)tex.format, tex.width, tex.height, tex.depth, (uint)tex.dim, (uint)tex.tileMode, (uint)tex.aa, 0);
|
||||
Debug(surfInfo);
|
||||
uint bpp = TegraX1Swizzle.DIV_ROUND_UP(surfInfo.bpp, 8);
|
||||
|
||||
if (surfInfo.depth != 1)
|
||||
@ -616,7 +486,7 @@ namespace FirstPlugin
|
||||
mipOffset -= (uint)surfInfo.surfSize;
|
||||
|
||||
surfInfo = getSurfaceInfo((GX2SurfaceFormat)tex.format, tex.width, tex.height, tex.depth, (uint)tex.dim, (uint)tex.tileMode, (uint)tex.aa, mipLevel);
|
||||
data = new byte[surfInfo.surfSize + mipOffset];
|
||||
data = new byte[surfInfo.surfSize];
|
||||
Array.Copy(tex.mipData, mipOffset, data, 0, surfInfo.surfSize);
|
||||
}
|
||||
byte[] deswizzled = deswizzle(width_, height_, surfInfo.height, (uint)tex.format,
|
||||
@ -634,24 +504,10 @@ namespace FirstPlugin
|
||||
|
||||
/*---------------------------------------
|
||||
*
|
||||
* Code ported from AboodXD's GTX Extractor https://github.com/aboood40091/GTX-Extractor/blob/master/gtx_extract.py
|
||||
*
|
||||
* With help by Aelan!
|
||||
* Code ported from AboodXD's GTX Extractorhttps://github.com/aboood40091/GTX-Extractor/blob/f586dde90bd4a262421a4a565c1556d0079a748e/addrlib/addrlib_cy.pyx
|
||||
*
|
||||
*---------------------------------------*/
|
||||
|
||||
/*var s_textureFormats[] = {
|
||||
// internalFormat, gxFormat, glFormat, fourCC, nutFormat, name, bpp, compressed
|
||||
{ FORMAT_RGBA_8888, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GL_RGBA8, 0x00000000, 0x11, "RGBA_8888", 0x20, 0 },
|
||||
{ FORMAT_ABGR_8888, GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM, GL_RGBA8, 0x00000000, 0x0E, "ABGR_8888 (WIP)", 0x20, 0 },
|
||||
{ FORMAT_DXT1, GX2_SURFACE_FORMAT_T_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0x31545844, 0x00, "DXT1", 0x40, 1 },
|
||||
{ FORMAT_DXT3, GX2_SURFACE_FORMAT_T_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0x33545844, 0x01, "DXT3", 0x80, 1 },
|
||||
{ FORMAT_DXT5, GX2_SURFACE_FORMAT_T_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0x35545844, 0x02, "DXT5", 0x80, 1 },
|
||||
{ FORMAT_ATI1, GX2_SURFACE_FORMAT_T_BC4_UNORM, GL_COMPRESSED_RED_RGTC1, 0x31495441, 0x15, "ATI1", 0x40, 1 },
|
||||
{ FORMAT_ATI2, GX2_SURFACE_FORMAT_T_BC5_UNORM, GL_COMPRESSED_RG_RGTC2, 0x32495441, 0x16, "ATI2", 0x80, 1 },
|
||||
{ FORMAT_INVALID, GX2_SURFACE_FORMAT_INVALID, 0, 0xFFFFFFFF, 0x00, nullptr, 0x00, 0 }
|
||||
};*/
|
||||
|
||||
public static bool IsFormatBCN(GX2SurfaceFormat Format)
|
||||
{
|
||||
switch (Format)
|
||||
@ -686,19 +542,6 @@ namespace FirstPlugin
|
||||
private static byte[] swizzleSurf(uint width, uint height, uint height_, uint format, uint tileMode, uint swizzle_,
|
||||
uint pitch, uint bitsPerPixel, byte[] data, int swizzle)
|
||||
{
|
||||
Console.WriteLine("swizzling level....");
|
||||
Console.WriteLine("---------------------------");
|
||||
Console.WriteLine("width " + width);
|
||||
Console.WriteLine("height " + height);
|
||||
Console.WriteLine("height_ " + height_);
|
||||
Console.WriteLine("format " + format);
|
||||
Console.WriteLine("tileMode " + tileMode);
|
||||
Console.WriteLine("swizzle_ " + swizzle_);
|
||||
Console.WriteLine("pitch " + pitch);
|
||||
Console.WriteLine("bitsPerPixel " + bitsPerPixel);
|
||||
Console.WriteLine("swizzle " + swizzle);
|
||||
Console.WriteLine("---------------------------");
|
||||
|
||||
uint bytesPerPixel = bitsPerPixel / 8;
|
||||
byte[] result = new byte[data.Length];
|
||||
|
||||
@ -1809,11 +1652,6 @@ namespace FirstPlugin
|
||||
if (padDims == 0)
|
||||
padDims = 3;
|
||||
|
||||
Console.WriteLine("padDims " + padDims);
|
||||
Console.WriteLine("pitchAlign " + pitchAlign);
|
||||
|
||||
|
||||
|
||||
if ((pitchAlign & (pitchAlign - 1)) == 0)
|
||||
expPitch = powTwoAlign(expPitch, pitchAlign);
|
||||
else
|
||||
@ -1826,10 +1664,6 @@ namespace FirstPlugin
|
||||
if (padDims > 1)
|
||||
expHeight = powTwoAlign(expHeight, heightAlign);
|
||||
|
||||
Console.WriteLine("expPitch " + expPitch);
|
||||
Console.WriteLine("expHeight " + expHeight);
|
||||
Console.WriteLine("expNumSlices " + expNumSlices);
|
||||
|
||||
if (padDims > 2 || thickness > 1)
|
||||
{
|
||||
if (isCube != 0)
|
||||
@ -1838,10 +1672,6 @@ namespace FirstPlugin
|
||||
if (thickness > 1)
|
||||
expNumSlices = powTwoAlign(expNumSlices, sliceAlign);
|
||||
}
|
||||
Console.WriteLine("expPitch " + expPitch);
|
||||
Console.WriteLine("expHeight " + expHeight);
|
||||
Console.WriteLine("expNumSlices " + expNumSlices);
|
||||
|
||||
return new Tuple<uint, uint, uint>(expPitch, expHeight, expNumSlices);
|
||||
}
|
||||
|
||||
@ -1885,9 +1715,6 @@ namespace FirstPlugin
|
||||
microTileThickness = 1;
|
||||
}
|
||||
}
|
||||
Console.WriteLine($"baseTileMode {baseTileMode}");
|
||||
Console.WriteLine($"tileMode {tileMode}");
|
||||
|
||||
if (tileMode == baseTileMode
|
||||
|| mipLevel == 0
|
||||
|| isThickMacroTiled((AddrTileMode)baseTileMode) == 0
|
||||
@ -1907,29 +1734,9 @@ namespace FirstPlugin
|
||||
|
||||
bankSwappedWidth = computeSurfaceBankSwappedWidth((AddrTileMode)tileMode, bpp, pitch, numSamples);
|
||||
|
||||
Console.WriteLine("---------------------");
|
||||
Console.WriteLine(baseAlign);
|
||||
Console.WriteLine(pitchAlign);
|
||||
Console.WriteLine(heightAlign);
|
||||
Console.WriteLine(macroWidth);
|
||||
Console.WriteLine(macroHeight);
|
||||
Console.WriteLine(bankSwappedWidth);
|
||||
Console.WriteLine("---------------------");
|
||||
|
||||
if (bankSwappedWidth > pitchAlign)
|
||||
pitchAlign = bankSwappedWidth;
|
||||
|
||||
Console.WriteLine("padDimensions");
|
||||
Console.WriteLine(tileMode);
|
||||
Console.WriteLine(padDims);
|
||||
Console.WriteLine((flags.value >> 4) & 1);
|
||||
Console.WriteLine((flags.value >> 7) & 1);
|
||||
Console.WriteLine(pitchAlign);
|
||||
Console.WriteLine(heightAlign);
|
||||
Console.WriteLine(microTileThickness);
|
||||
Console.WriteLine("---------------------");
|
||||
Console.WriteLine("expPitch " + expPitch);
|
||||
|
||||
var padDimens = padDimensions(
|
||||
tileMode,
|
||||
padDims,
|
||||
@ -1943,14 +1750,6 @@ namespace FirstPlugin
|
||||
expHeight = padDimens.Item2;
|
||||
expNumSlices = padDimens.Item3;
|
||||
|
||||
Console.WriteLine(expPitch);
|
||||
Console.WriteLine(expHeight);
|
||||
Console.WriteLine(expNumSlices);
|
||||
Console.WriteLine(bpp);
|
||||
Console.WriteLine(numSamples);
|
||||
|
||||
Console.WriteLine("---------------------");
|
||||
|
||||
pPitchOut = expPitch;
|
||||
pHeightOut = expHeight;
|
||||
pNumSlicesOut = expNumSlices;
|
||||
@ -2041,12 +1840,6 @@ namespace FirstPlugin
|
||||
pHeightOut = expHeight;
|
||||
pNumSlicesOut = expNumSlices;
|
||||
pSurfSize = (expHeight * expPitch * expNumSlices * bpp * numSamples + 7) / 8;
|
||||
Console.WriteLine($"expHeight {expHeight}");
|
||||
Console.WriteLine($"expPitch {expPitch}");
|
||||
Console.WriteLine($"expNumSlices {expNumSlices}");
|
||||
Console.WriteLine($"bpp {bpp}");
|
||||
Console.WriteLine($"numSamples {numSamples}");
|
||||
Console.WriteLine($"bpp {bpp}");
|
||||
|
||||
pTileModeOut = expTileMode;
|
||||
pBaseAlign = baseAlign;
|
||||
|
562
Switch_FileFormatsMain/FileFormats/Texture/GTXFile.cs
Normal file
562
Switch_FileFormatsMain/FileFormats/Texture/GTXFile.cs
Normal file
@ -0,0 +1,562 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Switch_Toolbox.Library.IO;
|
||||
using Switch_Toolbox.Library;
|
||||
using System.Windows.Forms;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public enum BlockType : uint
|
||||
{
|
||||
Invalid = 0x00,
|
||||
EndOfFile = 0x01,
|
||||
AlignData = 0x02,
|
||||
VertexShaderHeader = 0x03,
|
||||
VertexShaderProgram = 0x05,
|
||||
PixelShaderHeader = 0x06,
|
||||
PixelShaderProgram = 0x07,
|
||||
GeometryShaderHeader = 0x08,
|
||||
GeometryShaderProgram = 0x09,
|
||||
GeometryShaderProgram2 = 0x10,
|
||||
ImageInfo = 0x11,
|
||||
ImageData = 0x12,
|
||||
MipData = 0x13,
|
||||
ComputeShaderHeader = 0x14,
|
||||
ComputeShader = 0x15,
|
||||
UserBlock = 0x16,
|
||||
}
|
||||
|
||||
public class GTXFile : TreeNode, IFileFormat
|
||||
{
|
||||
public bool CanSave { get; set; } = false;
|
||||
public bool FileIsEdited { get; set; } = false;
|
||||
public bool FileIsCompressed { get; set; } = false;
|
||||
public string[] Description { get; set; } = new string[] { "GTX" };
|
||||
public string[] Extension { get; set; } = new string[] { "*.gtx" };
|
||||
public string Magic { get; set; } = "Gfx2 ";
|
||||
public CompressionType CompressionType { get; set; } = CompressionType.None;
|
||||
public byte[] Data { get; set; }
|
||||
public string FileName { get; set; }
|
||||
public bool IsActive { get; set; } = false;
|
||||
public bool UseEditMenu { get; set; } = false;
|
||||
public string FilePath { get; set; }
|
||||
public IFileInfo IFileInfo { get; set; }
|
||||
|
||||
public Type[] Types
|
||||
{
|
||||
get
|
||||
{
|
||||
List<Type> types = new List<Type>();
|
||||
return types.ToArray();
|
||||
}
|
||||
}
|
||||
private GTXHeader header;
|
||||
|
||||
public List<byte[]> data = new List<byte[]>();
|
||||
public List<byte[]> mipMaps = new List<byte[]>();
|
||||
public List<TextureData> textures = new List<TextureData>();
|
||||
|
||||
public List<GTXDataBlock> blocks = new List<GTXDataBlock>();
|
||||
|
||||
public void Load()
|
||||
{
|
||||
CanSave = true;
|
||||
Text = FileName;
|
||||
|
||||
ReadGx2(new FileReader(Data));
|
||||
|
||||
ContextMenu = new ContextMenu();
|
||||
MenuItem save = new MenuItem("Save");
|
||||
ContextMenu.MenuItems.Add(save);
|
||||
save.Click += Save;
|
||||
}
|
||||
private void Save(object sender, EventArgs args)
|
||||
{
|
||||
SaveFileDialog sfd = new SaveFileDialog();
|
||||
sfd.DefaultExt = "gtx";
|
||||
sfd.Filter = "Supported Formats|*.gtx;";
|
||||
sfd.FileName = FileName;
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
STFileSaver.SaveFileFormat(this, sfd.FileName);
|
||||
}
|
||||
}
|
||||
public void Unload()
|
||||
{
|
||||
}
|
||||
public byte[] Save()
|
||||
{
|
||||
System.IO.MemoryStream mem = new System.IO.MemoryStream();
|
||||
using (FileWriter writer = new FileWriter(mem))
|
||||
{
|
||||
writer.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
|
||||
header.Write(writer);
|
||||
writer.Seek(header.HeaderSize, System.IO.SeekOrigin.Begin);
|
||||
foreach (var block in blocks)
|
||||
block.Write(writer);
|
||||
}
|
||||
return mem.ToArray();
|
||||
}
|
||||
private void ReadGx2(FileReader reader)
|
||||
{
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
|
||||
header = new GTXHeader();
|
||||
header.Read(reader);
|
||||
|
||||
Console.WriteLine("header size " + header.HeaderSize);
|
||||
|
||||
uint surfBlockType;
|
||||
uint dataBlockType;
|
||||
uint mipBlockType;
|
||||
|
||||
if (header.MajorVersion == 6)
|
||||
{
|
||||
surfBlockType = 0x0A;
|
||||
dataBlockType = 0x0B;
|
||||
mipBlockType = 0x0C;
|
||||
}
|
||||
else if (header.MajorVersion == 7)
|
||||
{
|
||||
surfBlockType = 0x0B;
|
||||
dataBlockType = 0x0C;
|
||||
mipBlockType = 0x0D;
|
||||
}
|
||||
else
|
||||
throw new Exception($"Unsupported GTX version {header.MajorVersion}");
|
||||
|
||||
if (header.GpuVersion != 2)
|
||||
throw new Exception($"Unsupported GPU version {header.GpuVersion}");
|
||||
|
||||
reader.Position = header.HeaderSize;
|
||||
|
||||
bool blockB = false;
|
||||
bool blockC = false;
|
||||
|
||||
uint ImageInfo = 0;
|
||||
uint images = 0;
|
||||
|
||||
while (reader.Position < reader.BaseStream.Length)
|
||||
{
|
||||
GTXDataBlock block = new GTXDataBlock();
|
||||
block.Read(reader);
|
||||
blocks.Add(block);
|
||||
|
||||
//Here we use "if" instead of "case" statements as types vary between versions
|
||||
if ((uint)block.BlockType == surfBlockType)
|
||||
{
|
||||
ImageInfo += 1;
|
||||
blockB = true;
|
||||
|
||||
var surface = new SurfaceInfoParse();
|
||||
surface.Read(new FileReader(block.data));
|
||||
|
||||
if (surface.numMips > 14)
|
||||
throw new Exception($"Invalid number of mip maps {surface.numMips}!");
|
||||
|
||||
TextureData textureData = new TextureData();
|
||||
textureData.surface = surface;
|
||||
textureData.Text = "Texture" + ImageInfo;
|
||||
Nodes.Add(textureData);
|
||||
textures.Add(textureData);
|
||||
}
|
||||
else if ((uint)block.BlockType == dataBlockType)
|
||||
{
|
||||
images += 1;
|
||||
blockC = true;
|
||||
|
||||
data.Add(block.data);
|
||||
}
|
||||
else if ((uint)block.BlockType == mipBlockType)
|
||||
{
|
||||
mipMaps.Add(block.data);
|
||||
}
|
||||
}
|
||||
if (textures.Count != data.Count)
|
||||
throw new Exception($"Bad size! {textures.Count} {data.Count}");
|
||||
|
||||
int curTex = 0;
|
||||
int curMip = 0;
|
||||
foreach (var node in Nodes)
|
||||
{
|
||||
TextureData tex = (TextureData)node;
|
||||
tex.surface.data = data[curTex];
|
||||
tex.surface.bpp = GTX.surfaceGetBitsPerPixel(tex.surface.format) >> 3;
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
if (tex.surface.numMips > 1 )
|
||||
tex.surface.mipData = mipMaps[curMip++];
|
||||
else
|
||||
tex.surface.mipData = new byte[0];
|
||||
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("// ----- GX2Surface Info ----- ");
|
||||
Console.WriteLine(" dim = " + tex.surface.dim);
|
||||
Console.WriteLine(" width = " + tex.surface.width);
|
||||
Console.WriteLine(" height = " + tex.surface.height);
|
||||
Console.WriteLine(" depth = " + tex.surface.depth);
|
||||
Console.WriteLine(" numMips = " + tex.surface.numMips);
|
||||
Console.WriteLine(" format = " + tex.surface.format);
|
||||
Console.WriteLine(" aa = " + tex.surface.aa);
|
||||
Console.WriteLine(" use = " + tex.surface.use);
|
||||
Console.WriteLine(" imageSize = " + tex.surface.imageSize);
|
||||
Console.WriteLine(" mipSize = " + tex.surface.mipSize);
|
||||
Console.WriteLine(" tileMode = " + tex.surface.tileMode);
|
||||
Console.WriteLine(" swizzle = " + tex.surface.swizzle);
|
||||
Console.WriteLine(" alignment = " + tex.surface.alignment);
|
||||
Console.WriteLine(" pitch = " + tex.surface.pitch);
|
||||
Console.WriteLine(" bits per pixel = " + (tex.surface.bpp << 3));
|
||||
Console.WriteLine(" bytes per pixel = " + tex.surface.bpp);
|
||||
Console.WriteLine(" data size = " + tex.surface.data.Length);
|
||||
Console.WriteLine(" mip size = " + tex.surface.mipData.Length);
|
||||
Console.WriteLine(" realSize = " + tex.surface.imageSize);
|
||||
|
||||
List<byte[]> mips = GTX.Decode(tex.surface);
|
||||
tex.renderedTex.mipmaps.Add(mips);
|
||||
tex.renderedTex.width = (int)tex.surface.width;
|
||||
tex.renderedTex.height = (int)tex.surface.height;
|
||||
|
||||
curTex++;
|
||||
}
|
||||
}
|
||||
public class GTXHeader
|
||||
{
|
||||
readonly string Magic = "Gfx2";
|
||||
public uint HeaderSize;
|
||||
public uint MajorVersion;
|
||||
public uint MinorVersion;
|
||||
public uint GpuVersion;
|
||||
public uint AlignMode;
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
string Signature = reader.ReadString(4, Encoding.ASCII);
|
||||
if (Signature != Magic)
|
||||
throw new Exception($"Invalid signature {Signature}! Expected Gfx2.");
|
||||
|
||||
HeaderSize = reader.ReadUInt32();
|
||||
MajorVersion = reader.ReadUInt32();
|
||||
MinorVersion = reader.ReadUInt32();
|
||||
GpuVersion = reader.ReadUInt32();
|
||||
AlignMode = reader.ReadUInt32();
|
||||
}
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
writer.WriteSignature(Magic);
|
||||
writer.Write(HeaderSize);
|
||||
writer.Write(MajorVersion);
|
||||
writer.Write(MinorVersion);
|
||||
writer.Write(GpuVersion);
|
||||
writer.Write(AlignMode);
|
||||
}
|
||||
}
|
||||
public class GTXDataBlock
|
||||
{
|
||||
readonly string Magic = "BLK{";
|
||||
public uint HeaderSize;
|
||||
public uint MajorVersion;
|
||||
public uint MinorVersion;
|
||||
public BlockType BlockType;
|
||||
public uint Identifier;
|
||||
public uint index;
|
||||
public uint DataSize;
|
||||
public byte[] data;
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
long blockStart = reader.Position;
|
||||
|
||||
string Signature = reader.ReadString(4, Encoding.ASCII);
|
||||
if (Signature != Magic)
|
||||
throw new Exception($"Invalid signature {Signature}! Expected BLK.");
|
||||
|
||||
HeaderSize = reader.ReadUInt32();
|
||||
MajorVersion = reader.ReadUInt32(); //Must be 0x01 for 6.x.x
|
||||
MinorVersion = reader.ReadUInt32(); //Must be 0x00 for 6.x.x
|
||||
BlockType = reader.ReadEnum<BlockType>(false);
|
||||
DataSize = reader.ReadUInt32();
|
||||
Identifier = reader.ReadUInt32();
|
||||
index = reader.ReadUInt32();
|
||||
|
||||
reader.Seek(blockStart + HeaderSize, System.IO.SeekOrigin.Begin);
|
||||
data = reader.ReadBytes((int)DataSize);
|
||||
System.IO.File.WriteAllBytes($"block {BlockType}.bin", data);
|
||||
}
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
long blockStart = writer.Position;
|
||||
|
||||
writer.WriteSignature(Magic);
|
||||
writer.Write(HeaderSize);
|
||||
writer.Write(MajorVersion);
|
||||
writer.Write(MinorVersion);
|
||||
writer.Write(BlockType, false);
|
||||
writer.Write(DataSize);
|
||||
writer.Write(Identifier);
|
||||
writer.Write(index);
|
||||
writer.Seek(blockStart + HeaderSize, System.IO.SeekOrigin.Begin);
|
||||
|
||||
writer.Write(data);
|
||||
}
|
||||
}
|
||||
public class TextureData : TreeNodeCustom
|
||||
{
|
||||
public SurfaceInfoParse surface;
|
||||
public RenderableTex renderedTex = new RenderableTex();
|
||||
|
||||
public TextureData()
|
||||
{
|
||||
ImageKey = "Texture";
|
||||
SelectedImageKey = "Texture";
|
||||
|
||||
ContextMenu = new ContextMenu();
|
||||
MenuItem export = new MenuItem("Export");
|
||||
ContextMenu.MenuItems.Add(export);
|
||||
export.Click += Export;
|
||||
MenuItem replace = new MenuItem("Replace");
|
||||
ContextMenu.MenuItems.Add(replace);
|
||||
replace.Click += Replace;
|
||||
MenuItem remove = new MenuItem("Remove");
|
||||
ContextMenu.MenuItems.Add(remove);
|
||||
remove.Click += Remove;
|
||||
}
|
||||
private void Remove(object sender, EventArgs args)
|
||||
{
|
||||
((GTXFile)Parent).Nodes.Remove(this);
|
||||
}
|
||||
private void Export(object sender, EventArgs args)
|
||||
{
|
||||
SaveFileDialog sfd = new SaveFileDialog();
|
||||
sfd.FileName = Text;
|
||||
sfd.DefaultExt = "bftex";
|
||||
sfd.Filter = "Supported Formats|*.bftex;*.dds; *.png;*.tga;*.jpg;*.tiff|" +
|
||||
"Binary Texture |*.bftex|" +
|
||||
"Microsoft DDS |*.dds|" +
|
||||
"Portable Network Graphics |*.png|" +
|
||||
"Joint Photographic Experts Group |*.jpg|" +
|
||||
"Bitmap Image |*.bmp|" +
|
||||
"Tagged Image File Format |*.tiff|" +
|
||||
"All files(*.*)|*.*";
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
Export(sfd.FileName);
|
||||
}
|
||||
}
|
||||
public void Export(string FileName, bool ExportSurfaceLevel = false,
|
||||
bool ExportMipMapLevel = false, int SurfaceLevel = 0, int MipLevel = 0)
|
||||
{
|
||||
string ext = System.IO.Path.GetExtension(FileName);
|
||||
ext = ext.ToLower();
|
||||
|
||||
switch (ext)
|
||||
{
|
||||
case ".dds":
|
||||
SaveDDS(FileName);
|
||||
break;
|
||||
default:
|
||||
SaveBitMap(FileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
internal void SaveBitMap(string FileName, int SurfaceLevel = 0, int MipLevel = 0)
|
||||
{
|
||||
Bitmap bitMap = DisplayTexture(MipLevel, SurfaceLevel);
|
||||
|
||||
bitMap.Save(FileName);
|
||||
}
|
||||
internal void SaveDDS(string FileName)
|
||||
{
|
||||
DDS dds = new DDS();
|
||||
dds.header = new DDS.Header();
|
||||
dds.header.width = (uint)renderedTex.width;
|
||||
dds.header.height = (uint)renderedTex.width;
|
||||
dds.header.mipmapCount = (uint)renderedTex.mipmaps[0].Count;
|
||||
|
||||
dds.header.pitchOrLinearSize = (uint)renderedTex.mipmaps[0][0].Length;
|
||||
|
||||
|
||||
|
||||
dds.Save(dds, FileName, renderedTex.mipmaps);
|
||||
}
|
||||
private void Replace(object sender, EventArgs args)
|
||||
{
|
||||
OpenFileDialog ofd = new OpenFileDialog();
|
||||
ofd.Filter = "Supported Formats|*.dds; *.png;*.tga;*.jpg;*.tiff|" +
|
||||
"Microsoft DDS |*.dds|" +
|
||||
"Portable Network Graphics |*.png|" +
|
||||
"Joint Photographic Experts Group |*.jpg|" +
|
||||
"Bitmap Image |*.bmp|" +
|
||||
"Tagged Image File Format |*.tiff|" +
|
||||
"All files(*.*)|*.*";
|
||||
|
||||
ofd.Multiselect = false;
|
||||
if (ofd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
Replace(ofd.FileName);
|
||||
}
|
||||
}
|
||||
public void Replace(string FileName)
|
||||
{
|
||||
string ext = System.IO.Path.GetExtension(FileName);
|
||||
ext = ext.ToLower();
|
||||
|
||||
GTXImporterSettings setting = new GTXImporterSettings();
|
||||
GTXTextureImporter importer = new GTXTextureImporter();
|
||||
|
||||
switch (ext)
|
||||
{
|
||||
case ".dds":
|
||||
setting.LoadDDS(FileName, null);
|
||||
break;
|
||||
default:
|
||||
setting.LoadBitMap(FileName);
|
||||
importer.LoadSetting(setting);
|
||||
break;
|
||||
}
|
||||
|
||||
if (importer.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
|
||||
if (setting.GenerateMipmaps)
|
||||
{
|
||||
setting.DataBlockOutput.Clear();
|
||||
setting.DataBlockOutput.Add(setting.GenerateMips());
|
||||
}
|
||||
|
||||
if (setting.DataBlockOutput != null)
|
||||
{
|
||||
var surface = setting.CreateGx2Texture(setting.DataBlockOutput[0]);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Something went wrong???");
|
||||
}
|
||||
UpdateEditor();
|
||||
}
|
||||
}
|
||||
public class RenderableTex
|
||||
{
|
||||
public int width, height;
|
||||
public int display;
|
||||
public PixelInternalFormat pixelInternalFormat;
|
||||
public PixelFormat pixelFormat;
|
||||
public PixelType pixelType = PixelType.UnsignedByte;
|
||||
public int mipMapCount;
|
||||
public List<List<byte[]>> mipmaps = new List<List<byte[]>>();
|
||||
public byte[] data;
|
||||
|
||||
public class Surface
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnClick(TreeView treeView)
|
||||
{
|
||||
UpdateEditor();
|
||||
}
|
||||
|
||||
public void UpdateEditor()
|
||||
{
|
||||
if (Viewport.Instance.gL_ControlModern1.Visible == false)
|
||||
PluginRuntime.FSHPDockState = WeifenLuo.WinFormsUI.Docking.DockState.Document;
|
||||
|
||||
GTXEditor docked = (GTXEditor)LibraryGUI.Instance.GetContentDocked(new GTXEditor());
|
||||
if (docked == null)
|
||||
{
|
||||
docked = new GTXEditor();
|
||||
LibraryGUI.Instance.LoadDockContent(docked, PluginRuntime.FSHPDockState);
|
||||
}
|
||||
docked.Text = Text;
|
||||
docked.Dock = DockStyle.Fill;
|
||||
docked.LoadPicture(DisplayTexture());
|
||||
docked.LoadProperty(this);
|
||||
}
|
||||
|
||||
public Bitmap DisplayTexture(int DisplayMipIndex = 0, int ArrayIndex = 0)
|
||||
{
|
||||
if (renderedTex.mipmaps.Count <= 0)
|
||||
{
|
||||
throw new Exception("No texture data found");
|
||||
}
|
||||
|
||||
uint width = (uint)Math.Max(1, renderedTex.width >> DisplayMipIndex);
|
||||
uint height = (uint)Math.Max(1, renderedTex.height >> DisplayMipIndex);
|
||||
|
||||
byte[] data = renderedTex.mipmaps[ArrayIndex][DisplayMipIndex];
|
||||
|
||||
return FTEX.DecodeBlock(data, width, height, (Syroot.NintenTools.Bfres.GX2.GX2SurfaceFormat)surface.format);
|
||||
}
|
||||
}
|
||||
public class SurfaceInfoParse : GTX.GX2Surface
|
||||
{
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||
|
||||
dim = reader.ReadUInt32();
|
||||
width = reader.ReadUInt32();
|
||||
height = reader.ReadUInt32();
|
||||
depth = reader.ReadUInt32();
|
||||
numMips = reader.ReadUInt32();
|
||||
format = reader.ReadUInt32();
|
||||
aa = reader.ReadUInt32();
|
||||
use = reader.ReadUInt32();
|
||||
imageSize = reader.ReadUInt32();
|
||||
imagePtr = reader.ReadUInt32();
|
||||
mipSize = reader.ReadUInt32();
|
||||
mipPtr = reader.ReadUInt32();
|
||||
tileMode = reader.ReadUInt32();
|
||||
swizzle = reader.ReadUInt32();
|
||||
alignment = reader.ReadUInt32();
|
||||
pitch = reader.ReadUInt32();
|
||||
mipOffset = reader.ReadUInt32s(13);
|
||||
firstMip = reader.ReadUInt32();
|
||||
imageCount = reader.ReadUInt32();
|
||||
firstSlice = reader.ReadUInt32();
|
||||
numSlices = reader.ReadUInt32();
|
||||
compSel = reader.ReadBytes(4);
|
||||
texRegs = reader.ReadUInt32s(5);
|
||||
}
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
writer.Write(dim);
|
||||
writer.Write(width);
|
||||
writer.Write(height);
|
||||
writer.Write(depth);
|
||||
writer.Write(numMips);
|
||||
writer.Write(format);
|
||||
writer.Write(aa);
|
||||
writer.Write(use);
|
||||
writer.Write(imageSize);
|
||||
writer.Write(imagePtr);
|
||||
writer.Write(mipSize);
|
||||
writer.Write(mipPtr);
|
||||
writer.Write(tileMode);
|
||||
writer.Write(swizzle);
|
||||
writer.Write(alignment);
|
||||
writer.Write(pitch);
|
||||
writer.Write(mipOffset);
|
||||
writer.Write(firstMip);
|
||||
writer.Write(imageCount);
|
||||
writer.Write(firstSlice);
|
||||
writer.Write(numSlices);
|
||||
writer.Write(compSel);
|
||||
writer.Write(texRegs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -156,7 +156,6 @@ namespace FirstPlugin
|
||||
{
|
||||
Console.WriteLine("Something went wrong??");
|
||||
}
|
||||
texture.blocksCompressed.Clear();
|
||||
texture.mipmaps.Clear();
|
||||
|
||||
|
||||
@ -177,7 +176,7 @@ namespace FirstPlugin
|
||||
public List<uint[]> mipSizes = new List<uint[]>();
|
||||
public int Alignment;
|
||||
public List<List<byte[]>> mipmaps = new List<List<byte[]>>();
|
||||
public List<List<byte[]>> blocksCompressed = new List<List<byte[]>>();
|
||||
public byte[] ImageData;
|
||||
bool IsSwizzled = true;
|
||||
public string ArcOffset; //Temp for exporting in batch
|
||||
|
||||
@ -200,7 +199,7 @@ namespace FirstPlugin
|
||||
var bntxFile = new BNTX();
|
||||
var tex = new TextureData();
|
||||
tex.Replace(ofd.FileName);
|
||||
blocksCompressed = tex.Texture.TextureData;
|
||||
ImageData = tex.Texture.TextureData[0][0];
|
||||
mipmaps = tex.mipmaps;
|
||||
Width = tex.Texture.Width;
|
||||
Height = tex.Texture.Height;
|
||||
@ -236,8 +235,7 @@ namespace FirstPlugin
|
||||
|
||||
if (sfd.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
System.IO.File.WriteAllBytes(sfd.FileName, Save());
|
||||
STFileSaver.SaveFileFormat(this, sfd.FileName);
|
||||
}
|
||||
}
|
||||
public void Export(string FileName, bool ExportSurfaceLevel = false,
|
||||
@ -318,39 +316,17 @@ namespace FirstPlugin
|
||||
//Seek to next one
|
||||
reader.Seek(mipPos + 0x40, System.IO.SeekOrigin.Begin);
|
||||
}
|
||||
|
||||
|
||||
reader.Seek(0, System.IO.SeekOrigin.Begin);
|
||||
for (int arrayLevel = 1; arrayLevel < ArrayCount + 1; arrayLevel++)
|
||||
{
|
||||
List<byte[]> mipmaps = new List<byte[]>();
|
||||
ImageData = reader.ReadBytes(imagesize);
|
||||
|
||||
for (int mipLevel = 0; mipLevel < mipCount; mipLevel++)
|
||||
{
|
||||
//Get the size from the size array
|
||||
int size = (int)mipSizes[arrayLevel - 1][mipLevel];
|
||||
|
||||
//Align the size
|
||||
if (mipLevel == 0)
|
||||
if (size % Alignment != 0) size = size + (Alignment - (size % Alignment));
|
||||
|
||||
mipmaps.Add(reader.ReadBytes(imagesize));
|
||||
break;
|
||||
}
|
||||
blocksCompressed.Add(mipmaps);
|
||||
//Seek the next array
|
||||
reader.Seek(imagesize / (int)ArrayCount, System.IO.SeekOrigin.Begin);
|
||||
}
|
||||
LoadTexture();
|
||||
}
|
||||
public void Write(FileWriter writer)
|
||||
{
|
||||
int arrayCount = blocksCompressed.Count;
|
||||
int arrayCount = mipSizes.Count;
|
||||
|
||||
writer.Write(ImageData); //Write textue block first
|
||||
|
||||
foreach (var array in blocksCompressed)
|
||||
{
|
||||
writer.Write(array[0]); //Write textue block first
|
||||
}
|
||||
long headerStart = writer.Position;
|
||||
foreach (var mips in mipSizes)
|
||||
{
|
||||
@ -371,10 +347,10 @@ namespace FirstPlugin
|
||||
writer.Write((byte)unk);
|
||||
writer.Seek(2); //padding
|
||||
writer.Write(unk2);
|
||||
writer.Write(blocksCompressed[0].Count);
|
||||
writer.Write(mipSizes.Count);
|
||||
writer.Write(Alignment);
|
||||
writer.Write(arrayCount);
|
||||
writer.Write(blocksCompressed[0][0].Length * arrayCount);
|
||||
writer.Write(ImageData.Length);
|
||||
writer.WriteSignature(" XET");
|
||||
writer.Write(131073);
|
||||
|
||||
@ -392,7 +368,7 @@ namespace FirstPlugin
|
||||
if (IsSwizzled)
|
||||
LoadTexture();
|
||||
else
|
||||
mipmaps.Add(blocksCompressed[ArrayIndex]);
|
||||
mipmaps.Add(new List<byte[]>() { ImageData });
|
||||
|
||||
if (mipmaps[0].Count <= 0)
|
||||
{
|
||||
@ -504,13 +480,21 @@ namespace FirstPlugin
|
||||
|
||||
uint bpp = bpps((byte)Format);
|
||||
|
||||
for (int arrayLevel = 0; arrayLevel < blocksCompressed.Count; arrayLevel++)
|
||||
for (int arrayLevel = 0; arrayLevel < mipSizes.Count; arrayLevel++)
|
||||
{
|
||||
int blockHeightShift = 0;
|
||||
uint mipOffset = 0;
|
||||
|
||||
List<byte[]> mips = new List<byte[]>();
|
||||
for (int mipLevel = 0; mipLevel < blocksCompressed[arrayLevel].Count; mipLevel++)
|
||||
for (int mipLevel = 0; mipLevel < mipSizes[arrayLevel].Length; mipLevel++)
|
||||
{
|
||||
//Get the size from the size array
|
||||
int MipSize = (int)mipSizes[arrayLevel][mipLevel];
|
||||
|
||||
//Align the size
|
||||
if (mipLevel == 0)
|
||||
if (MipSize % Alignment != 0) MipSize = MipSize + (Alignment - (MipSize % Alignment));
|
||||
|
||||
uint width = (uint)Math.Max(1, Width >> mipLevel);
|
||||
uint height = (uint)Math.Max(1, Height >> mipLevel);
|
||||
|
||||
@ -519,14 +503,14 @@ namespace FirstPlugin
|
||||
if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight)
|
||||
blockHeightShift += 1;
|
||||
|
||||
Console.WriteLine($"{blk_dim.ToString("x")} {bpp} {width} {height} {linesPerBlockHeight} {blkWidth} {blkHeight} {size} { blocksCompressed[arrayLevel][mipLevel].Length}");
|
||||
Console.WriteLine($"{blk_dim.ToString("x")} {bpp} {width} {height} {linesPerBlockHeight} {blkWidth} {blkHeight} {size} { ImageData.Length}");
|
||||
|
||||
try
|
||||
{
|
||||
byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, target, bpp, tileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), blocksCompressed[arrayLevel][mipLevel]);
|
||||
byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, target, bpp, tileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), ImageData);
|
||||
//Create a copy and use that to remove uneeded data
|
||||
byte[] result_ = new byte[size];
|
||||
Array.Copy(result, 0, result_, 0, size);
|
||||
Array.Copy(result, mipOffset, result_, 0, size);
|
||||
|
||||
mips.Add(result_);
|
||||
}
|
||||
@ -537,6 +521,8 @@ namespace FirstPlugin
|
||||
BadSwizzle = true;
|
||||
break;
|
||||
}
|
||||
mipOffset += (uint)MipSize;
|
||||
break;
|
||||
}
|
||||
mipmaps.Add(mips);
|
||||
}
|
||||
|
@ -214,7 +214,8 @@ namespace FirstPlugin
|
||||
public uint[] MipOffsets { get; set; }
|
||||
public BlockHeader DataBlockHeader { get; set; }
|
||||
public List<byte[]> mipmaps = new List<byte[]>();
|
||||
public List<byte[]> compressedBlocks = new List<byte[]>();
|
||||
public byte[] ImageData;
|
||||
|
||||
|
||||
public void Read(FileReader reader)
|
||||
{
|
||||
@ -240,24 +241,12 @@ namespace FirstPlugin
|
||||
DataBlockHeader.Read(reader);
|
||||
|
||||
reader.Seek(DataBlockOff + DataBlockHeader.DataOffset, SeekOrigin.Begin);
|
||||
// data = reader.ReadBytes((int)DataBlockHeader.DataSize);
|
||||
long datastart = reader.Position;
|
||||
ImageData = reader.ReadBytes((int)DataSize);
|
||||
|
||||
Console.WriteLine(DataBlockHeader.DataSize);
|
||||
for (int i = 0; i < MipCount; i++)
|
||||
{
|
||||
int size = (int)((int)DataBlockHeader.DataSize - MipOffsets[i]);
|
||||
Console.WriteLine(size);
|
||||
if (ImageData.Length == 0)
|
||||
throw new System.Exception("Empty data size!");
|
||||
|
||||
using (reader.TemporarySeek(datastart + MipOffsets[i], System.IO.SeekOrigin.Begin))
|
||||
{
|
||||
compressedBlocks.Add(reader.ReadBytes(size));
|
||||
}
|
||||
if (compressedBlocks[i].Length == 0)
|
||||
throw new System.Exception("Empty mip size!");
|
||||
|
||||
break; //Only first mip level works?
|
||||
}
|
||||
reader.Seek(DataBlockOff + DataBlockHeader.DataOffset + (long)DataBlockHeader.DataSize, SeekOrigin.Begin);
|
||||
BlockHeader EndBlockHeader = new BlockHeader();
|
||||
EndBlockHeader.Read(reader);
|
||||
@ -353,20 +342,36 @@ namespace FirstPlugin
|
||||
uint bpp = XTXFormats.bpps((uint)Format);
|
||||
|
||||
int blockHeightShift = 0;
|
||||
for (int mipLevel = 0; mipLevel < compressedBlocks.Count; mipLevel++)
|
||||
for (int mipLevel = 0; mipLevel < MipOffsets.Length; mipLevel++)
|
||||
{
|
||||
|
||||
uint width = (uint)Math.Max(1, Width >> mipLevel);
|
||||
uint height = (uint)Math.Max(1, Height >> mipLevel);
|
||||
|
||||
// uint size = width * height * bpp;
|
||||
uint size = TegraX1Swizzle.DIV_ROUND_UP(width, blkWidth) * TegraX1Swizzle.DIV_ROUND_UP(height, blkHeight) * bpp;
|
||||
|
||||
byte[] Output = new byte[size];
|
||||
|
||||
uint mipOffset;
|
||||
if (mipLevel != 0)
|
||||
{
|
||||
mipOffset = (MipOffsets[mipLevel - 1]);
|
||||
if (mipLevel == 1)
|
||||
mipOffset -= (uint)size;
|
||||
|
||||
Array.Copy(ImageData, mipOffset, Output, 0, size);
|
||||
}
|
||||
else
|
||||
Output = ImageData;
|
||||
|
||||
byte[] output = new byte[size];
|
||||
Console.WriteLine(mipLevel + " " + size);
|
||||
|
||||
if (TegraX1Swizzle.pow2_round_up(TegraX1Swizzle.DIV_ROUND_UP(height, blkWidth)) < linesPerBlockHeight)
|
||||
blockHeightShift += 1;
|
||||
|
||||
byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, (int)Target, bpp, (uint)TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), compressedBlocks[mipLevel]);
|
||||
byte[] result = TegraX1Swizzle.deswizzle(width, height, blkWidth, blkHeight, (int)Target, bpp, (uint)TileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), Output);
|
||||
//Create a copy and use that to remove uneeded data
|
||||
byte[] result_ = new byte[size];
|
||||
Array.Copy(result, 0, result_, 0, size);
|
||||
|
@ -295,15 +295,15 @@ namespace FirstPlugin
|
||||
// Bind the texture and create the uniform if the material has the right textures.
|
||||
if (hasTex)
|
||||
{
|
||||
GL.Uniform1(shader.GetUniformLocation(name), BindTexture(mattex));
|
||||
GL.Uniform1(shader.GetUniformLocation(name), BindTexture(mattex, mat.GetResFileU() != null));
|
||||
}
|
||||
}
|
||||
public static int BindTexture(MatTexture tex)
|
||||
public static int BindTexture(MatTexture tex, bool IsWiiU)
|
||||
{
|
||||
GL.ActiveTexture(TextureUnit.Texture0 + tex.hash + 1);
|
||||
GL.BindTexture(TextureTarget.Texture2D, RenderTools.defaultTex.Id);
|
||||
|
||||
if (BFRES.Instance.IsWiiU)
|
||||
if (IsWiiU)
|
||||
{
|
||||
foreach (var ftexContainer in PluginRuntime.ftexContainers)
|
||||
{
|
||||
|
@ -312,7 +312,7 @@ namespace FirstPlugin
|
||||
Console.WriteLine("click");
|
||||
int index = textureRefListView.SelectedIndices[0];
|
||||
Texture_Selector tex = new Texture_Selector();
|
||||
tex.LoadTexture();
|
||||
tex.LoadTexture(material.GetResFileU() != null);
|
||||
if (tex.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
material.textures[index].Name = tex.GetSelectedTexture();
|
||||
|
@ -59,7 +59,7 @@ namespace FirstPlugin
|
||||
bonesCB.SelectedIndex = 0;
|
||||
textBoxVertexSkinCount.Text = shape.VertexSkinCount.ToString();
|
||||
|
||||
if (BFRES.Instance.IsWiiU)
|
||||
if (shape.GetResFileU() != null)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -18,9 +18,12 @@ namespace FirstPlugin
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void LoadTexture()
|
||||
bool IsWIiiU = false;
|
||||
public void LoadTexture(bool isWiiU)
|
||||
{
|
||||
if (BFRES.Instance.IsWiiU)
|
||||
IsWIiiU = isWiiU;
|
||||
|
||||
if (IsWIiiU)
|
||||
{
|
||||
foreach (FTEXContainer ftexcont in PluginRuntime.ftexContainers)
|
||||
{
|
||||
@ -54,7 +57,7 @@ namespace FirstPlugin
|
||||
if (listView1.SelectedItems.Count > 0)
|
||||
{
|
||||
string TexName = listView1.SelectedItems[0].Text;
|
||||
if (BFRES.Instance.IsWiiU)
|
||||
if (IsWIiiU)
|
||||
{
|
||||
foreach (FTEXContainer ftexcont in PluginRuntime.ftexContainers)
|
||||
{
|
||||
|
BIN
Switch_FileFormatsMain/GUI/TextureUI/0x1cda00708.XTEX
Normal file
BIN
Switch_FileFormatsMain/GUI/TextureUI/0x1cda00708.XTEX
Normal file
Binary file not shown.
@ -49,8 +49,8 @@ namespace FirstPlugin
|
||||
}
|
||||
private void LoadImage()
|
||||
{
|
||||
if (Thread != null && Thread.IsAlive)
|
||||
Thread.Abort();
|
||||
// if (Thread != null && Thread.IsAlive)
|
||||
// Thread.Abort();
|
||||
|
||||
Thread = new Thread((ThreadStart)(() =>
|
||||
{
|
||||
|
341
Switch_FileFormatsMain/GUI/TextureUI/GTXEditor.Designer.cs
generated
Normal file
341
Switch_FileFormatsMain/GUI/TextureUI/GTXEditor.Designer.cs
generated
Normal file
@ -0,0 +1,341 @@
|
||||
namespace FirstPlugin
|
||||
{
|
||||
partial class GTXEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BNTXEditor));
|
||||
this.panel1 = new System.Windows.Forms.Panel();
|
||||
this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
|
||||
this.splitter1 = new System.Windows.Forms.Splitter();
|
||||
this.panel2 = new System.Windows.Forms.Panel();
|
||||
this.panel4 = new System.Windows.Forms.Panel();
|
||||
this.pictureBoxCustom1 = new Switch_Toolbox.Library.Forms.PictureBoxCustom();
|
||||
this.panel3 = new System.Windows.Forms.Panel();
|
||||
this.imageBGComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.texSizeMipsLabel = new System.Windows.Forms.Label();
|
||||
this.mipLevelCounterLabel = new System.Windows.Forms.Label();
|
||||
this.BtnMipsRight = new System.Windows.Forms.Button();
|
||||
this.BtmMipsLeft = new System.Windows.Forms.Button();
|
||||
this.button1 = new System.Windows.Forms.Button();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.arrayLevelCounterLabel = new System.Windows.Forms.Label();
|
||||
this.btnRightArray = new System.Windows.Forms.Button();
|
||||
this.btnLeftArray = new System.Windows.Forms.Button();
|
||||
this.btnEdit = new System.Windows.Forms.Button();
|
||||
this.panel1.SuspendLayout();
|
||||
this.panel2.SuspendLayout();
|
||||
this.panel4.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).BeginInit();
|
||||
this.panel3.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// panel1
|
||||
//
|
||||
this.panel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.panel1.Controls.Add(this.propertyGrid1);
|
||||
this.panel1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel1.Name = "panel1";
|
||||
this.panel1.Size = new System.Drawing.Size(593, 296);
|
||||
this.panel1.TabIndex = 1;
|
||||
//
|
||||
// propertyGrid1
|
||||
//
|
||||
this.propertyGrid1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.propertyGrid1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
|
||||
this.propertyGrid1.CategoryForeColor = System.Drawing.Color.WhiteSmoke;
|
||||
this.propertyGrid1.CategorySplitterColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.propertyGrid1.CommandsActiveLinkColor = System.Drawing.Color.Red;
|
||||
this.propertyGrid1.CommandsBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50)))));
|
||||
this.propertyGrid1.CommandsDisabledLinkColor = System.Drawing.Color.FromArgb(((int)(((byte)(50)))), ((int)(((byte)(50)))), ((int)(((byte)(50)))));
|
||||
this.propertyGrid1.CommandsForeColor = System.Drawing.Color.White;
|
||||
this.propertyGrid1.DisabledItemForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(127)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
|
||||
this.propertyGrid1.HelpBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
|
||||
this.propertyGrid1.HelpBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(45)))), ((int)(((byte)(45)))), ((int)(((byte)(45)))));
|
||||
this.propertyGrid1.HelpForeColor = System.Drawing.Color.White;
|
||||
this.propertyGrid1.LineColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.propertyGrid1.Location = new System.Drawing.Point(0, 0);
|
||||
this.propertyGrid1.Name = "propertyGrid1";
|
||||
this.propertyGrid1.SelectedItemWithFocusForeColor = System.Drawing.Color.Silver;
|
||||
this.propertyGrid1.Size = new System.Drawing.Size(593, 299);
|
||||
this.propertyGrid1.TabIndex = 2;
|
||||
this.propertyGrid1.ToolbarVisible = false;
|
||||
this.propertyGrid1.ViewBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(40)))), ((int)(((byte)(40)))));
|
||||
this.propertyGrid1.ViewBorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.propertyGrid1.ViewForeColor = System.Drawing.Color.White;
|
||||
this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged);
|
||||
//
|
||||
// splitter1
|
||||
//
|
||||
this.splitter1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.splitter1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.splitter1.Location = new System.Drawing.Point(0, 296);
|
||||
this.splitter1.Name = "splitter1";
|
||||
this.splitter1.Size = new System.Drawing.Size(593, 3);
|
||||
this.splitter1.TabIndex = 2;
|
||||
this.splitter1.TabStop = false;
|
||||
//
|
||||
// panel2
|
||||
//
|
||||
this.panel2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.panel2.Controls.Add(this.panel4);
|
||||
this.panel2.Controls.Add(this.panel3);
|
||||
this.panel2.Controls.Add(this.button1);
|
||||
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel2.Location = new System.Drawing.Point(0, 299);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(593, 297);
|
||||
this.panel2.TabIndex = 3;
|
||||
//
|
||||
// panel4
|
||||
//
|
||||
this.panel4.Controls.Add(this.pictureBoxCustom1);
|
||||
this.panel4.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel4.Location = new System.Drawing.Point(0, 80);
|
||||
this.panel4.Name = "panel4";
|
||||
this.panel4.Size = new System.Drawing.Size(593, 217);
|
||||
this.panel4.TabIndex = 4;
|
||||
//
|
||||
// pictureBoxCustom1
|
||||
//
|
||||
this.pictureBoxCustom1.BackColor = System.Drawing.Color.Transparent;
|
||||
this.pictureBoxCustom1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pictureBoxCustom1.BackgroundImage")));
|
||||
this.pictureBoxCustom1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.pictureBoxCustom1.Location = new System.Drawing.Point(0, 0);
|
||||
this.pictureBoxCustom1.Name = "pictureBoxCustom1";
|
||||
this.pictureBoxCustom1.Size = new System.Drawing.Size(593, 217);
|
||||
this.pictureBoxCustom1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
this.pictureBoxCustom1.TabIndex = 0;
|
||||
this.pictureBoxCustom1.TabStop = false;
|
||||
//
|
||||
// panel3
|
||||
//
|
||||
this.panel3.Controls.Add(this.btnEdit);
|
||||
this.panel3.Controls.Add(this.label5);
|
||||
this.panel3.Controls.Add(this.arrayLevelCounterLabel);
|
||||
this.panel3.Controls.Add(this.btnRightArray);
|
||||
this.panel3.Controls.Add(this.btnLeftArray);
|
||||
this.panel3.Controls.Add(this.imageBGComboBox);
|
||||
this.panel3.Controls.Add(this.label1);
|
||||
this.panel3.Controls.Add(this.texSizeMipsLabel);
|
||||
this.panel3.Controls.Add(this.mipLevelCounterLabel);
|
||||
this.panel3.Controls.Add(this.BtnMipsRight);
|
||||
this.panel3.Controls.Add(this.BtmMipsLeft);
|
||||
this.panel3.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.panel3.Location = new System.Drawing.Point(0, 25);
|
||||
this.panel3.Name = "panel3";
|
||||
this.panel3.Size = new System.Drawing.Size(593, 55);
|
||||
this.panel3.TabIndex = 2;
|
||||
//
|
||||
// imageBGComboBox
|
||||
//
|
||||
this.imageBGComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.imageBGComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.imageBGComboBox.FormattingEnabled = true;
|
||||
this.imageBGComboBox.Location = new System.Drawing.Point(215, 7);
|
||||
this.imageBGComboBox.Name = "imageBGComboBox";
|
||||
this.imageBGComboBox.Size = new System.Drawing.Size(121, 21);
|
||||
this.imageBGComboBox.TabIndex = 5;
|
||||
this.imageBGComboBox.SelectedIndexChanged += new System.EventHandler(this.imageBGComboBox_SelectedIndexChanged);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.ForeColor = System.Drawing.Color.White;
|
||||
this.label1.Location = new System.Drawing.Point(342, 7);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(67, 13);
|
||||
this.label1.TabIndex = 4;
|
||||
this.label1.Text = "Mip Counter:";
|
||||
//
|
||||
// texSizeMipsLabel
|
||||
//
|
||||
this.texSizeMipsLabel.AutoSize = true;
|
||||
this.texSizeMipsLabel.ForeColor = System.Drawing.Color.White;
|
||||
this.texSizeMipsLabel.Location = new System.Drawing.Point(127, 34);
|
||||
this.texSizeMipsLabel.Name = "texSizeMipsLabel";
|
||||
this.texSizeMipsLabel.Size = new System.Drawing.Size(42, 13);
|
||||
this.texSizeMipsLabel.TabIndex = 3;
|
||||
this.texSizeMipsLabel.Text = "00 / 00";
|
||||
//
|
||||
// mipLevelCounterLabel
|
||||
//
|
||||
this.mipLevelCounterLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.mipLevelCounterLabel.AutoSize = true;
|
||||
this.mipLevelCounterLabel.ForeColor = System.Drawing.Color.White;
|
||||
this.mipLevelCounterLabel.Location = new System.Drawing.Point(415, 7);
|
||||
this.mipLevelCounterLabel.Name = "mipLevelCounterLabel";
|
||||
this.mipLevelCounterLabel.Size = new System.Drawing.Size(42, 13);
|
||||
this.mipLevelCounterLabel.TabIndex = 2;
|
||||
this.mipLevelCounterLabel.Text = "00 / 00";
|
||||
//
|
||||
// BtnMipsRight
|
||||
//
|
||||
this.BtnMipsRight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.BtnMipsRight.Location = new System.Drawing.Point(533, 3);
|
||||
this.BtnMipsRight.Name = "BtnMipsRight";
|
||||
this.BtnMipsRight.Size = new System.Drawing.Size(57, 21);
|
||||
this.BtnMipsRight.TabIndex = 1;
|
||||
this.BtnMipsRight.Text = ">";
|
||||
this.BtnMipsRight.UseVisualStyleBackColor = true;
|
||||
this.BtnMipsRight.Click += new System.EventHandler(this.BtnMipsRight_Click);
|
||||
//
|
||||
// BtmMipsLeft
|
||||
//
|
||||
this.BtmMipsLeft.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.BtmMipsLeft.Enabled = false;
|
||||
this.BtmMipsLeft.Location = new System.Drawing.Point(470, 3);
|
||||
this.BtmMipsLeft.Name = "BtmMipsLeft";
|
||||
this.BtmMipsLeft.Size = new System.Drawing.Size(57, 21);
|
||||
this.BtmMipsLeft.TabIndex = 0;
|
||||
this.BtmMipsLeft.Text = "<";
|
||||
this.BtmMipsLeft.UseVisualStyleBackColor = true;
|
||||
this.BtmMipsLeft.Click += new System.EventHandler(this.BtmMipsLeft_Click);
|
||||
//
|
||||
// button1
|
||||
//
|
||||
this.button1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(64)))), ((int)(((byte)(64)))), ((int)(((byte)(64)))));
|
||||
this.button1.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
this.button1.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(90)))), ((int)(((byte)(90)))));
|
||||
this.button1.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Gray;
|
||||
this.button1.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(90)))), ((int)(((byte)(90)))), ((int)(((byte)(90)))));
|
||||
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.button1.ForeColor = System.Drawing.Color.White;
|
||||
this.button1.Location = new System.Drawing.Point(0, 0);
|
||||
this.button1.Name = "button1";
|
||||
this.button1.Size = new System.Drawing.Size(593, 25);
|
||||
this.button1.TabIndex = 1;
|
||||
this.button1.Text = "Hide";
|
||||
this.button1.UseVisualStyleBackColor = false;
|
||||
this.button1.Click += new System.EventHandler(this.button1_Click);
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.ForeColor = System.Drawing.Color.White;
|
||||
this.label5.Location = new System.Drawing.Point(342, 30);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(74, 13);
|
||||
this.label5.TabIndex = 9;
|
||||
this.label5.Text = "Array Counter:";
|
||||
//
|
||||
// arrayLevelCounterLabel
|
||||
//
|
||||
this.arrayLevelCounterLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.arrayLevelCounterLabel.AutoSize = true;
|
||||
this.arrayLevelCounterLabel.ForeColor = System.Drawing.Color.White;
|
||||
this.arrayLevelCounterLabel.Location = new System.Drawing.Point(415, 30);
|
||||
this.arrayLevelCounterLabel.Name = "arrayLevelCounterLabel";
|
||||
this.arrayLevelCounterLabel.Size = new System.Drawing.Size(42, 13);
|
||||
this.arrayLevelCounterLabel.TabIndex = 8;
|
||||
this.arrayLevelCounterLabel.Text = "00 / 00";
|
||||
//
|
||||
// btnRightArray
|
||||
//
|
||||
this.btnRightArray.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnRightArray.Location = new System.Drawing.Point(533, 26);
|
||||
this.btnRightArray.Name = "btnRightArray";
|
||||
this.btnRightArray.Size = new System.Drawing.Size(57, 21);
|
||||
this.btnRightArray.TabIndex = 7;
|
||||
this.btnRightArray.Text = ">";
|
||||
this.btnRightArray.UseVisualStyleBackColor = true;
|
||||
this.btnRightArray.Click += new System.EventHandler(this.btnRightArray_Click);
|
||||
//
|
||||
// btnLeftArray
|
||||
//
|
||||
this.btnLeftArray.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnLeftArray.Enabled = false;
|
||||
this.btnLeftArray.Location = new System.Drawing.Point(470, 26);
|
||||
this.btnLeftArray.Name = "btnLeftArray";
|
||||
this.btnLeftArray.Size = new System.Drawing.Size(57, 21);
|
||||
this.btnLeftArray.TabIndex = 6;
|
||||
this.btnLeftArray.Text = "<";
|
||||
this.btnLeftArray.UseVisualStyleBackColor = true;
|
||||
this.btnLeftArray.Click += new System.EventHandler(this.btnLeftArray_Click);
|
||||
//
|
||||
// btnEdit
|
||||
//
|
||||
this.btnEdit.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.btnEdit.ForeColor = System.Drawing.Color.White;
|
||||
this.btnEdit.Location = new System.Drawing.Point(6, 5);
|
||||
this.btnEdit.Name = "btnEdit";
|
||||
this.btnEdit.Size = new System.Drawing.Size(63, 23);
|
||||
this.btnEdit.TabIndex = 12;
|
||||
this.btnEdit.Text = "Edit";
|
||||
this.btnEdit.UseVisualStyleBackColor = true;
|
||||
this.btnEdit.Click += new System.EventHandler(this.btnEdit_Click);
|
||||
// BNTXEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.panel2);
|
||||
this.Controls.Add(this.splitter1);
|
||||
this.Controls.Add(this.panel1);
|
||||
this.Name = "BNTXEditor";
|
||||
this.Size = new System.Drawing.Size(593, 596);
|
||||
this.panel1.ResumeLayout(false);
|
||||
this.panel2.ResumeLayout(false);
|
||||
this.panel4.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBoxCustom1)).EndInit();
|
||||
this.panel3.ResumeLayout(false);
|
||||
this.panel3.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel panel1;
|
||||
private System.Windows.Forms.Button button1;
|
||||
private System.Windows.Forms.Splitter splitter1;
|
||||
private System.Windows.Forms.Panel panel2;
|
||||
private Switch_Toolbox.Library.Forms.PictureBoxCustom pictureBoxCustom1;
|
||||
private System.Windows.Forms.PropertyGrid propertyGrid1;
|
||||
private System.Windows.Forms.Panel panel4;
|
||||
private System.Windows.Forms.Panel panel3;
|
||||
private System.Windows.Forms.Label mipLevelCounterLabel;
|
||||
private System.Windows.Forms.Button BtnMipsRight;
|
||||
private System.Windows.Forms.Button BtmMipsLeft;
|
||||
private System.Windows.Forms.Label texSizeMipsLabel;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.ComboBox imageBGComboBox;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Label arrayLevelCounterLabel;
|
||||
private System.Windows.Forms.Button btnRightArray;
|
||||
private System.Windows.Forms.Button btnLeftArray;
|
||||
private System.Windows.Forms.Button btnEdit;
|
||||
private System.Windows.Forms.ToolStripMenuItem replaceSurfaceLevelToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem exportSurfaceLevelToolStripMenuItem;
|
||||
}
|
||||
}
|
175
Switch_FileFormatsMain/GUI/TextureUI/GTXEditor.cs
Normal file
175
Switch_FileFormatsMain/GUI/TextureUI/GTXEditor.cs
Normal file
@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using Syroot.NintenTools.NSW.Bntx;
|
||||
using Syroot.NintenTools.NSW.Bntx.GFX;
|
||||
using Switch_Toolbox.Library;
|
||||
|
||||
namespace FirstPlugin
|
||||
{
|
||||
public partial class GTXEditor : UserControl
|
||||
{
|
||||
private Thread Thread;
|
||||
|
||||
public GTXEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
foreach (var type in Enum.GetValues(typeof(Runtime.PictureBoxBG)).Cast<Runtime.PictureBoxBG>())
|
||||
imageBGComboBox.Items.Add(type);
|
||||
|
||||
imageBGComboBox.SelectedItem = Runtime.pictureBoxStyle;
|
||||
UpdateBackgroundImage();
|
||||
}
|
||||
public void LoadPicture(Bitmap image)
|
||||
{
|
||||
// pictureBoxCustom1.Image = image;
|
||||
}
|
||||
|
||||
GTXFile.TextureData textureData;
|
||||
int CurMipDisplayLevel = 0;
|
||||
int CurArrayDisplayLevel = 0;
|
||||
public void LoadProperty(GTXFile.TextureData tex)
|
||||
{
|
||||
CurMipDisplayLevel = 0;
|
||||
CurArrayDisplayLevel = 0;
|
||||
|
||||
textureData = tex;
|
||||
propertyGrid1.PropertySort = PropertySort.Categorized;
|
||||
UpdateMipDisplay();
|
||||
}
|
||||
private void UpdateMipDisplay()
|
||||
{
|
||||
mipLevelCounterLabel.Text = $"{CurMipDisplayLevel} / {textureData.renderedTex.mipmaps[CurArrayDisplayLevel].Count - 1}";
|
||||
arrayLevelCounterLabel.Text = $"{CurArrayDisplayLevel} / {textureData.renderedTex.mipmaps.Count - 1}";
|
||||
|
||||
|
||||
if (Thread != null && Thread.IsAlive)
|
||||
Thread.Abort();
|
||||
|
||||
Thread = new Thread((ThreadStart)(() =>
|
||||
{
|
||||
pictureBoxCustom1.Image = Imaging.GetLoadingImage();
|
||||
pictureBoxCustom1.Image = textureData.DisplayTexture(CurMipDisplayLevel, CurArrayDisplayLevel);
|
||||
|
||||
// texSizeMipsLabel.Text = $"Width = {pictureBoxCustom1.Image.Width} Height = {pictureBoxCustom1.Image.Height}";
|
||||
}));
|
||||
Thread.Start();
|
||||
|
||||
|
||||
if (CurMipDisplayLevel != textureData.renderedTex.mipmaps[CurArrayDisplayLevel].Count - 1)
|
||||
BtnMipsRight.Enabled = true;
|
||||
else
|
||||
BtnMipsRight.Enabled = false;
|
||||
|
||||
if (CurMipDisplayLevel != 0)
|
||||
BtmMipsLeft.Enabled = true;
|
||||
else
|
||||
BtmMipsLeft.Enabled = false;
|
||||
|
||||
if (CurArrayDisplayLevel != textureData.renderedTex.mipmaps.Count - 1)
|
||||
btnRightArray.Enabled = true;
|
||||
else
|
||||
btnRightArray.Enabled = false;
|
||||
|
||||
if (CurArrayDisplayLevel != 0)
|
||||
btnLeftArray.Enabled = true;
|
||||
else
|
||||
btnLeftArray.Enabled = false;
|
||||
}
|
||||
|
||||
bool IsHidden = false;
|
||||
private void button1_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (IsHidden)
|
||||
{
|
||||
panel1.Visible = true;
|
||||
IsHidden = false;
|
||||
button1.Text = "Hide";
|
||||
}
|
||||
else
|
||||
{
|
||||
panel1.Visible = false;
|
||||
IsHidden = true;
|
||||
button1.Text = "Show";
|
||||
}
|
||||
}
|
||||
|
||||
private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
|
||||
{
|
||||
if (propertyGrid1.SelectedObject != null)
|
||||
{
|
||||
Texture tex = (Texture)propertyGrid1.SelectedObject;
|
||||
textureData.Text = tex.Name;
|
||||
}
|
||||
}
|
||||
|
||||
private void BtmMipsLeft_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (CurMipDisplayLevel != 0)
|
||||
CurMipDisplayLevel -= 1;
|
||||
|
||||
UpdateMipDisplay();
|
||||
}
|
||||
|
||||
private void BtnMipsRight_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (CurMipDisplayLevel != textureData.renderedTex.mipmaps[CurArrayDisplayLevel].Count - 1)
|
||||
CurMipDisplayLevel += 1;
|
||||
|
||||
UpdateMipDisplay();
|
||||
}
|
||||
|
||||
private void btnLeftArray_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (CurArrayDisplayLevel != 0)
|
||||
CurArrayDisplayLevel -= 1;
|
||||
|
||||
UpdateMipDisplay();
|
||||
}
|
||||
|
||||
private void btnRightArray_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (CurArrayDisplayLevel != textureData.renderedTex.mipmaps.Count - 1)
|
||||
CurArrayDisplayLevel += 1;
|
||||
|
||||
UpdateMipDisplay();
|
||||
}
|
||||
|
||||
|
||||
private void UpdateBackgroundImage()
|
||||
{
|
||||
switch (Runtime.pictureBoxStyle)
|
||||
{
|
||||
case Runtime.PictureBoxBG.Black:
|
||||
pictureBoxCustom1.BackColor = Color.Black;
|
||||
pictureBoxCustom1.BackgroundImage = null;
|
||||
break;
|
||||
case Runtime.PictureBoxBG.Checkerboard:
|
||||
pictureBoxCustom1.BackColor = Color.Transparent;
|
||||
pictureBoxCustom1.BackgroundImage = pictureBoxCustom1.GetCheckerBackground();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void imageBGComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
Runtime.pictureBoxStyle = (Runtime.PictureBoxBG)imageBGComboBox.SelectedItem;
|
||||
UpdateBackgroundImage();
|
||||
}
|
||||
|
||||
private void btnEdit_Click(object sender, EventArgs e)
|
||||
{
|
||||
Button btnSender = (Button)sender;
|
||||
Point ptLowerLeft = new Point(0, btnSender.Height);
|
||||
ptLowerLeft = btnSender.PointToScreen(ptLowerLeft);
|
||||
}
|
||||
}
|
||||
}
|
331
Switch_FileFormatsMain/GUI/TextureUI/GTXEditor.resx
Normal file
331
Switch_FileFormatsMain/GUI/TextureUI/GTXEditor.resx
Normal file
@ -0,0 +1,331 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="pictureBoxCustom1.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAAlgAAAJYCAMAAACJuGjuAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
|
||||
JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEXMzMzNzc3Ozs7Pz8/Q0NDR0dHS
|
||||
0tLT09PU1NTV1dXW1tbX19fY2NjZ2dna2trb29vc3Nzd3d3e3t7f39/g4ODh4eHi4uLj4+Pk5OTl5eXm
|
||||
5ubn5+fo6Ojp6enq6urr6+vs7Ozt7e3u7u7v7+/w8PDx8fHy8vLz8/P09PT19fX29vb39/f4+Pj5+fn6
|
||||
+vr7+/v8/Pz9/f3+/v7///8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
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
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="contextMenuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
@ -16,7 +16,6 @@ namespace FirstPlugin
|
||||
public uint TexWidth;
|
||||
public uint TexHeight;
|
||||
public uint MipCount;
|
||||
public uint bpp;
|
||||
public uint Depth = 1;
|
||||
public uint arrayLength = 1;
|
||||
public List<byte[]> DataBlockOutput = new List<byte[]>();
|
||||
@ -194,8 +193,9 @@ namespace FirstPlugin
|
||||
uint pitch = surfOut.pitch;
|
||||
uint mipSize = 0;
|
||||
uint dataSize = (uint)imageData.Length;
|
||||
uint bpp = GTX.surfaceGetBitsPerPixel((uint)Format) >> 3;
|
||||
|
||||
if (imageData.Length <= 0)
|
||||
if (dataSize <= 0)
|
||||
throw new Exception($"Image is empty!!");
|
||||
|
||||
if (surfOut.depth != 1)
|
||||
@ -228,30 +228,36 @@ namespace FirstPlugin
|
||||
List<uint> mipOffsets = new List<uint>();
|
||||
List<byte[]> Swizzled = new List<byte[]>();
|
||||
|
||||
byte[] data;
|
||||
for (int mipLevel = 0; mipLevel < MipCount; mipLevel++)
|
||||
{
|
||||
var result = TextureHelper.GetCurrentMipSize(TexWidth, TexHeight, blkWidth, blkHeight, bpp, mipLevel);
|
||||
|
||||
uint offset = result.Item1;
|
||||
uint size = result.Item2;
|
||||
|
||||
byte[] data_ = Utils.SubArray(imageData, offset, size);
|
||||
Console.WriteLine("Swizzle Size " + size);
|
||||
Console.WriteLine("Swizzle offset " + offset);
|
||||
Console.WriteLine("bpp " + bpp);
|
||||
Console.WriteLine("TexWidth " + TexWidth);
|
||||
Console.WriteLine("TexHeight " + TexHeight);
|
||||
Console.WriteLine("blkWidth " + blkWidth);
|
||||
Console.WriteLine("blkHeight " + blkHeight);
|
||||
Console.WriteLine("mipLevel " + mipLevel);
|
||||
|
||||
byte[] data_ = new byte[size];
|
||||
Array.Copy(imageData, offset, data_,0, size);
|
||||
|
||||
uint width_ = Math.Max(1, TexWidth >> mipLevel);
|
||||
uint height_ = Math.Max(1, TexHeight >> mipLevel);
|
||||
|
||||
|
||||
if (mipLevel != 0)
|
||||
{
|
||||
surfOut = GTX.getSurfaceInfo(Format, TexWidth, TexHeight, 1, 1, tileMode, 0, mipLevel);
|
||||
|
||||
if (mipLevel == 1)
|
||||
{
|
||||
if (mipLevel == 1)
|
||||
mipOffsets.Add(imageSize);
|
||||
else
|
||||
mipOffsets.Add(mipSize);
|
||||
}
|
||||
mipOffsets.Add(imageSize);
|
||||
else
|
||||
mipOffsets.Add(mipSize);
|
||||
}
|
||||
|
||||
data_ = Utils.CombineByteArray(data_, new byte[surfOut.surfSize - size]);
|
||||
@ -260,10 +266,11 @@ namespace FirstPlugin
|
||||
if (mipLevel != 0)
|
||||
mipSize += (uint)(surfOut.surfSize + dataAlignBytes.Length);
|
||||
|
||||
Swizzled.Add(Utils.CombineByteArray(dataAlignBytes, GTX.swizzle(width_, height_, surfOut.height, (uint)Format, surfOut.tileMode, s,
|
||||
surfOut.pitch, surfOut.bpp, data_)));
|
||||
byte[] SwizzledData = GTX.swizzle(width_, height_, surfOut.height, (uint)Format, surfOut.tileMode, s,
|
||||
surfOut.pitch, surfOut.bpp, data_);
|
||||
|
||||
Swizzled.Add(dataAlignBytes.Concat(SwizzledData).ToArray());
|
||||
}
|
||||
File.WriteAllBytes("NewSwizzle.bin",Swizzled[0]);
|
||||
|
||||
compSel[0] = GX2CompSel.ChannelR;
|
||||
compSel[1] = GX2CompSel.ChannelG;
|
||||
@ -275,12 +282,13 @@ namespace FirstPlugin
|
||||
surf.width = TexWidth;
|
||||
surf.height = TexHeight;
|
||||
surf.depth = 1;
|
||||
surf.use = 1;
|
||||
surf.dim = (uint)SurfaceDim;
|
||||
surf.bpp = GTX.surfaceGetBitsPerPixel((uint)Format >> 3);
|
||||
surf.tileMode = tileMode;
|
||||
surf.swizzle = s;
|
||||
surf.resourceFlags = 0;
|
||||
surf.pitch = surfOut.pitch;
|
||||
surf.pitch = pitch;
|
||||
surf.bpp = bpp;
|
||||
surf.format = (uint)Format;
|
||||
surf.numMips = MipCount;
|
||||
surf.aa = (uint)AAMode;
|
||||
@ -295,10 +303,12 @@ namespace FirstPlugin
|
||||
for (int mipLevel = 1; mipLevel < Swizzled.Count; mipLevel++)
|
||||
{
|
||||
mips.Add(Swizzled[mipLevel]);
|
||||
Console.WriteLine(Swizzled[mipLevel].Length);
|
||||
}
|
||||
surf.mipData = Utils.CombineByteArray(mips.ToArray());
|
||||
mips.Clear();
|
||||
|
||||
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("// ----- GX2Surface Info ----- ");
|
||||
Console.WriteLine(" dim = 1");
|
||||
@ -326,7 +336,6 @@ namespace FirstPlugin
|
||||
Console.WriteLine(" bytes per pixel = " + surf.bpp);
|
||||
Console.WriteLine(" realSize = " + imageData.Length);
|
||||
|
||||
|
||||
return surf;
|
||||
}
|
||||
private static Tuple<uint, uint> GetCurrentMipSize(uint width, uint height, uint bpp, int CurLevel, bool IsCompressed)
|
||||
|
@ -54,47 +54,50 @@ namespace FirstPlugin
|
||||
public bool IsSRGB = true;
|
||||
public bool GenerateMipmaps = false; //If bitmap and count more that 1 then geenrate
|
||||
|
||||
private SurfaceFormat LoadDDSFormat(string fourCC, DDS dds = null, bool IsSRGB = false)
|
||||
private SurfaceFormat LoadDDSFormat(uint fourCC, DDS dds = null, bool IsSRGB = false)
|
||||
{
|
||||
bool IsDX10 = false;
|
||||
|
||||
switch (fourCC)
|
||||
{
|
||||
case "DXT1":
|
||||
case DDS.FOURCC_DXT1:
|
||||
if (IsSRGB)
|
||||
return SurfaceFormat.BC1_SRGB;
|
||||
else
|
||||
return SurfaceFormat.BC1_UNORM;
|
||||
case "DXT3":
|
||||
case DDS.FOURCC_DXT3:
|
||||
if (IsSRGB)
|
||||
return SurfaceFormat.BC2_SRGB;
|
||||
else
|
||||
return SurfaceFormat.BC2_UNORM;
|
||||
case "DXT5":
|
||||
case DDS.FOURCC_DXT5:
|
||||
if (IsSRGB)
|
||||
return SurfaceFormat.BC3_SRGB;
|
||||
else
|
||||
return SurfaceFormat.BC3_UNORM;
|
||||
case "BC4U":
|
||||
case DDS.FOURCC_BC4U:
|
||||
return SurfaceFormat.BC4_UNORM;
|
||||
case "BC4S":
|
||||
case DDS.FOURCC_BC4S:
|
||||
return SurfaceFormat.BC4_SNORM;
|
||||
case "ATI1":
|
||||
case DDS.FOURCC_ATI1:
|
||||
return SurfaceFormat.BC4_UNORM;
|
||||
case "ATI2":
|
||||
case DDS.FOURCC_ATI2:
|
||||
return SurfaceFormat.BC5_UNORM;
|
||||
case "BC5U":
|
||||
case DDS.FOURCC_BC5U:
|
||||
return SurfaceFormat.BC5_UNORM;
|
||||
case "BC5S":
|
||||
case DDS.FOURCC_BC5S:
|
||||
return SurfaceFormat.BC5_SNORM;
|
||||
case "DX10":
|
||||
case DDS.FOURCC_DX10:
|
||||
IsDX10 = true;
|
||||
break;
|
||||
default:
|
||||
return SurfaceFormat.R8_G8_B8_A8_SRGB;
|
||||
}
|
||||
Console.WriteLine(IsDX10);
|
||||
if (IsDX10)
|
||||
{
|
||||
Console.WriteLine(dds.DX10header.DXGI_Format);
|
||||
|
||||
switch (dds.DX10header.DXGI_Format)
|
||||
{
|
||||
case DDS.DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM:
|
||||
@ -145,7 +148,7 @@ namespace FirstPlugin
|
||||
DataBlockOutput.Add(dds.bdata);
|
||||
|
||||
|
||||
Format = LoadDDSFormat(dds.header.ddspf.fourCC.ToString(), dds, IsSRGB);
|
||||
Format = LoadDDSFormat(dds.header.ddspf.fourCC, dds, IsSRGB);
|
||||
|
||||
Texture tex = FromBitMap(DataBlockOutput[0], this);
|
||||
|
||||
|
@ -42,12 +42,15 @@
|
||||
<ItemGroup>
|
||||
<Reference Include="BarsLibrary">
|
||||
<HintPath>..\Switch_Toolbox\Lib\BarsLibrary.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="BezelEngineArchive_Lib">
|
||||
<HintPath>..\Switch_Toolbox\Lib\BezelEngineArchive_Lib.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="ByamlExt">
|
||||
<HintPath>..\Switch_Toolbox\Lib\ByamlExt.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Costura, Version=3.1.4.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
|
||||
<HintPath>..\Switch_Toolbox\Lib\Costura.dll</HintPath>
|
||||
@ -55,10 +58,12 @@
|
||||
</Reference>
|
||||
<Reference Include="EditorCoreCommon">
|
||||
<HintPath>..\Switch_Toolbox\Lib\EditorCoreCommon.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="KCLExt, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Switch_Toolbox\Lib\KCLExt.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="NAudio">
|
||||
@ -80,6 +85,7 @@
|
||||
</Reference>
|
||||
<Reference Include="SARCExt">
|
||||
<HintPath>..\Switch_Toolbox\Lib\SARCExt.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="SFGraphics">
|
||||
<HintPath>..\Switch_Toolbox\Lib\SFGraphics.dll</HintPath>
|
||||
@ -91,18 +97,23 @@
|
||||
</Reference>
|
||||
<Reference Include="Syroot.BinaryData">
|
||||
<HintPath>..\Switch_Toolbox\Lib\Syroot.BinaryData.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Syroot.Maths">
|
||||
<HintPath>..\Switch_Toolbox\Lib\Syroot.Maths.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Syroot.NintenTools.Bfres">
|
||||
<HintPath>..\Switch_Toolbox\Lib\Syroot.NintenTools.Bfres.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Syroot.NintenTools.NSW.Bfres">
|
||||
<HintPath>..\Switch_Toolbox\Lib\Syroot.NintenTools.NSW.Bfres.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="Syroot.NintenTools.NSW.Bntx">
|
||||
<HintPath>..\Switch_Toolbox\Lib\Syroot.NintenTools.NSW.Bntx.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
@ -132,9 +143,6 @@
|
||||
<HintPath>..\packages\DockPanelSuite.3.0.4\lib\net40\WeifenLuo.WinFormsUI.Docking.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="ZstdNet">
|
||||
<HintPath>..\Switch_Toolbox\Lib\ZstdNet.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Config.cs" />
|
||||
@ -171,6 +179,7 @@
|
||||
<Compile Include="FileFormats\Texture\BNTX.cs" />
|
||||
<Compile Include="FileFormats\Texture\FTEX.cs" />
|
||||
<Compile Include="FileFormats\Texture\GTX.cs" />
|
||||
<Compile Include="FileFormats\Texture\GTXFile.cs" />
|
||||
<Compile Include="FileFormats\Texture\TegraX1Swizzle.cs" />
|
||||
<Compile Include="FileFormats\Texture\NUTEXB.cs" />
|
||||
<Compile Include="FileFormats\Texture\TexConv.cs" />
|
||||
@ -267,6 +276,12 @@
|
||||
<DependentUpon>BfresShapeEditor.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="GUI\FormLoader.cs" />
|
||||
<Compile Include="GUI\TextureUI\GTXEditor.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="GUI\TextureUI\GTXEditor.Designer.cs">
|
||||
<DependentUpon>GTXEditor.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="GUI\TextureUI\GTXImporterSettings.cs" />
|
||||
<Compile Include="GUI\TextureUI\GTXTextureImporter.cs">
|
||||
<SubType>Form</SubType>
|
||||
@ -431,6 +446,9 @@
|
||||
<EmbeddedResource Include="GUI\BFRES\BfresShapeEditor.resx">
|
||||
<DependentUpon>BfresShapeEditor.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="GUI\TextureUI\GTXEditor.resx">
|
||||
<DependentUpon>GTXEditor.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="GUI\TextureUI\GTXTextureImporter.resx">
|
||||
<DependentUpon>GTXTextureImporter.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
@ -500,6 +518,7 @@
|
||||
<ProjectReference Include="..\Switch_Toolbox_Library\Switch_Toolbox_Library.csproj">
|
||||
<Project>{96820047-2a39-4e5a-bfa4-e84fff5c66cf}</Project>
|
||||
<Name>Switch_Toolbox_Library</Name>
|
||||
<Private>False</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@ -531,6 +550,7 @@
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>aximp</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<Private>False</Private>
|
||||
</COMReference>
|
||||
<COMReference Include="WMPLib">
|
||||
<Guid>{6BF52A50-394A-11D3-B153-00C04F79FAA6}</Guid>
|
||||
@ -539,7 +559,7 @@
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <vcclr.h>
|
||||
#include "DirectXTex.h"
|
||||
#define _WIN32_WINNT 0x0600
|
||||
|
||||
using namespace System;
|
||||
using namespace System::IO;
|
||||
|
Binary file not shown.
Binary file not shown.
@ -11,10 +11,10 @@ using Switch_Toolbox.Library.Forms;
|
||||
using WeifenLuo.WinFormsUI.Docking;
|
||||
using Switch_Toolbox.Library;
|
||||
using Smash_Forge.Rendering;
|
||||
using Switch_Toolbox_Library;
|
||||
using Switch_Toolbox.Library.IO;
|
||||
using System.Net;
|
||||
|
||||
|
||||
namespace Switch_Toolbox
|
||||
{
|
||||
public partial class MainForm : Form
|
||||
@ -35,7 +35,6 @@ namespace Switch_Toolbox
|
||||
public MainForm()
|
||||
{
|
||||
InitializeComponent();
|
||||
new DiscordPresence().Initialize();
|
||||
|
||||
ShaderTools.executableDir = executableDir;
|
||||
|
||||
@ -237,10 +236,15 @@ namespace Switch_Toolbox
|
||||
SaveRecentFile(FileName);
|
||||
|
||||
FileReader f = new FileReader(data);
|
||||
|
||||
uint Identifier = f.ReadUInt32();
|
||||
f.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
string Magic = f.ReadMagic(0, 4);
|
||||
string Magic2 = f.ReadMagic(0, 2);
|
||||
string Magic3 = f.ReadMagic((int)f.BaseStream.Length - 7, 3);
|
||||
|
||||
|
||||
//Determine if the file is compressed or not
|
||||
if (Magic == "Yaz0")
|
||||
{
|
||||
@ -248,6 +252,12 @@ namespace Switch_Toolbox
|
||||
OpenFile(FileName, data, true, CompressionType.Yaz0);
|
||||
return;
|
||||
}
|
||||
if (Identifier == 0x28B52FFD || Identifier == 0xFD2FB528)
|
||||
{
|
||||
data = STLibraryCompression.ZSTD.Decompress(f.getSection(0, data.Length));
|
||||
OpenFile(FileName, data, true, CompressionType.Zstb);
|
||||
return;
|
||||
}
|
||||
if (Magic == "ZLIB")
|
||||
{
|
||||
data = FileReader.InflateZLIB(f.getSection(64, data.Length - 64));
|
||||
|
@ -53,9 +53,6 @@
|
||||
<HintPath>..\packages\CsvHelper.8.0.0-beta01\lib\net45\CsvHelper.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
</Reference>
|
||||
<Reference Include="DiscordRPC">
|
||||
<HintPath>Lib\DiscordRPC.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EditorCoreCommon">
|
||||
<HintPath>..\..\..\..\Documents\Visual Studio 2017\Projects\WindowsFormsApp2\WindowsFormsApp2\Lib\EditorCoreCommon.dll</HintPath>
|
||||
<Private>False</Private>
|
||||
@ -405,4 +402,4 @@
|
||||
</Target>
|
||||
<Import Project="..\packages\Costura.Fody.3.1.4\build\Costura.Fody.targets" Condition="Exists('..\packages\Costura.Fody.3.1.4\build\Costura.Fody.targets')" />
|
||||
<Import Project="..\packages\AssimpNet.4.1.0\build\AssimpNet.targets" Condition="Exists('..\packages\AssimpNet.4.1.0\build\AssimpNet.targets')" />
|
||||
</Project>
|
||||
</Project>
|
@ -77,7 +77,7 @@ PostProcessSteps.CalculateTangentSpace | PostProcessSteps.GenerateNormals);
|
||||
objects.Add(CreateGenericObject(scene.Meshes[index], index, worldTK));
|
||||
|
||||
foreach (Node child in parent.Children)
|
||||
BuildNode(child, ref rootTransform);
|
||||
BuildNode(child, ref world);
|
||||
}
|
||||
public void LoadMeshes()
|
||||
{
|
||||
|
@ -16,6 +16,26 @@ namespace Switch_Toolbox.Library
|
||||
input.A2, input.B2, input.C2, input.D2,
|
||||
input.A3, input.B3, input.C3, input.D3,
|
||||
input.A4, input.B4, input.C4, input.D4);
|
||||
|
||||
/* return new OpenTK.Matrix4()
|
||||
{
|
||||
M11 = input.A1,
|
||||
M12 = input.A2,
|
||||
M13 = input.A3,
|
||||
M14 = input.A4,
|
||||
M21 = input.B1,
|
||||
M22 = input.B2,
|
||||
M23 = input.B3,
|
||||
M24 = input.B4,
|
||||
M31 = input.C1,
|
||||
M32 = input.C2,
|
||||
M33 = input.C3,
|
||||
M34 = input.C4,
|
||||
M41 = input.D1,
|
||||
M42 = input.D2,
|
||||
M43 = input.D3,
|
||||
M44 = input.D4
|
||||
};*/
|
||||
}
|
||||
public static OpenTK.Quaternion TKQuaternion(Assimp.Quaternion rot)
|
||||
{
|
||||
@ -27,6 +47,32 @@ namespace Switch_Toolbox.Library
|
||||
return quat;
|
||||
}
|
||||
|
||||
public static Matrix4x4 AssimpFromTKMatrix(Matrix4 tkMatrix)
|
||||
{
|
||||
Matrix4x4 m = new Matrix4x4();
|
||||
m.A1 = tkMatrix.M11;
|
||||
m.A2 = tkMatrix.M12;
|
||||
m.A3 = tkMatrix.M13;
|
||||
m.A4 = tkMatrix.M14;
|
||||
|
||||
m.B1 = tkMatrix.M21;
|
||||
m.B2 = tkMatrix.M22;
|
||||
m.B3 = tkMatrix.M23;
|
||||
m.B4 = tkMatrix.M24;
|
||||
|
||||
m.C1 = tkMatrix.M31;
|
||||
m.C2 = tkMatrix.M32;
|
||||
m.C3 = tkMatrix.M33;
|
||||
m.C4 = tkMatrix.M34;
|
||||
|
||||
m.D1 = tkMatrix.M41;
|
||||
m.D2 = tkMatrix.M42;
|
||||
m.D3 = tkMatrix.M43;
|
||||
m.D4 = tkMatrix.M44;
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
public static Vector3 ToEulerAngles(Assimp.Quaternion q)
|
||||
{
|
||||
float PI = (float)Math.PI;
|
||||
|
@ -25,7 +25,9 @@ namespace Switch_Toolbox.Library
|
||||
public const uint FOURCC_DXT5 = 0x35545844;
|
||||
public const uint FOURCC_ATI1 = 0x31495441;
|
||||
public const uint FOURCC_BC4U = 0x55344342;
|
||||
public const uint FOURCC_BC4S = 0x53344342;
|
||||
public const uint FOURCC_BC5U = 0x55354342;
|
||||
public const uint FOURCC_BC5S = 0x53354342;
|
||||
public const uint FOURCC_DX10 = 0x30315844;
|
||||
|
||||
public const uint FOURCC_ATI2 = 0x32495441;
|
||||
@ -369,7 +371,7 @@ namespace Switch_Toolbox.Library
|
||||
imageSize = header.width * header.height * getFormatSize(header.ddspf.fourCC);
|
||||
|
||||
reader.TemporarySeek((int)(4 + header.size + DX10HeaderSize), SeekOrigin.Begin);
|
||||
bdata = reader.ReadBytes((int)imageSize);
|
||||
bdata = reader.ReadBytes((int)(reader.BaseStream.Length - reader.Position));
|
||||
|
||||
reader.Dispose();
|
||||
reader.Close();
|
||||
|
@ -50,6 +50,15 @@ namespace Switch_Toolbox.Library
|
||||
|
||||
return Img;
|
||||
}
|
||||
private static void ConvertBgraToRgba(byte[] bytes)
|
||||
{
|
||||
for (int i = 0; i < bytes.Length; i += 4)
|
||||
{
|
||||
var temp = bytes[i];
|
||||
bytes[i] = bytes[i + 2];
|
||||
bytes[i + 2] = temp;
|
||||
}
|
||||
}
|
||||
public class ColorSwapFilter
|
||||
{
|
||||
private ColorSwapType swapType = ColorSwapType.FixDDS;
|
||||
|
@ -8,7 +8,7 @@ namespace Switch_Toolbox.Library
|
||||
{
|
||||
public class TextureHelper
|
||||
{
|
||||
public static Tuple<uint, uint> GetCurrentMipSize(uint width, uint height, uint blkHeight, uint blkWidth, uint bpp, int CurLevel)
|
||||
public static Tuple<uint, uint> GetCurrentMipSize(uint width, uint height, uint blkWidth, uint blkHeight, uint bpp, int CurLevel)
|
||||
{
|
||||
uint offset = 0;
|
||||
uint width_ = 0;
|
||||
|
@ -8,9 +8,165 @@ using System.IO;
|
||||
using System.IO.Compression;
|
||||
using OpenTK;
|
||||
using K4os.Compression.LZ4.Streams;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Switch_Toolbox.Library.IO
|
||||
{
|
||||
public class STFileSaver
|
||||
{
|
||||
/// <summary>
|
||||
/// Saves the <see cref="IFileFormat"/> as a file from the given <param name="FileName">
|
||||
/// </summary>
|
||||
/// <param name="IFileFormat">The format instance of the file being saved</param>
|
||||
/// <param name="FileName">The name of the file</param>
|
||||
/// <param name="Alignment">The Alignment used for compression. Used for Yaz0 compression type. </param>
|
||||
/// <param name="EnableDialog">Toggle for showing compression dialog</param>
|
||||
/// <returns></returns>
|
||||
public static void SaveFileFormat(IFileFormat FileFormat, string FileName, int Alignment = 0, bool EnableDialog = true)
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
|
||||
byte[] data = FileFormat.Save();
|
||||
if (EnableDialog && FileFormat.FileIsCompressed)
|
||||
{
|
||||
DialogResult save = MessageBox.Show($"Compress file with {FileFormat.CompressionType}?", "File Save", MessageBoxButtons.YesNo);
|
||||
|
||||
if (save == DialogResult.Yes)
|
||||
{
|
||||
switch (FileFormat.CompressionType)
|
||||
{
|
||||
case CompressionType.Yaz0:
|
||||
data = EveryFileExplorer.YAZ0.Compress(data, Runtime.Yaz0CompressionLevel, (uint)Alignment);
|
||||
break;
|
||||
case CompressionType.Zstb:
|
||||
data = STLibraryCompression.ZSTD.Compress(data);
|
||||
break;
|
||||
case CompressionType.Lz4:
|
||||
data = STLibraryCompression.Type_LZ4.Compress(data);
|
||||
break;
|
||||
case CompressionType.Lz4f:
|
||||
data = STLibraryCompression.Type_LZ4.Compress(data);
|
||||
break;
|
||||
case CompressionType.Gzip:
|
||||
data = STLibraryCompression.GZIP.Compress(data);
|
||||
break;
|
||||
default:
|
||||
MessageBox.Show($"Compression Type {FileFormat.CompressionType} not supported!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
File.WriteAllBytes(FileName, data);
|
||||
MessageBox.Show($"File has been saved to {FileName}");
|
||||
Cursor.Current = Cursors.Default;
|
||||
}
|
||||
}
|
||||
public class STFileLoader
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the <see cref="TreeNodeFile"/> from a file or byte array.
|
||||
/// </summary>
|
||||
/// <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="ArchiveHash">The unique hash from an archive for saving</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>
|
||||
/// <returns></returns>
|
||||
public static TreeNodeFile GetNodeFileFormat(string FileName, byte[] data, bool InArchive = false,
|
||||
string ArchiveHash = "", TreeNode archiveNode = null, bool Compressed = false, CompressionType CompType = 0)
|
||||
{
|
||||
IFileFormat format = OpenFileFormat(FileName, data, InArchive, ArchiveHash, archiveNode);
|
||||
|
||||
if (format is TreeNode)
|
||||
return (TreeNodeFile)format;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the <see cref="IFileFormat"/> from a file or byte array.
|
||||
/// </summary>
|
||||
/// <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>
|
||||
/// <returns></returns>
|
||||
public static IFileFormat OpenFileFormat(string FileName, byte[] data, bool InArchive = false,
|
||||
string ArchiveHash = "", TreeNode archiveNode = null, bool Compressed = false, CompressionType CompType = 0)
|
||||
{
|
||||
Cursor.Current = Cursors.WaitCursor;
|
||||
FileReader fileReader = new FileReader(data);
|
||||
string Magic4 = fileReader.ReadMagic(0, 4);
|
||||
string Magic2 = fileReader.ReadMagic(0, 2);
|
||||
if (Magic4 == "Yaz0")
|
||||
{
|
||||
data = EveryFileExplorer.YAZ0.Decompress(data);
|
||||
return OpenFileFormat(FileName, data, InArchive, ArchiveHash, archiveNode, true, CompressionType.Yaz0);
|
||||
}
|
||||
if (Magic4 == "ZLIB")
|
||||
{
|
||||
data = FileReader.InflateZLIB(fileReader.getSection(64, data.Length - 64));
|
||||
return OpenFileFormat(FileName, data, InArchive, ArchiveHash, archiveNode, true, CompressionType.Zlib);
|
||||
}
|
||||
fileReader.Dispose();
|
||||
fileReader.Close();
|
||||
foreach (IFileFormat fileFormat in FileManager.GetFileFormats())
|
||||
{
|
||||
if (fileFormat.Magic == Magic4 || fileFormat.Magic == Magic2)
|
||||
{
|
||||
fileFormat.CompressionType = CompType;
|
||||
fileFormat.FileIsCompressed = Compressed;
|
||||
fileFormat.Data = data;
|
||||
fileFormat.Load();
|
||||
fileFormat.FileName = Path.GetFileName(FileName);
|
||||
fileFormat.FilePath = FileName;
|
||||
fileFormat.IFileInfo = new IFileInfo();
|
||||
fileFormat.IFileInfo.InArchive = InArchive;
|
||||
fileFormat.IFileInfo.ArchiveHash = ArchiveHash;
|
||||
fileFormat.FileIsCompressed = Compressed;
|
||||
if (Compressed)
|
||||
fileFormat.CompressionType = CompType;
|
||||
|
||||
if (fileFormat is TreeNode)
|
||||
{
|
||||
((TreeNode)fileFormat).Text = archiveNode.Text;
|
||||
((TreeNode)fileFormat).ImageKey = archiveNode.ImageKey;
|
||||
((TreeNode)fileFormat).SelectedImageKey = archiveNode.SelectedImageKey;
|
||||
return fileFormat;
|
||||
}
|
||||
}
|
||||
if (fileFormat.Magic == string.Empty)
|
||||
{
|
||||
foreach (string str3 in fileFormat.Extension)
|
||||
{
|
||||
if (str3.Remove(0, 1) == Path.GetExtension(FileName))
|
||||
{
|
||||
fileFormat.Data = data;
|
||||
fileFormat.Load();
|
||||
fileFormat.FileName = Path.GetFileName(FileName);
|
||||
fileFormat.FilePath = FileName;
|
||||
fileFormat.IFileInfo = new IFileInfo();
|
||||
fileFormat.IFileInfo.InArchive = true;
|
||||
fileFormat.IFileInfo.ArchiveHash = ArchiveHash;
|
||||
|
||||
if (fileFormat is TreeNode)
|
||||
{
|
||||
((TreeNode)fileFormat).Text = archiveNode.Text;
|
||||
((TreeNode)fileFormat).ImageKey = archiveNode.ImageKey;
|
||||
((TreeNode)fileFormat).SelectedImageKey = archiveNode.SelectedImageKey;
|
||||
return fileFormat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class STLibraryCompression
|
||||
{
|
||||
public static byte[] CompressFile(byte[] data, IFileFormat format)
|
||||
@ -31,6 +187,32 @@ namespace Switch_Toolbox.Library.IO
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class GZIP
|
||||
{
|
||||
public static byte[] Decompress(byte[] b)
|
||||
|
@ -102,6 +102,10 @@
|
||||
<Reference Include="WeifenLuo.WinFormsUI.Docking.ThemeVS2015, Version=3.0.4.0, Culture=neutral, PublicKeyToken=5cded1a1a0a7b481, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\DockPanelSuite.ThemeVS2015.3.0.4\lib\net40\WeifenLuo.WinFormsUI.Docking.ThemeVS2015.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="ZstdNet, Version=1.3.3.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Switch_Toolbox\Lib\ZstdNet.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Animations\Animation.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user