Tons more RSTB progress (Note file in archives don't work yet)
This commit is contained in:
parent
7aa040aebf
commit
41adcfffc1
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,123 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Switch_Toolbox.Library.IO;
|
|
||||||
|
|
||||||
namespace FirstPlugin.FileFormats
|
|
||||||
{
|
|
||||||
//Parsing based on wiki https://zeldamods.org/wiki/ResourceSizeTable.product.rsizetable
|
|
||||||
//Functions from https://github.com/zeldamods/rstb/blob/master/rstb/rstb.py
|
|
||||||
//Copyright 2018 leoetlino <leo@leolam.fr>
|
|
||||||
//Licensed under GPLv2+
|
|
||||||
// Copy of license can be found under Lib/Licenses
|
|
||||||
|
|
||||||
public class RSTB
|
|
||||||
{
|
|
||||||
public Dictionary<string, uint> NameTables { get; set; }
|
|
||||||
public Dictionary<uint, uint> Crc32Tables { get; set; }
|
|
||||||
|
|
||||||
public void LoadFile(string FileName) {
|
|
||||||
Read(new FileReader(FileName));
|
|
||||||
}
|
|
||||||
|
|
||||||
public RSTB()
|
|
||||||
{
|
|
||||||
Crc32Tables = new Dictionary<uint, uint>();
|
|
||||||
NameTables = new Dictionary<string, uint>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Read(FileReader reader)
|
|
||||||
{
|
|
||||||
reader.ReadSignature(4, "RSTB");
|
|
||||||
uint Crc32TableCount = reader.ReadUInt32();
|
|
||||||
uint NameTableCount = reader.ReadUInt32();
|
|
||||||
|
|
||||||
for (int i = 0; i < Crc32TableCount; i++)
|
|
||||||
{
|
|
||||||
uint Crc32 = reader.ReadUInt32();
|
|
||||||
uint Size = reader.ReadUInt32();
|
|
||||||
Crc32Tables.Add(Crc32, Size);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < NameTableCount; i++)
|
|
||||||
{
|
|
||||||
string Name = reader.ReadString(128);
|
|
||||||
uint Size = reader.ReadUInt32();
|
|
||||||
NameTables.Add(Name, Size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write(FileWriter writer)
|
|
||||||
{
|
|
||||||
writer.WriteSignature("RSTB");
|
|
||||||
writer.Write(Crc32Tables.Count);
|
|
||||||
writer.Write(NameTables.Count);
|
|
||||||
|
|
||||||
foreach (var table in Crc32Tables)
|
|
||||||
{
|
|
||||||
writer.Write(table.Key);
|
|
||||||
writer.Write(table.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var table in NameTables)
|
|
||||||
{
|
|
||||||
writer.Write(table.Key.ToByteArray(128));
|
|
||||||
writer.Write(table.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint GetSize(string Name)
|
|
||||||
{
|
|
||||||
uint Crc32 = Name.EncodeCrc32();
|
|
||||||
if (Crc32Tables.ContainsKey(Crc32))
|
|
||||||
return Crc32Tables[Crc32];
|
|
||||||
if (NameTables.ContainsKey(Name))
|
|
||||||
return NameTables[Name];
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public uint SetSize(string Name)
|
|
||||||
{
|
|
||||||
if (IsNeededInNameMap(Name))
|
|
||||||
{
|
|
||||||
if (Name.Length > 128)
|
|
||||||
throw new Exception("Name is too long! Must be smaller than 128 characters!");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
uint Crc32 = Name.EncodeCrc32();
|
|
||||||
if (Crc32Tables.ContainsKey(Crc32))
|
|
||||||
return Crc32Tables[Crc32];
|
|
||||||
if (NameTables.ContainsKey(Name))
|
|
||||||
return NameTables[Name];
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetBufferSize()
|
|
||||||
{
|
|
||||||
return (4 + 4 + 4) + 8 * Crc32Tables.Count + (132 * NameTables.Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsInTable(string Name)
|
|
||||||
{
|
|
||||||
uint Crc32 = Name.EncodeCrc32();
|
|
||||||
if (Crc32Tables.ContainsKey(Crc32) || NameTables.ContainsKey(Name))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsNeededInNameMap(string Name)
|
|
||||||
{
|
|
||||||
uint Crc32 = Name.EncodeCrc32();
|
|
||||||
foreach (var existingName in NameTables.Keys)
|
|
||||||
if (Crc32Tables.ContainsKey(existingName.EncodeCrc32()))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
56
Switch_FileFormatsMain/Resources/resource_factory_info.tsv
Normal file
56
Switch_FileFormatsMain/Resources/resource_factory_info.tsv
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
name size_nx size_wiiu alignment parse_size_nx parse_size_wiiu other_extensions multiplier constant subsystem details
|
||||||
|
BASE 0x20 0x14 8 0 0 1 0 General
|
||||||
|
* 0x38 0x20 4 0 0 Tex.bfres, Tex1.bfres, Tex2.bfres, Tex1.1.bfres, Tex1.2.bfres, Tex1.3.bfres, Tex1.4.bfres 1 0 General
|
||||||
|
sarc 0x68 0x3c 0x80 0 0 pack, bactorpack, bmodelsh, beventpack, stera, stats 1 0 General
|
||||||
|
bfres 0x1a8 0x13c 0x1000 complex complex 2.5 0x400000 General
|
||||||
|
bcamanim 0x50 0x2c 0x2000 complex complex 1 0x680 General 0x2f8 + graphics resources
|
||||||
|
batpl, bnfprl 0x40 0x24 4 0 0 1 0 General
|
||||||
|
bplacement 0x48 0x14 4 0 0 1 0 General
|
||||||
|
hks, lua 0x38 0x14 4 0 0 1 0 General
|
||||||
|
bactcapt 0x538 0x3b4 4 0 0 1 0x1000 ActorCaptureMgr
|
||||||
|
bitemico 0x60 0xd0 0x2000 0 0 1 0 UI
|
||||||
|
jpg 0x80 0x174 0x2000 0 0 1 0 UI
|
||||||
|
bmaptex 0x60 0xd0 0x2000 0 0 1 0 UI
|
||||||
|
bstftex 0x60 0xd0 0x2000 0 0 bmapopen, breviewtex 1 0 UI
|
||||||
|
bgdata 0x140 0xcc 4 0 0 5 0xc0000 GameData
|
||||||
|
bgsvdata 0x38 0x14 4 0 0 1 0x300000 GameData
|
||||||
|
hknm2 0x48 0x28 4 complex complex 1 0xb28 HavokAI
|
||||||
|
bmscdef 0x2a8 0x1fc 4 complex complex 1 0 Sound
|
||||||
|
bars 0xb0 0x84 0x80 complex complex 1 0 Sound allocates (0x18 + string data on heap) in some cases + 0xa8 and calls sead::ResourceMgr::create with the heap
|
||||||
|
bxml 0x778 0x4a8 4 complex complex 1 0x1000 ActorParam 0 or (4 * n) (depending on contents)
|
||||||
|
bgparamlist 0x2c0 0x248 4 complex complex 1 0xdb18 ActorParam complex. allocates depending on nodes that are present in the gparamlist
|
||||||
|
bmodellist 0x7d0 0x508 4 complex complex 2 0 ActorParam
|
||||||
|
baslist 0x410 0x2f4 4 complex complex 0 0x80000 ActorParam
|
||||||
|
baiprog 0x448 0x30c 4 complex complex 1 0x300000 ActorParam
|
||||||
|
bphysics 0x470 0x324 4 complex complex 6 0 ActorParam
|
||||||
|
bchemical 0x3c0 0x2cc 4 complex complex 0 0x2000 ActorParam
|
||||||
|
bas 0x3c8 0x2d0 4 complex complex 0 0x80000 ActorParam
|
||||||
|
batcllist 0x3f0 0x2e4 4 0 0 1 0x2000 ActorParam
|
||||||
|
batcl 0x428 0x344 4 complex complex 1 0x2000 ActorParam
|
||||||
|
baischedule 0x2b8 0x244 4 0 0 1 0x800 ActorParam
|
||||||
|
bdmgparam 0x11d0 0x9f0 4 0x790 0x3c0 1 0x20000 ActorParam
|
||||||
|
brgconfiglist 0x3d0 0x2d4 4 complex complex 1 0x2000 ActorParam
|
||||||
|
brgconfig 0x42d8 0x2acc 4 0 0 1 0x20000 ActorParam
|
||||||
|
brgbw 0x2c0 0x248 4 complex complex 1 0x20000 ActorParam
|
||||||
|
bawareness 0xb38 0x70c 4 0 0 1 0 ActorParam
|
||||||
|
bdrop 0x320 0x27c 4 complex complex 1 0x5000 ActorParam
|
||||||
|
bshop 0x320 0x27c 4 complex complex 1 0x20000 ActorParam
|
||||||
|
brecipe 0x320 0x27c 4 complex complex 1 0x20000 ActorParam
|
||||||
|
blod 0x3c0 0x2cc 4 0 0 1 0x20000 ActorParam
|
||||||
|
bbonectrl 0x8d0 0x564 4 complex complex 1 0x40000 ActorParam
|
||||||
|
blifecondition 0x4b0 0x35c 4 complex complex 1 0x20000 ActorParam
|
||||||
|
bumii 0x2b8 0x244 4 0 0 1 0 ActorParam
|
||||||
|
baniminfo 0x2c8 0x24c 4 complex complex 1.5 0 ActorParam
|
||||||
|
byaml 0x20 0x14 4 0 0 1 0 ActorParam
|
||||||
|
bassetting 0x260 0x1d8 4 complex complex 0 0x80000 ActorParam
|
||||||
|
hkrb 0x20 0x14 4 0 0 1 0x400 Physics
|
||||||
|
hkrg 0x20 0x14 4 0 0 1 0x400 Physics
|
||||||
|
bphyssb 0x5b0 0x384 4 complex complex 1 0x100000 Physics
|
||||||
|
hkcl 0xe8 0xb8 4 complex complex 2 0x2800 Physics
|
||||||
|
hksc 0x140 0xe8 4 complex complex 1.3 0x40000 Physics
|
||||||
|
hktmrb 0x48 0x28 4 complex complex 1 0x800 Physics
|
||||||
|
brgcon 0x48 0x28 4 complex complex 1 0x4000 Physics
|
||||||
|
esetlist 0x38 0x20 0x4000 0 0 1 0 Effect
|
||||||
|
bdemo 0xb20 0x6cc 4 0 0 1 0xb20 Event
|
||||||
|
bfevfl 0x40 0x24 4 0 0 1 0x40 Event
|
||||||
|
bfevtm 0x40 0x24 4 0 0 1 0x40 Event
|
|
@ -76,6 +76,10 @@
|
|||||||
<HintPath>..\Toolbox\Lib\CSCore.dll</HintPath>
|
<HintPath>..\Toolbox\Lib\CSCore.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="CsvHelper">
|
||||||
|
<HintPath>..\Toolbox\Lib\CsvHelper.dll</HintPath>
|
||||||
|
<Private>False</Private>
|
||||||
|
</Reference>
|
||||||
<Reference Include="EditorCoreCommon">
|
<Reference Include="EditorCoreCommon">
|
||||||
<HintPath>..\Toolbox\Lib\EditorCoreCommon.dll</HintPath>
|
<HintPath>..\Toolbox\Lib\EditorCoreCommon.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
@ -234,12 +238,10 @@
|
|||||||
<Compile Include="FileFormats\Audio\Archives\BFGRP.cs" />
|
<Compile Include="FileFormats\Audio\Archives\BFGRP.cs" />
|
||||||
<Compile Include="FileFormats\GFBMDL\GFBMDL.cs" />
|
<Compile Include="FileFormats\GFBMDL\GFBMDL.cs" />
|
||||||
<Compile Include="FileFormats\Hashes\SAHT.cs" />
|
<Compile Include="FileFormats\Hashes\SAHT.cs" />
|
||||||
<Compile Include="FileFormats\SizeTables\RSTB.cs" />
|
|
||||||
<Compile Include="FileFormats\Shader\NSWShaderDecompile.cs" />
|
<Compile Include="FileFormats\Shader\NSWShaderDecompile.cs" />
|
||||||
<Compile Include="FileFormats\Shader\NUSHDB.cs" />
|
<Compile Include="FileFormats\Shader\NUSHDB.cs" />
|
||||||
<Compile Include="FileFormats\Shader\NVNSH.cs" />
|
<Compile Include="FileFormats\Shader\NVNSH.cs" />
|
||||||
<Compile Include="FileFormats\Shader\SHARCFBNX.cs" />
|
<Compile Include="FileFormats\Shader\SHARCFBNX.cs" />
|
||||||
<Compile Include="FileFormats\SizeTables\TPFileSizeTable.cs" />
|
|
||||||
<Compile Include="FileFormats\Texture\BCLIM.cs" />
|
<Compile Include="FileFormats\Texture\BCLIM.cs" />
|
||||||
<Compile Include="FileFormats\Texture\BFLIM.cs" />
|
<Compile Include="FileFormats\Texture\BFLIM.cs" />
|
||||||
<Compile Include="FileFormats\Layout\BFLAN.cs" />
|
<Compile Include="FileFormats\Layout\BFLAN.cs" />
|
||||||
@ -1211,6 +1213,7 @@
|
|||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="Resources\resource_factory_info.tsv" />
|
||||||
<None Include="Resources\TextureError.png" />
|
<None Include="Resources\TextureError.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1 +1 @@
|
|||||||
a5f8e3bc83ca333f1641f1a9eb9720cb2bff4cb6
|
81115f490d097ea68b62b86788a8bc08ded17c3e
|
||||||
|
Binary file not shown.
Binary file not shown.
@ -216,6 +216,12 @@ namespace Switch_Toolbox.Library
|
|||||||
Enum.TryParse(node.InnerText, out cameraMode);
|
Enum.TryParse(node.InnerText, out cameraMode);
|
||||||
Runtime.ViewportCameraMode = cameraMode;
|
Runtime.ViewportCameraMode = cameraMode;
|
||||||
break;
|
break;
|
||||||
|
case "BotwTable":
|
||||||
|
bool.TryParse(node.InnerText, out Runtime.ResourceTables.BotwTable);
|
||||||
|
break;
|
||||||
|
case "TpTable":
|
||||||
|
bool.TryParse(node.InnerText, out Runtime.ResourceTables.TpTable);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -318,6 +324,7 @@ namespace Switch_Toolbox.Library
|
|||||||
AppendBackgroundSettings(doc, mainNode);
|
AppendBackgroundSettings(doc, mainNode);
|
||||||
AppendGridSettings(doc, mainNode);
|
AppendGridSettings(doc, mainNode);
|
||||||
AppenPBRSettings(doc, mainNode);
|
AppenPBRSettings(doc, mainNode);
|
||||||
|
AppendResourceTableSettings(doc, mainNode);
|
||||||
|
|
||||||
return doc;
|
return doc;
|
||||||
}
|
}
|
||||||
@ -407,6 +414,14 @@ namespace Switch_Toolbox.Library
|
|||||||
renderSettingsNode.AppendChild(createNode(doc, "bonePointSize", Runtime.bonePointSize.ToString()));
|
renderSettingsNode.AppendChild(createNode(doc, "bonePointSize", Runtime.bonePointSize.ToString()));
|
||||||
renderSettingsNode.AppendChild(createNode(doc, "MaxCameraSpeed", Runtime.MaxCameraSpeed.ToString()));
|
renderSettingsNode.AppendChild(createNode(doc, "MaxCameraSpeed", Runtime.MaxCameraSpeed.ToString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void AppendResourceTableSettings(XmlDocument doc, XmlNode parentNode)
|
||||||
|
{
|
||||||
|
XmlNode resourceTableNode = doc.CreateElement("ResourceTables");
|
||||||
|
parentNode.AppendChild(resourceTableNode);
|
||||||
|
resourceTableNode.AppendChild(createNode(doc, "BotwTable", Runtime.ResourceTables.BotwTable.ToString()));
|
||||||
|
resourceTableNode.AppendChild(createNode(doc, "TpTable", Runtime.ResourceTables.TpTable.ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
private static void AppendGridSettings(XmlDocument doc, XmlNode parentNode)
|
private static void AppendGridSettings(XmlDocument doc, XmlNode parentNode)
|
||||||
{
|
{
|
||||||
|
335
Switch_Toolbox_Library/FileFormats/SizeTables/RSTB.cs
Normal file
335
Switch_Toolbox_Library/FileFormats/SizeTables/RSTB.cs
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Switch_Toolbox.Library.IO;
|
||||||
|
using CsvHelper;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Switch_Toolbox.Library
|
||||||
|
{
|
||||||
|
//Parsing based on wiki https://zeldamods.org/wiki/ResourceSizeTable.product.rsizetable
|
||||||
|
//Functions from https://github.com/zeldamods/rstb/blob/master/rstb/rstb.py
|
||||||
|
//Copyright 2018 leoetlino <leo@leolam.fr>
|
||||||
|
//Licensed under GPLv2+
|
||||||
|
// Copy of license can be found under Lib/Licenses
|
||||||
|
public class RSTB
|
||||||
|
{
|
||||||
|
public bool IsBigEndian { get; set; } = true;
|
||||||
|
public bool IsWiiU { get; set; } = true;
|
||||||
|
|
||||||
|
public Dictionary<string, uint> NameTables { get; set; }
|
||||||
|
public Dictionary<uint, uint> Crc32Tables { get; set; }
|
||||||
|
|
||||||
|
private int ParseSize(string FilePath, byte[] Data = null, bool Force = false)
|
||||||
|
{
|
||||||
|
var size = new RSTB.SizeCalculator().CalculateFileSize(FilePath, Data, IsWiiU, Force);
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
var result = MessageBox.Show("Error! Could not calculate size for resource entry! Do you want to remove it instead?", "Resource Table", MessageBoxButtons.YesNo);
|
||||||
|
if (result == DialogResult.OK)
|
||||||
|
{
|
||||||
|
DeleteEntry(FilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetEntry(string FileName, byte[] Data = null, bool Force = false)
|
||||||
|
{
|
||||||
|
uint OldSize = GetSize(FileName);
|
||||||
|
uint NewSize = (uint)ParseSize(FileName, Data, Force);
|
||||||
|
|
||||||
|
SetSize(FileName, NewSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void LoadFile(string FileName) {
|
||||||
|
Read(new FileReader(EveryFileExplorer.YAZ0.Decompress(FileName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hacky but no other way. Check if the name path count is over 10k
|
||||||
|
//This shouldn't ever be the case, and little endian bom would read over that amount
|
||||||
|
private bool CheckEndianness(FileReader reader)
|
||||||
|
{
|
||||||
|
reader.SetByteOrder(true);
|
||||||
|
|
||||||
|
reader.Position = 8;
|
||||||
|
bool IsBigEndian = reader.ReadUInt32() < 10000;
|
||||||
|
reader.Position = 0;
|
||||||
|
|
||||||
|
return IsBigEndian;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RSTB()
|
||||||
|
{
|
||||||
|
Crc32Tables = new Dictionary<uint, uint>();
|
||||||
|
NameTables = new Dictionary<string, uint>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Read(FileReader reader)
|
||||||
|
{
|
||||||
|
IsBigEndian = CheckEndianness(reader);
|
||||||
|
|
||||||
|
reader.SetByteOrder(IsBigEndian);
|
||||||
|
reader.ReadSignature(4, "RSTB");
|
||||||
|
uint Crc32TableCount = reader.ReadUInt32();
|
||||||
|
uint NameTableCount = reader.ReadUInt32();
|
||||||
|
|
||||||
|
for (int i = 0; i < Crc32TableCount; i++)
|
||||||
|
{
|
||||||
|
uint Crc32 = reader.ReadUInt32();
|
||||||
|
uint Size = reader.ReadUInt32();
|
||||||
|
|
||||||
|
Crc32Tables.Add(Crc32, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < NameTableCount; i++)
|
||||||
|
{
|
||||||
|
string Name = reader.ReadString(128);
|
||||||
|
uint Size = reader.ReadUInt32();
|
||||||
|
|
||||||
|
NameTables.Add(Name, Size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(FileWriter writer)
|
||||||
|
{
|
||||||
|
writer.SetByteOrder(IsBigEndian);
|
||||||
|
writer.WriteSignature("RSTB");
|
||||||
|
writer.Write(Crc32Tables.Count);
|
||||||
|
writer.Write(NameTables.Count);
|
||||||
|
|
||||||
|
var Crc32Sorted = Crc32Tables.OrderBy(x => x.Key);
|
||||||
|
var NamesSorted = NameTables.OrderBy(x => x.Key);
|
||||||
|
|
||||||
|
foreach (var table in Crc32Sorted)
|
||||||
|
{
|
||||||
|
writer.Write(table.Key);
|
||||||
|
writer.Write(table.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var table in NamesSorted)
|
||||||
|
{
|
||||||
|
writer.Write(table.Key.ToByteArray(128));
|
||||||
|
writer.Write(table.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.Close();
|
||||||
|
writer.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Gets the size of the resource in the RSTB
|
||||||
|
public uint GetSize(string Name)
|
||||||
|
{
|
||||||
|
uint Crc32 = Name.EncodeCrc32();
|
||||||
|
if (Crc32Tables.ContainsKey(Crc32))
|
||||||
|
return Crc32Tables[Crc32];
|
||||||
|
if (NameTables.ContainsKey(Name))
|
||||||
|
return NameTables[Name];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sets the size of the resource in the RSTB
|
||||||
|
public void SetSize(string Name, uint Size)
|
||||||
|
{
|
||||||
|
if (IsNeededInNameMap(Name))
|
||||||
|
{
|
||||||
|
if (Name.Length > 128)
|
||||||
|
throw new Exception("Name is too long! Must be smaller than 128 characters!");
|
||||||
|
|
||||||
|
NameTables[Name] = Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint Crc32 = Name.EncodeCrc32();
|
||||||
|
Crc32Tables[Crc32] = Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DeleteEntry(string FileName)
|
||||||
|
{
|
||||||
|
if (!IsInTable(FileName))
|
||||||
|
MessageBox.Show("File not in table! Could not remove entry! " + FileName);
|
||||||
|
|
||||||
|
uint Crc32 = FileName.EncodeCrc32();
|
||||||
|
if (Crc32Tables.ContainsKey(Crc32))
|
||||||
|
Crc32Tables.Remove(Crc32);
|
||||||
|
if (NameTables.ContainsKey(FileName))
|
||||||
|
NameTables.Remove(FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetBufferSize()
|
||||||
|
{
|
||||||
|
return (4 + 4 + 4) + 8 * Crc32Tables.Count + (132 * NameTables.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsInTable(string Name)
|
||||||
|
{
|
||||||
|
uint Crc32 = Name.EncodeCrc32();
|
||||||
|
if (Crc32Tables.ContainsKey(Crc32) || NameTables.ContainsKey(Name))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsNeededInNameMap(string Name)
|
||||||
|
{
|
||||||
|
uint Crc32 = Name.EncodeCrc32();
|
||||||
|
foreach (var existingName in NameTables.Keys)
|
||||||
|
if (Crc32Tables.ContainsKey(existingName.EncodeCrc32()))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FactoryParsers
|
||||||
|
{
|
||||||
|
public int ParseWiiU(byte[] FileData) { return 0;}
|
||||||
|
public int ParseNX(byte[] FileData) { return 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SizeCalculator
|
||||||
|
{
|
||||||
|
public Dictionary<string, FactoryParsers> FactoryParsers = new Dictionary<string, FactoryParsers>();
|
||||||
|
public Dictionary<string, Factory> FactoryInfo = new Dictionary<string, Factory>();
|
||||||
|
|
||||||
|
public class Factory
|
||||||
|
{
|
||||||
|
public int Size_NX { get; set; }
|
||||||
|
public int Size_WiiU { get; set; }
|
||||||
|
public int Alignment { get; set; }
|
||||||
|
public int Parse_Size_NX { get; set; }
|
||||||
|
public int Parse_Size_WiiU { get; set; }
|
||||||
|
|
||||||
|
public float Multiplier { get; set; }
|
||||||
|
public int Constant { get; set; }
|
||||||
|
public bool IsComplex { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public SizeCalculator()
|
||||||
|
{
|
||||||
|
var reader = new System.IO.StreamReader(new System.IO.MemoryStream(Properties.Resources.resource_factory_info), true);
|
||||||
|
using (var csv = new CsvReader(reader, new CsvHelper.Configuration.Configuration() { Delimiter = "\t" }))
|
||||||
|
{
|
||||||
|
csv.Read();
|
||||||
|
csv.ReadHeader();
|
||||||
|
while (csv.Read())
|
||||||
|
{
|
||||||
|
//Parse table entries
|
||||||
|
var name = csv.GetField("name");
|
||||||
|
var size_nx = csv.GetField("size_nx");
|
||||||
|
var size_wiiu = csv.GetField("size_wiiu");
|
||||||
|
var alignment = csv.GetField("alignment");
|
||||||
|
var constant = csv.GetField("constant");
|
||||||
|
var parse_size_nx = csv.GetField("parse_size_nx");
|
||||||
|
var parse_size_wiiu = csv.GetField("parse_size_wiiu");
|
||||||
|
var multiplier = csv.GetField("multiplier");
|
||||||
|
var otherExtensions = csv.GetField("other_extensions").Split(',');
|
||||||
|
|
||||||
|
foreach (var extension in otherExtensions)
|
||||||
|
Console.WriteLine("other_extensions " + extension);
|
||||||
|
|
||||||
|
//Add new factory to dictionary for extension data
|
||||||
|
var factory = new Factory();
|
||||||
|
ParseObject(size_nx, factory.Size_NX);
|
||||||
|
ParseObject(size_wiiu, factory.Size_WiiU);
|
||||||
|
ParseObject(alignment, factory.Alignment);
|
||||||
|
ParseObject(constant, factory.Constant);
|
||||||
|
ParseObject(parse_size_nx, factory.Parse_Size_NX);
|
||||||
|
ParseObject(parse_size_wiiu, factory.Parse_Size_WiiU);
|
||||||
|
ParseObject(multiplier, factory.Multiplier);
|
||||||
|
|
||||||
|
FactoryInfo.Add(name, factory);
|
||||||
|
foreach (var extension in otherExtensions)
|
||||||
|
{
|
||||||
|
if (extension != string.Empty)
|
||||||
|
FactoryInfo.Add(extension.Strip(), factory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ParseObject(string value, uint output) {
|
||||||
|
uint.TryParse(value, out output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ParseObject(string value, float output) {
|
||||||
|
float.TryParse(value, out output);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CalculateFileSize(string FileName, byte[] Data, bool IsWiiU, bool Force)
|
||||||
|
{
|
||||||
|
return CalculateFileSizeByExtension(FileName, Data, IsWiiU, System.IO.Path.GetExtension(FileName), Force);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int CalculateFileSizeByExtension(string FileName, byte[] Data, bool WiiU, string Ext, bool Force = false)
|
||||||
|
{
|
||||||
|
int Size = 0;
|
||||||
|
if (System.IO.File.Exists(FileName))
|
||||||
|
{
|
||||||
|
if (Ext.StartsWith("s"))
|
||||||
|
{
|
||||||
|
using (var reader = new FileReader(FileName))
|
||||||
|
{
|
||||||
|
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
|
||||||
|
reader.Seek(4, System.IO.SeekOrigin.Begin);
|
||||||
|
Size = reader.ReadInt32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Size = (int)new System.IO.FileInfo(FileName).Length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Size = Data.Length;
|
||||||
|
|
||||||
|
byte[] FileData = Data;
|
||||||
|
|
||||||
|
Size = (Size + 31) & -32;
|
||||||
|
string ActualExt = Ext.Replace(".s", ".").Remove(0,1);
|
||||||
|
Factory Info = FactoryInfo[ActualExt];
|
||||||
|
if (Info.IsComplex)
|
||||||
|
{
|
||||||
|
if (!FactoryParsers.ContainsKey(ActualExt) && !Force)
|
||||||
|
return 0;
|
||||||
|
if (System.IO.File.Exists(FileName))
|
||||||
|
FileData = EveryFileExplorer.YAZ0.Decompress(FileName);
|
||||||
|
else if (Data != null)
|
||||||
|
FileData = EveryFileExplorer.YAZ0.Decompress(Data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WiiU)
|
||||||
|
{
|
||||||
|
Size += 0xe4;
|
||||||
|
Size += Info.Size_WiiU;
|
||||||
|
|
||||||
|
if (!FactoryParsers.ContainsKey(ActualExt))
|
||||||
|
Size += 0;
|
||||||
|
else if (Info.IsComplex)
|
||||||
|
Size += FactoryParsers[ActualExt].ParseWiiU(FileData);
|
||||||
|
else
|
||||||
|
Size += Info.Parse_Size_WiiU;
|
||||||
|
|
||||||
|
if (ActualExt == "beventpack")
|
||||||
|
Size += 0xe0;
|
||||||
|
if (ActualExt == "bfevfl")
|
||||||
|
Size += 0x58;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Size += 0x168;
|
||||||
|
Size += Info.Size_NX;
|
||||||
|
|
||||||
|
if (!FactoryParsers.ContainsKey(ActualExt))
|
||||||
|
Size += 0;
|
||||||
|
else if (Info.IsComplex)
|
||||||
|
Size += FactoryParsers[ActualExt].ParseNX(FileData);
|
||||||
|
else
|
||||||
|
Size += Info.Parse_Size_NX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ using Switch_Toolbox.Library.IO;
|
|||||||
using Switch_Toolbox.Library;
|
using Switch_Toolbox.Library;
|
||||||
using Syroot.BinaryData;
|
using Syroot.BinaryData;
|
||||||
|
|
||||||
namespace FirstPlugin
|
namespace Switch_Toolbox.Library
|
||||||
{
|
{
|
||||||
public class TPFileSizeTable
|
public class TPFileSizeTable
|
||||||
{
|
{
|
@ -226,7 +226,6 @@ namespace BarSlider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void OnMouseUp(object sender, MouseEventArgs e)
|
private void OnMouseUp(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (TextEditorActive)
|
if (TextEditorActive)
|
||||||
|
113
Switch_Toolbox_Library/Forms/Dialogs/STSaveLogDialog.Designer.cs
generated
Normal file
113
Switch_Toolbox_Library/Forms/Dialogs/STSaveLogDialog.Designer.cs
generated
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
namespace Switch_Toolbox.Library.Forms
|
||||||
|
{
|
||||||
|
partial class STSaveLogDialog
|
||||||
|
{
|
||||||
|
/// <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 Windows Form 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.btnDetails = new Switch_Toolbox.Library.Forms.STButton();
|
||||||
|
this.lblMessage = new Switch_Toolbox.Library.Forms.STLabel();
|
||||||
|
this.tbDetails = new System.Windows.Forms.RichTextBox();
|
||||||
|
this.stButton1 = new Switch_Toolbox.Library.Forms.STButton();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// btnDetails
|
||||||
|
//
|
||||||
|
this.btnDetails.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.btnDetails.Enabled = false;
|
||||||
|
this.btnDetails.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.btnDetails.Location = new System.Drawing.Point(12, 78);
|
||||||
|
this.btnDetails.Name = "btnDetails";
|
||||||
|
this.btnDetails.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.btnDetails.TabIndex = 1;
|
||||||
|
this.btnDetails.Text = "Details";
|
||||||
|
this.btnDetails.UseVisualStyleBackColor = true;
|
||||||
|
this.btnDetails.Click += new System.EventHandler(this.btnDetails_Click);
|
||||||
|
//
|
||||||
|
// lblMessage
|
||||||
|
//
|
||||||
|
this.lblMessage.AutoSize = true;
|
||||||
|
this.lblMessage.Location = new System.Drawing.Point(12, 19);
|
||||||
|
this.lblMessage.MaximumSize = new System.Drawing.Size(310, 0);
|
||||||
|
this.lblMessage.Name = "lblMessage";
|
||||||
|
this.lblMessage.Size = new System.Drawing.Size(35, 13);
|
||||||
|
this.lblMessage.TabIndex = 5;
|
||||||
|
this.lblMessage.Text = "label1";
|
||||||
|
//
|
||||||
|
// tbDetails
|
||||||
|
//
|
||||||
|
this.tbDetails.Anchor = System.Windows.Forms.AnchorStyles.Bottom;
|
||||||
|
this.tbDetails.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||||
|
this.tbDetails.Location = new System.Drawing.Point(-42, 107);
|
||||||
|
this.tbDetails.MaximumSize = new System.Drawing.Size(328, 100);
|
||||||
|
this.tbDetails.Name = "tbDetails";
|
||||||
|
this.tbDetails.ReadOnly = true;
|
||||||
|
this.tbDetails.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Vertical;
|
||||||
|
this.tbDetails.Size = new System.Drawing.Size(328, 100);
|
||||||
|
this.tbDetails.TabIndex = 6;
|
||||||
|
this.tbDetails.Text = "";
|
||||||
|
this.tbDetails.Visible = false;
|
||||||
|
//
|
||||||
|
// stButton1
|
||||||
|
//
|
||||||
|
this.stButton1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||||
|
this.stButton1.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||||
|
this.stButton1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||||
|
this.stButton1.Location = new System.Drawing.Point(160, 78);
|
||||||
|
this.stButton1.Name = "stButton1";
|
||||||
|
this.stButton1.Size = new System.Drawing.Size(75, 23);
|
||||||
|
this.stButton1.TabIndex = 8;
|
||||||
|
this.stButton1.Text = "Ok";
|
||||||
|
this.stButton1.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// STSaveLogDialog
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(247, 111);
|
||||||
|
this.Controls.Add(this.stButton1);
|
||||||
|
this.Controls.Add(this.tbDetails);
|
||||||
|
this.Controls.Add(this.lblMessage);
|
||||||
|
this.Controls.Add(this.btnDetails);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.MinimizeBox = false;
|
||||||
|
this.Name = "STSaveLogDialog";
|
||||||
|
this.ShowIcon = false;
|
||||||
|
this.ShowInTaskbar = false;
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||||
|
this.Text = "Save Notification";
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
this.PerformLayout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
private Switch_Toolbox.Library.Forms.STButton btnDetails;
|
||||||
|
private Switch_Toolbox.Library.Forms.STLabel lblMessage;
|
||||||
|
private System.Windows.Forms.RichTextBox tbDetails;
|
||||||
|
private STButton stButton1;
|
||||||
|
}
|
||||||
|
}
|
103
Switch_Toolbox_Library/Forms/Dialogs/STSaveLogDialog.cs
Normal file
103
Switch_Toolbox_Library/Forms/Dialogs/STSaveLogDialog.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Data;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace Switch_Toolbox.Library.Forms
|
||||||
|
{
|
||||||
|
//Based from https://stackoverflow.com/questions/8653430/how-can-i-show-a-message-box-with-details-in-winforms/40469355#40469355
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A dialog-style form with optional colapsable details section
|
||||||
|
/// </summary>
|
||||||
|
public partial class STSaveLogDialog : Form
|
||||||
|
{
|
||||||
|
private const string DetailsFormat = "Details {0}";
|
||||||
|
|
||||||
|
public STSaveLogDialog(string message, string title, string details = null)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
lblMessage.Text = message;
|
||||||
|
this.Text = title;
|
||||||
|
|
||||||
|
if (details != null)
|
||||||
|
{
|
||||||
|
btnDetails.Enabled = true;
|
||||||
|
btnDetails.Text = DownArrow;
|
||||||
|
tbDetails.Text = details;
|
||||||
|
}
|
||||||
|
BackColor = FormThemes.BaseTheme.FormBackColor;
|
||||||
|
ForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||||
|
|
||||||
|
tbDetails.BackColor = FormThemes.BaseTheme.FormBackColor;
|
||||||
|
tbDetails.ForeColor = FormThemes.BaseTheme.FormForeColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string UpArrow
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return string.Format(DetailsFormat, char.ConvertFromUtf32(0x25B4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string DownArrow
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return string.Format(DetailsFormat, char.ConvertFromUtf32(0x25BE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Meant to give the look and feel of a regular MessageBox
|
||||||
|
/// </summary>
|
||||||
|
public static DialogResult Show(string message, string title, string details = null)
|
||||||
|
{
|
||||||
|
return new STSaveLogDialog(message, title, details).ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnLoad(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnLoad(e);
|
||||||
|
|
||||||
|
// Change these properties now so the label is rendered so we get its real height
|
||||||
|
var height = lblMessage.Height;
|
||||||
|
SetMessageBoxHeight(height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetMessageBoxHeight(int heightChange)
|
||||||
|
{
|
||||||
|
this.Height = this.Height + heightChange;
|
||||||
|
if (this.Height < 150)
|
||||||
|
{
|
||||||
|
this.Height = 150;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnDetails_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// Re-anchoring the controls so they stay in their place while the form is resized
|
||||||
|
stButton1.Anchor = AnchorStyles.Top;
|
||||||
|
btnDetails.Anchor = AnchorStyles.Top;
|
||||||
|
tbDetails.Anchor = AnchorStyles.Top;
|
||||||
|
|
||||||
|
tbDetails.Visible = !tbDetails.Visible;
|
||||||
|
|
||||||
|
btnDetails.Text = tbDetails.Visible ? UpArrow : DownArrow;
|
||||||
|
|
||||||
|
SetMessageBoxHeight(tbDetails.Visible ? tbDetails.Height + 10 : -tbDetails.Height - 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnCopy_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
Clipboard.SetText(tbDetails.Text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
120
Switch_Toolbox_Library/Forms/Dialogs/STSaveLogDialog.resx
Normal file
120
Switch_Toolbox_Library/Forms/Dialogs/STSaveLogDialog.resx
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
<?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>
|
||||||
|
</root>
|
@ -56,11 +56,17 @@ namespace Switch_Toolbox.Library.IO
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public void CheckByteOrderMark(uint ByteOrderMark)
|
public void CheckByteOrderMark(uint ByteOrderMark)
|
||||||
{
|
{
|
||||||
if (ByteOrderMark == 0xFEFF)
|
SetByteOrder(ByteOrderMark == 0xFEFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetByteOrder(bool IsBigEndian)
|
||||||
|
{
|
||||||
|
if (IsBigEndian)
|
||||||
ByteOrder = ByteOrder.BigEndian;
|
ByteOrder = ByteOrder.BigEndian;
|
||||||
else
|
else
|
||||||
ByteOrder = ByteOrder.LittleEndian;
|
ByteOrder = ByteOrder.LittleEndian;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ReadSignature(int length, string ExpectedSignature)
|
public string ReadSignature(int length, string ExpectedSignature)
|
||||||
{
|
{
|
||||||
string RealSignature = ReadString(length, Encoding.ASCII);
|
string RealSignature = ReadString(length, Encoding.ASCII);
|
||||||
@ -71,6 +77,7 @@ namespace Switch_Toolbox.Library.IO
|
|||||||
return RealSignature;
|
return RealSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public long ReadOffset(bool IsRelative, Type OffsetType)
|
public long ReadOffset(bool IsRelative, Type OffsetType)
|
||||||
{
|
{
|
||||||
long pos = Position;
|
long pos = Position;
|
||||||
|
@ -20,7 +20,7 @@ namespace Switch_Toolbox.Library.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
public FileWriter(string fileName)
|
public FileWriter(string fileName)
|
||||||
: this(new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Write))
|
: this(new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
public FileWriter(byte[] data)
|
public FileWriter(byte[] data)
|
||||||
@ -62,6 +62,14 @@ namespace Switch_Toolbox.Library.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetByteOrder(bool IsBigEndian)
|
||||||
|
{
|
||||||
|
if (IsBigEndian)
|
||||||
|
ByteOrder = ByteOrder.BigEndian;
|
||||||
|
else
|
||||||
|
ByteOrder = ByteOrder.LittleEndian;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// RelativeOffsetPosition controls the relative position the offset starts at
|
// RelativeOffsetPosition controls the relative position the offset starts at
|
||||||
//
|
//
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
using Syroot.BinaryData;
|
using Syroot.BinaryData;
|
||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Switch_Toolbox.Library.Forms;
|
||||||
|
|
||||||
namespace Switch_Toolbox.Library.IO
|
namespace Switch_Toolbox.Library.IO
|
||||||
{
|
{
|
||||||
@ -16,7 +18,7 @@ namespace Switch_Toolbox.Library.IO
|
|||||||
/// <param name="Alignment">The Alignment used for compression. Used for Yaz0 compression type. </param>
|
/// <param name="Alignment">The Alignment used for compression. Used for Yaz0 compression type. </param>
|
||||||
/// <param name="EnableDialog">Toggle for showing compression dialog</param>
|
/// <param name="EnableDialog">Toggle for showing compression dialog</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static void SaveFileFormat(IFileFormat FileFormat, string FileName, bool EnableDialog = true)
|
public static void SaveFileFormat(IFileFormat FileFormat, string FileName, bool EnableDialog = true, string DetailsLog = "")
|
||||||
{
|
{
|
||||||
//These always get created on loading a file,however not on creating a new file
|
//These always get created on loading a file,however not on creating a new file
|
||||||
if (FileFormat.IFileInfo == null)
|
if (FileFormat.IFileInfo == null)
|
||||||
@ -37,18 +39,71 @@ namespace Switch_Toolbox.Library.IO
|
|||||||
|
|
||||||
FileFormat.IFileInfo.CompressedSize = (uint)FinalData.Length;
|
FileFormat.IFileInfo.CompressedSize = (uint)FinalData.Length;
|
||||||
|
|
||||||
|
DetailsLog += "\n" + SatisfyFileTables(FileName, FinalData,
|
||||||
|
FileFormat.IFileInfo.DecompressedSize,
|
||||||
|
FileFormat.IFileInfo.CompressedSize,
|
||||||
|
FileFormat.IFileInfo.FileIsCompressed);
|
||||||
|
|
||||||
File.WriteAllBytes(FileName, FinalData);
|
File.WriteAllBytes(FileName, FinalData);
|
||||||
MessageBox.Show($"File has been saved to {FileName}");
|
STSaveLogDialog.Show($"File has been saved to {FileName}", "Save Notification", DetailsLog);
|
||||||
Cursor.Current = Cursors.Default;
|
Cursor.Current = Cursors.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string SatisfyFileTables(string FilePath, byte[] Data, uint DecompressedSize, uint CompressedSize, bool IsCompressed)
|
||||||
|
{
|
||||||
|
string FileLog = "";
|
||||||
|
|
||||||
|
bool IsBotwFile = FilePath.IsSubPathOf(Runtime.BotwGamePath);
|
||||||
|
bool IsTPHDFile = FilePath.IsSubPathOf(Runtime.TpGamePath);
|
||||||
|
|
||||||
|
if (Runtime.ResourceTables.BotwTable && IsBotwFile)
|
||||||
|
{
|
||||||
|
string newFilePath = FilePath.Replace(Runtime.BotwGamePath, string.Empty).Remove(0, 1);
|
||||||
|
newFilePath = newFilePath.Replace(".s", ".");
|
||||||
|
string RealExtension = Path.GetExtension(newFilePath).Replace(".s", ".");
|
||||||
|
|
||||||
|
string RstbPath = Path.Combine($"{Runtime.BotwGamePath}",
|
||||||
|
"System", "Resource", "ResourceSizeTable.product.srsizetable");
|
||||||
|
|
||||||
|
RSTB BotwResourceTable = new RSTB();
|
||||||
|
BotwResourceTable.LoadFile(RstbPath);
|
||||||
|
|
||||||
|
//Create a backup first if one doesn't exist
|
||||||
|
if (!File.Exists($"{RstbPath}.backup"))
|
||||||
|
{
|
||||||
|
BotwResourceTable.Write(new FileWriter($"{RstbPath}.backup"));
|
||||||
|
File.WriteAllBytes($"{RstbPath}.backup", EveryFileExplorer.YAZ0.Compress($"{RstbPath}.backup"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Now apply the file table then save the table
|
||||||
|
if (BotwResourceTable.IsInTable(newFilePath))
|
||||||
|
FileLog += $"File found in resource table! {newFilePath}";
|
||||||
|
else
|
||||||
|
FileLog += $"File NOT found in resource table! {newFilePath}";
|
||||||
|
|
||||||
|
BotwResourceTable.SetEntry(FilePath, Data);
|
||||||
|
BotwResourceTable.Write(new FileWriter(RstbPath));
|
||||||
|
File.WriteAllBytes(RstbPath, EveryFileExplorer.YAZ0.Compress(RstbPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Runtime.ResourceTables.TpTable && IsTPHDFile)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return FileLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void SaveFileFormat(byte[] data, bool FileIsCompressed, int Alignment,
|
public static void SaveFileFormat(byte[] data, bool FileIsCompressed, int Alignment,
|
||||||
CompressionType CompressionType, string FileName, bool EnableDialog = true)
|
CompressionType CompressionType, string FileName, bool EnableDialog = true, string DetailsLog = "")
|
||||||
{
|
{
|
||||||
Cursor.Current = Cursors.WaitCursor;
|
Cursor.Current = Cursors.WaitCursor;
|
||||||
byte[] FinalData = CompressFileFormat(data, FileIsCompressed, Alignment, CompressionType, FileName, EnableDialog);
|
byte[] FinalData = CompressFileFormat(data, FileIsCompressed, Alignment, CompressionType, FileName, EnableDialog);
|
||||||
File.WriteAllBytes(FileName, FinalData);
|
File.WriteAllBytes(FileName, FinalData);
|
||||||
MessageBox.Show($"File has been saved to {FileName}");
|
|
||||||
|
STSaveLogDialog.Show($"File has been saved to {FileName}", "Save Notification", DetailsLog);
|
||||||
Cursor.Current = Cursors.Default;
|
Cursor.Current = Cursors.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,11 +3,77 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace System
|
namespace System
|
||||||
{
|
{
|
||||||
public static class StringExtension
|
public static class StringExtension
|
||||||
{
|
{
|
||||||
|
//https://stackoverflow.com/questions/5617320/given-full-path-check-if-path-is-subdirectory-of-some-other-path-or-otherwise/31941159
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if <paramref name="path"/> starts with the path <paramref name="baseDirPath"/>.
|
||||||
|
/// The comparison is case-insensitive, handles / and \ slashes as folder separators and
|
||||||
|
/// only matches if the base dir folder name is matched exactly ("c:\foobar\file.txt" is not a sub path of "c:\foo").
|
||||||
|
/// </summary>
|
||||||
|
public static bool IsSubPathOf(this string path, string baseDirPath)
|
||||||
|
{
|
||||||
|
string normalizedPath = Path.GetFullPath(path.Replace('/', '\\')
|
||||||
|
.WithEnding("\\"));
|
||||||
|
|
||||||
|
string normalizedBaseDirPath = Path.GetFullPath(baseDirPath.Replace('/', '\\')
|
||||||
|
.WithEnding("\\"));
|
||||||
|
|
||||||
|
return normalizedPath.StartsWith(normalizedBaseDirPath, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns <paramref name="str"/> with the minimal concatenation of <paramref name="ending"/> (starting from end) that
|
||||||
|
/// results in satisfying .EndsWith(ending).
|
||||||
|
/// </summary>
|
||||||
|
/// <example>"hel".WithEnding("llo") returns "hello", which is the result of "hel" + "lo".</example>
|
||||||
|
public static string WithEnding( this string str, string ending)
|
||||||
|
{
|
||||||
|
if (str == null)
|
||||||
|
return ending;
|
||||||
|
|
||||||
|
string result = str;
|
||||||
|
|
||||||
|
// Right() is 1-indexed, so include these cases
|
||||||
|
// * Append no characters
|
||||||
|
// * Append up to N characters, where N is ending length
|
||||||
|
for (int i = 0; i <= ending.Length; i++)
|
||||||
|
{
|
||||||
|
string tmp = result + ending.Right(i);
|
||||||
|
if (tmp.EndsWith(ending))
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Gets the rightmost <paramref name="length" /> characters from a string.</summary>
|
||||||
|
/// <param name="value">The string to retrieve the substring from.</param>
|
||||||
|
/// <param name="length">The number of characters to retrieve.</param>
|
||||||
|
/// <returns>The substring.</returns>
|
||||||
|
public static string Right( this string value, int length)
|
||||||
|
{
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("value");
|
||||||
|
}
|
||||||
|
if (length < 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException("length", length, "Length is less than zero");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (length < value.Length) ? value.Substring(value.Length - length) : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string Strip(this string value)
|
||||||
|
{
|
||||||
|
return value.Replace(" ", string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
public static string Repeat(this string value, int count)
|
public static string Repeat(this string value, int count)
|
||||||
{
|
{
|
||||||
return new StringBuilder(value.Length * count).Insert(0, value, count).ToString();
|
return new StringBuilder(value.Length * count).Insert(0, value, count).ToString();
|
||||||
|
@ -730,6 +730,16 @@ namespace Switch_Toolbox.Library.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized resource of type System.Byte[].
|
||||||
|
/// </summary>
|
||||||
|
public static byte[] resource_factory_info {
|
||||||
|
get {
|
||||||
|
object obj = ResourceManager.GetObject("resource_factory_info", resourceCulture);
|
||||||
|
return ((byte[])(obj));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -373,4 +373,7 @@
|
|||||||
<data name="materialSphereTransparent" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
<data name="materialSphereTransparent" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
<value>..\Resources\materialSphereTransparent.tif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
<value>..\Resources\materialSphereTransparent.tif;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="resource_factory_info" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||||
|
<value>..\Resources\resource_factory_info.tsv;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
56
Switch_Toolbox_Library/Resources/resource_factory_info.tsv
Normal file
56
Switch_Toolbox_Library/Resources/resource_factory_info.tsv
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
name size_nx size_wiiu alignment parse_size_nx parse_size_wiiu other_extensions multiplier constant subsystem details
|
||||||
|
BASE 0x20 0x14 8 0 0 1 0 General
|
||||||
|
* 0x38 0x20 4 0 0 Tex.bfres, Tex1.bfres, Tex2.bfres, Tex1.1.bfres, Tex1.2.bfres, Tex1.3.bfres, Tex1.4.bfres 1 0 General
|
||||||
|
sarc 0x68 0x3c 0x80 0 0 pack, bactorpack, bmodelsh, beventpack, stera, stats 1 0 General
|
||||||
|
bfres 0x1a8 0x13c 0x1000 complex complex 2.5 0x400000 General
|
||||||
|
bcamanim 0x50 0x2c 0x2000 complex complex 1 0x680 General 0x2f8 + graphics resources
|
||||||
|
batpl, bnfprl 0x40 0x24 4 0 0 1 0 General
|
||||||
|
bplacement 0x48 0x14 4 0 0 1 0 General
|
||||||
|
hks, lua 0x38 0x14 4 0 0 1 0 General
|
||||||
|
bactcapt 0x538 0x3b4 4 0 0 1 0x1000 ActorCaptureMgr
|
||||||
|
bitemico 0x60 0xd0 0x2000 0 0 1 0 UI
|
||||||
|
jpg 0x80 0x174 0x2000 0 0 1 0 UI
|
||||||
|
bmaptex 0x60 0xd0 0x2000 0 0 1 0 UI
|
||||||
|
bstftex 0x60 0xd0 0x2000 0 0 bmapopen, breviewtex 1 0 UI
|
||||||
|
bgdata 0x140 0xcc 4 0 0 5 0xc0000 GameData
|
||||||
|
bgsvdata 0x38 0x14 4 0 0 1 0x300000 GameData
|
||||||
|
hknm2 0x48 0x28 4 complex complex 1 0xb28 HavokAI
|
||||||
|
bmscdef 0x2a8 0x1fc 4 complex complex 1 0 Sound
|
||||||
|
bars 0xb0 0x84 0x80 complex complex 1 0 Sound allocates (0x18 + string data on heap) in some cases + 0xa8 and calls sead::ResourceMgr::create with the heap
|
||||||
|
bxml 0x778 0x4a8 4 complex complex 1 0x1000 ActorParam 0 or (4 * n) (depending on contents)
|
||||||
|
bgparamlist 0x2c0 0x248 4 complex complex 1 0xdb18 ActorParam complex. allocates depending on nodes that are present in the gparamlist
|
||||||
|
bmodellist 0x7d0 0x508 4 complex complex 2 0 ActorParam
|
||||||
|
baslist 0x410 0x2f4 4 complex complex 0 0x80000 ActorParam
|
||||||
|
baiprog 0x448 0x30c 4 complex complex 1 0x300000 ActorParam
|
||||||
|
bphysics 0x470 0x324 4 complex complex 6 0 ActorParam
|
||||||
|
bchemical 0x3c0 0x2cc 4 complex complex 0 0x2000 ActorParam
|
||||||
|
bas 0x3c8 0x2d0 4 complex complex 0 0x80000 ActorParam
|
||||||
|
batcllist 0x3f0 0x2e4 4 0 0 1 0x2000 ActorParam
|
||||||
|
batcl 0x428 0x344 4 complex complex 1 0x2000 ActorParam
|
||||||
|
baischedule 0x2b8 0x244 4 0 0 1 0x800 ActorParam
|
||||||
|
bdmgparam 0x11d0 0x9f0 4 0x790 0x3c0 1 0x20000 ActorParam
|
||||||
|
brgconfiglist 0x3d0 0x2d4 4 complex complex 1 0x2000 ActorParam
|
||||||
|
brgconfig 0x42d8 0x2acc 4 0 0 1 0x20000 ActorParam
|
||||||
|
brgbw 0x2c0 0x248 4 complex complex 1 0x20000 ActorParam
|
||||||
|
bawareness 0xb38 0x70c 4 0 0 1 0 ActorParam
|
||||||
|
bdrop 0x320 0x27c 4 complex complex 1 0x5000 ActorParam
|
||||||
|
bshop 0x320 0x27c 4 complex complex 1 0x20000 ActorParam
|
||||||
|
brecipe 0x320 0x27c 4 complex complex 1 0x20000 ActorParam
|
||||||
|
blod 0x3c0 0x2cc 4 0 0 1 0x20000 ActorParam
|
||||||
|
bbonectrl 0x8d0 0x564 4 complex complex 1 0x40000 ActorParam
|
||||||
|
blifecondition 0x4b0 0x35c 4 complex complex 1 0x20000 ActorParam
|
||||||
|
bumii 0x2b8 0x244 4 0 0 1 0 ActorParam
|
||||||
|
baniminfo 0x2c8 0x24c 4 complex complex 1.5 0 ActorParam
|
||||||
|
byaml 0x20 0x14 4 0 0 1 0 ActorParam
|
||||||
|
bassetting 0x260 0x1d8 4 complex complex 0 0x80000 ActorParam
|
||||||
|
hkrb 0x20 0x14 4 0 0 1 0x400 Physics
|
||||||
|
hkrg 0x20 0x14 4 0 0 1 0x400 Physics
|
||||||
|
bphyssb 0x5b0 0x384 4 complex complex 1 0x100000 Physics
|
||||||
|
hkcl 0xe8 0xb8 4 complex complex 2 0x2800 Physics
|
||||||
|
hksc 0x140 0xe8 4 complex complex 1.3 0x40000 Physics
|
||||||
|
hktmrb 0x48 0x28 4 complex complex 1 0x800 Physics
|
||||||
|
brgcon 0x48 0x28 4 complex complex 1 0x4000 Physics
|
||||||
|
esetlist 0x38 0x20 0x4000 0 0 1 0 Effect
|
||||||
|
bdemo 0xb20 0x6cc 4 0 0 1 0xb20 Event
|
||||||
|
bfevfl 0x40 0x24 4 0 0 1 0x40 Event
|
||||||
|
bfevtm 0x40 0x24 4 0 0 1 0x40 Event
|
|
@ -15,6 +15,12 @@ namespace Switch_Toolbox.Library
|
|||||||
|
|
||||||
public class Runtime
|
public class Runtime
|
||||||
{
|
{
|
||||||
|
public static class ResourceTables
|
||||||
|
{
|
||||||
|
public static bool TpTable = false;
|
||||||
|
public static bool BotwTable = false;
|
||||||
|
}
|
||||||
|
|
||||||
public static string Mk8GamePath = "";
|
public static string Mk8GamePath = "";
|
||||||
public static string Mk8dGamePath = "";
|
public static string Mk8dGamePath = "";
|
||||||
public static string SmoGamePath = "";
|
public static string SmoGamePath = "";
|
||||||
|
@ -50,6 +50,9 @@
|
|||||||
<HintPath>..\Toolbox\Lib\CSCore.dll</HintPath>
|
<HintPath>..\Toolbox\Lib\CSCore.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="CsvHelper">
|
||||||
|
<HintPath>..\Toolbox\Lib\CsvHelper.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
<Reference Include="Cyotek.Windows.Forms.ImageBox">
|
<Reference Include="Cyotek.Windows.Forms.ImageBox">
|
||||||
<HintPath>..\Toolbox\Lib\Cyotek.Windows.Forms.ImageBox.dll</HintPath>
|
<HintPath>..\Toolbox\Lib\Cyotek.Windows.Forms.ImageBox.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
@ -220,6 +223,8 @@
|
|||||||
<Compile Include="FileFormats\DAE\DAE.cs" />
|
<Compile Include="FileFormats\DAE\DAE.cs" />
|
||||||
<Compile Include="FileFormats\OBJ.cs" />
|
<Compile Include="FileFormats\OBJ.cs" />
|
||||||
<Compile Include="FileFormats\R4G4.cs" />
|
<Compile Include="FileFormats\R4G4.cs" />
|
||||||
|
<Compile Include="FileFormats\SizeTables\RSTB.cs" />
|
||||||
|
<Compile Include="FileFormats\SizeTables\TPFileSizeTable.cs" />
|
||||||
<Compile Include="Forms\Archive\ArchiveFilePanel.cs">
|
<Compile Include="Forms\Archive\ArchiveFilePanel.cs">
|
||||||
<SubType>UserControl</SubType>
|
<SubType>UserControl</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -244,6 +249,12 @@
|
|||||||
<Compile Include="Forms\Dialogs\ExportModelSettings.Designer.cs">
|
<Compile Include="Forms\Dialogs\ExportModelSettings.Designer.cs">
|
||||||
<DependentUpon>ExportModelSettings.cs</DependentUpon>
|
<DependentUpon>ExportModelSettings.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Forms\Dialogs\STSaveLogDialog.cs">
|
||||||
|
<SubType>Form</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Forms\Dialogs\STSaveLogDialog.Designer.cs">
|
||||||
|
<DependentUpon>STSaveLogDialog.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Forms\Editors\Animation\BoneAnimTimeline.cs">
|
<Compile Include="Forms\Editors\Animation\BoneAnimTimeline.cs">
|
||||||
<SubType>UserControl</SubType>
|
<SubType>UserControl</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -733,6 +744,9 @@
|
|||||||
<EmbeddedResource Include="Forms\Dialogs\ExportModelSettings.resx">
|
<EmbeddedResource Include="Forms\Dialogs\ExportModelSettings.resx">
|
||||||
<DependentUpon>ExportModelSettings.cs</DependentUpon>
|
<DependentUpon>ExportModelSettings.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
|
<EmbeddedResource Include="Forms\Dialogs\STSaveLogDialog.resx">
|
||||||
|
<DependentUpon>STSaveLogDialog.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Forms\Dialogs\STOptionsDialog.resx">
|
<EmbeddedResource Include="Forms\Dialogs\STOptionsDialog.resx">
|
||||||
<DependentUpon>STOptionsDialog.cs</DependentUpon>
|
<DependentUpon>STOptionsDialog.cs</DependentUpon>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
@ -896,6 +910,7 @@
|
|||||||
<None Include="Resources\mesh.png" />
|
<None Include="Resources\mesh.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Include="Resources\resource_factory_info.tsv" />
|
||||||
<None Include="Resources\skeletonAnimation.png" />
|
<None Include="Resources\skeletonAnimation.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
79
Toolbox/GUI/Settings.Designer.cs
generated
79
Toolbox/GUI/Settings.Designer.cs
generated
@ -34,6 +34,7 @@
|
|||||||
this.chkBoxNormalMap = new Switch_Toolbox.Library.Forms.STCheckBox();
|
this.chkBoxNormalMap = new Switch_Toolbox.Library.Forms.STCheckBox();
|
||||||
this.shadingComboBox = new System.Windows.Forms.ComboBox();
|
this.shadingComboBox = new System.Windows.Forms.ComboBox();
|
||||||
this.panel2 = new Switch_Toolbox.Library.Forms.STPanel();
|
this.panel2 = new Switch_Toolbox.Library.Forms.STPanel();
|
||||||
|
this.uvChannelRB3 = new System.Windows.Forms.RadioButton();
|
||||||
this.uvChannelRB2 = new System.Windows.Forms.RadioButton();
|
this.uvChannelRB2 = new System.Windows.Forms.RadioButton();
|
||||||
this.uvChannelRB = new System.Windows.Forms.RadioButton();
|
this.uvChannelRB = new System.Windows.Forms.RadioButton();
|
||||||
this.displayBoundingBoxeChk = new Switch_Toolbox.Library.Forms.STCheckBox();
|
this.displayBoundingBoxeChk = new Switch_Toolbox.Library.Forms.STCheckBox();
|
||||||
@ -112,7 +113,10 @@
|
|||||||
this.chkUseSkyobx = new Switch_Toolbox.Library.Forms.STCheckBox();
|
this.chkUseSkyobx = new Switch_Toolbox.Library.Forms.STCheckBox();
|
||||||
this.stLabel15 = new Switch_Toolbox.Library.Forms.STLabel();
|
this.stLabel15 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||||
this.specularCubemapPathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
this.specularCubemapPathTB = new Switch_Toolbox.Library.Forms.STTextBox();
|
||||||
this.uvChannelRB3 = new System.Windows.Forms.RadioButton();
|
this.tabPage5 = new System.Windows.Forms.TabPage();
|
||||||
|
this.chkTpFileTable = new Switch_Toolbox.Library.Forms.STCheckBox();
|
||||||
|
this.stLabel17 = new Switch_Toolbox.Library.Forms.STLabel();
|
||||||
|
this.chkBotwFileTable = new Switch_Toolbox.Library.Forms.STCheckBox();
|
||||||
this.contentContainer.SuspendLayout();
|
this.contentContainer.SuspendLayout();
|
||||||
this.panel2.SuspendLayout();
|
this.panel2.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.cameraMaxSpeedUD)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.cameraMaxSpeedUD)).BeginInit();
|
||||||
@ -135,6 +139,7 @@
|
|||||||
this.tabPage3.SuspendLayout();
|
this.tabPage3.SuspendLayout();
|
||||||
this.stContextMenuStrip1.SuspendLayout();
|
this.stContextMenuStrip1.SuspendLayout();
|
||||||
this.tabPage4.SuspendLayout();
|
this.tabPage4.SuspendLayout();
|
||||||
|
this.tabPage5.SuspendLayout();
|
||||||
this.SuspendLayout();
|
this.SuspendLayout();
|
||||||
//
|
//
|
||||||
// contentContainer
|
// contentContainer
|
||||||
@ -228,6 +233,18 @@
|
|||||||
this.panel2.Size = new System.Drawing.Size(534, 293);
|
this.panel2.Size = new System.Drawing.Size(534, 293);
|
||||||
this.panel2.TabIndex = 4;
|
this.panel2.TabIndex = 4;
|
||||||
//
|
//
|
||||||
|
// uvChannelRB3
|
||||||
|
//
|
||||||
|
this.uvChannelRB3.AutoSize = true;
|
||||||
|
this.uvChannelRB3.Location = new System.Drawing.Point(477, 54);
|
||||||
|
this.uvChannelRB3.Name = "uvChannelRB3";
|
||||||
|
this.uvChannelRB3.Size = new System.Drawing.Size(49, 17);
|
||||||
|
this.uvChannelRB3.TabIndex = 34;
|
||||||
|
this.uvChannelRB3.TabStop = true;
|
||||||
|
this.uvChannelRB3.Text = "UV 3";
|
||||||
|
this.uvChannelRB3.UseVisualStyleBackColor = true;
|
||||||
|
this.uvChannelRB3.CheckedChanged += new System.EventHandler(this.uvChannelRB3_CheckedChanged);
|
||||||
|
//
|
||||||
// uvChannelRB2
|
// uvChannelRB2
|
||||||
//
|
//
|
||||||
this.uvChannelRB2.AutoSize = true;
|
this.uvChannelRB2.AutoSize = true;
|
||||||
@ -791,6 +808,7 @@
|
|||||||
this.stTabControl1.Controls.Add(this.tabPage2);
|
this.stTabControl1.Controls.Add(this.tabPage2);
|
||||||
this.stTabControl1.Controls.Add(this.tabPage3);
|
this.stTabControl1.Controls.Add(this.tabPage3);
|
||||||
this.stTabControl1.Controls.Add(this.tabPage4);
|
this.stTabControl1.Controls.Add(this.tabPage4);
|
||||||
|
this.stTabControl1.Controls.Add(this.tabPage5);
|
||||||
this.stTabControl1.Location = new System.Drawing.Point(0, 25);
|
this.stTabControl1.Location = new System.Drawing.Point(0, 25);
|
||||||
this.stTabControl1.myBackColor = System.Drawing.Color.Empty;
|
this.stTabControl1.myBackColor = System.Drawing.Color.Empty;
|
||||||
this.stTabControl1.Name = "stTabControl1";
|
this.stTabControl1.Name = "stTabControl1";
|
||||||
@ -1187,17 +1205,50 @@
|
|||||||
this.specularCubemapPathTB.Click += new System.EventHandler(this.cubemapPathTB_Click);
|
this.specularCubemapPathTB.Click += new System.EventHandler(this.cubemapPathTB_Click);
|
||||||
this.specularCubemapPathTB.TextChanged += new System.EventHandler(this.specularCubemapPathTB_TextChanged);
|
this.specularCubemapPathTB.TextChanged += new System.EventHandler(this.specularCubemapPathTB_TextChanged);
|
||||||
//
|
//
|
||||||
// uvChannelRB3
|
// tabPage5
|
||||||
//
|
//
|
||||||
this.uvChannelRB3.AutoSize = true;
|
this.tabPage5.Controls.Add(this.chkTpFileTable);
|
||||||
this.uvChannelRB3.Location = new System.Drawing.Point(477, 54);
|
this.tabPage5.Controls.Add(this.stLabel17);
|
||||||
this.uvChannelRB3.Name = "uvChannelRB3";
|
this.tabPage5.Controls.Add(this.chkBotwFileTable);
|
||||||
this.uvChannelRB3.Size = new System.Drawing.Size(49, 17);
|
this.tabPage5.Location = new System.Drawing.Point(4, 25);
|
||||||
this.uvChannelRB3.TabIndex = 34;
|
this.tabPage5.Name = "tabPage5";
|
||||||
this.uvChannelRB3.TabStop = true;
|
this.tabPage5.Padding = new System.Windows.Forms.Padding(3);
|
||||||
this.uvChannelRB3.Text = "UV 3";
|
this.tabPage5.Size = new System.Drawing.Size(541, 395);
|
||||||
this.uvChannelRB3.UseVisualStyleBackColor = true;
|
this.tabPage5.TabIndex = 4;
|
||||||
this.uvChannelRB3.CheckedChanged += new System.EventHandler(this.uvChannelRB3_CheckedChanged);
|
this.tabPage5.Text = "File Size Tables";
|
||||||
|
this.tabPage5.UseVisualStyleBackColor = true;
|
||||||
|
//
|
||||||
|
// chkTpFileTable
|
||||||
|
//
|
||||||
|
this.chkTpFileTable.AutoSize = true;
|
||||||
|
this.chkTpFileTable.Location = new System.Drawing.Point(17, 84);
|
||||||
|
this.chkTpFileTable.Name = "chkTpFileTable";
|
||||||
|
this.chkTpFileTable.Size = new System.Drawing.Size(178, 17);
|
||||||
|
this.chkTpFileTable.TabIndex = 3;
|
||||||
|
this.chkTpFileTable.Text = "Twilight Princess HD File Tables";
|
||||||
|
this.chkTpFileTable.UseVisualStyleBackColor = true;
|
||||||
|
this.chkTpFileTable.CheckedChanged += new System.EventHandler(this.chkTpFileTable_CheckedChanged);
|
||||||
|
//
|
||||||
|
// stLabel17
|
||||||
|
//
|
||||||
|
this.stLabel17.AutoSize = true;
|
||||||
|
this.stLabel17.Location = new System.Drawing.Point(25, 11);
|
||||||
|
this.stLabel17.Name = "stLabel17";
|
||||||
|
this.stLabel17.Size = new System.Drawing.Size(558, 13);
|
||||||
|
this.stLabel17.TabIndex = 2;
|
||||||
|
this.stLabel17.Text = "These options can prevent file size restrictions. Check these if you want them t" +
|
||||||
|
"o be adjusted when a file gets saved. ";
|
||||||
|
//
|
||||||
|
// chkBotwFileTable
|
||||||
|
//
|
||||||
|
this.chkBotwFileTable.AutoSize = true;
|
||||||
|
this.chkBotwFileTable.Location = new System.Drawing.Point(17, 61);
|
||||||
|
this.chkBotwFileTable.Name = "chkBotwFileTable";
|
||||||
|
this.chkBotwFileTable.Size = new System.Drawing.Size(195, 17);
|
||||||
|
this.chkBotwFileTable.TabIndex = 0;
|
||||||
|
this.chkBotwFileTable.Text = "BOTW Resource File Table (RSTB)";
|
||||||
|
this.chkBotwFileTable.UseVisualStyleBackColor = true;
|
||||||
|
this.chkBotwFileTable.CheckedChanged += new System.EventHandler(this.chkBotwFileTable_CheckedChanged);
|
||||||
//
|
//
|
||||||
// Settings
|
// Settings
|
||||||
//
|
//
|
||||||
@ -1237,6 +1288,8 @@
|
|||||||
this.stContextMenuStrip1.ResumeLayout(false);
|
this.stContextMenuStrip1.ResumeLayout(false);
|
||||||
this.tabPage4.ResumeLayout(false);
|
this.tabPage4.ResumeLayout(false);
|
||||||
this.tabPage4.PerformLayout();
|
this.tabPage4.PerformLayout();
|
||||||
|
this.tabPage5.ResumeLayout(false);
|
||||||
|
this.tabPage5.PerformLayout();
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1327,5 +1380,9 @@
|
|||||||
private System.Windows.Forms.RadioButton uvChannelRB2;
|
private System.Windows.Forms.RadioButton uvChannelRB2;
|
||||||
private System.Windows.Forms.RadioButton uvChannelRB;
|
private System.Windows.Forms.RadioButton uvChannelRB;
|
||||||
private System.Windows.Forms.RadioButton uvChannelRB3;
|
private System.Windows.Forms.RadioButton uvChannelRB3;
|
||||||
|
private System.Windows.Forms.TabPage tabPage5;
|
||||||
|
private Switch_Toolbox.Library.Forms.STCheckBox chkTpFileTable;
|
||||||
|
private Switch_Toolbox.Library.Forms.STLabel stLabel17;
|
||||||
|
private Switch_Toolbox.Library.Forms.STCheckBox chkBotwFileTable;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -85,6 +85,8 @@ namespace Toolbox
|
|||||||
chkUseSkyobx.Checked = Runtime.PBR.UseSkybox;
|
chkUseSkyobx.Checked = Runtime.PBR.UseSkybox;
|
||||||
chkDiffyseSkybox.Checked = Runtime.PBR.UseDiffuseSkyTexture;
|
chkDiffyseSkybox.Checked = Runtime.PBR.UseDiffuseSkyTexture;
|
||||||
chkDiffyseSkybox.Enabled = chkUseSkyobx.Checked;
|
chkDiffyseSkybox.Enabled = chkUseSkyobx.Checked;
|
||||||
|
chkBotwFileTable.Checked = Runtime.ResourceTables.BotwTable;
|
||||||
|
chkTpFileTable.Checked = Runtime.ResourceTables.TpTable;
|
||||||
|
|
||||||
displayBoundingBoxeChk.Checked = Runtime.renderBoundingBoxes;
|
displayBoundingBoxeChk.Checked = Runtime.renderBoundingBoxes;
|
||||||
|
|
||||||
@ -450,8 +452,11 @@ namespace Toolbox
|
|||||||
FolderSelectDialog sfd = new FolderSelectDialog();
|
FolderSelectDialog sfd = new FolderSelectDialog();
|
||||||
if (sfd.ShowDialog() == DialogResult.OK)
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
{
|
{
|
||||||
SMOPathTB.Text = sfd.SelectedPath;
|
if (!IsValidBotwDirectory(sfd.SelectedPath))
|
||||||
Runtime.BotwGamePath = SMOPathTB.Text;
|
throw new Exception("Invalid path choosen. Make sure you have atleast an RSTB file in the path! |System/Resource/ResourceSizeTable.product.srsizetable|");
|
||||||
|
|
||||||
|
botwGamePathTB.Text = sfd.SelectedPath;
|
||||||
|
Runtime.BotwGamePath = botwGamePathTB.Text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,5 +597,36 @@ namespace Toolbox
|
|||||||
Runtime.uvChannel = Runtime.UVChannel.Channel3;
|
Runtime.uvChannel = Runtime.UVChannel.Channel3;
|
||||||
UpdateViewportSettings();
|
UpdateViewportSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void chkBotwFileTable_CheckedChanged(object sender, EventArgs e) {
|
||||||
|
if (!System.IO.Directory.Exists(Runtime.BotwGamePath) || !IsValidBotwDirectory(Runtime.BotwGamePath))
|
||||||
|
{
|
||||||
|
FolderSelectDialog sfd = new FolderSelectDialog();
|
||||||
|
sfd.Title = "Select Modded Game Path!!!";
|
||||||
|
if (sfd.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
|
if (!IsValidBotwDirectory(sfd.SelectedPath))
|
||||||
|
throw new Exception($"Invalid path choosen. Make sure you have atleast an RSTB file in the path! |{sfd.SelectedPath}/System/Resource/ResourceSizeTable.product.srsizetable|");
|
||||||
|
|
||||||
|
botwGamePathTB.Text = sfd.SelectedPath;
|
||||||
|
Runtime.BotwGamePath = botwGamePathTB.Text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Runtime.ResourceTables.BotwTable = chkBotwFileTable.Checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsValidBotwDirectory(string GamePath)
|
||||||
|
{
|
||||||
|
//This is the only file i care about
|
||||||
|
string RstbPath = System.IO.Path.Combine($"{GamePath}",
|
||||||
|
"System", "Resource", "ResourceSizeTable.product.srsizetable");
|
||||||
|
|
||||||
|
return System.IO.File.Exists(RstbPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void chkTpFileTable_CheckedChanged(object sender, EventArgs e) {
|
||||||
|
Runtime.ResourceTables.TpTable = chkTpFileTable.Checked;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user