1
0
mirror of synced 2024-11-27 17:00:50 +01:00

Tons more RSTB progress (Note file in archives don't work yet)

This commit is contained in:
KillzXGaming 2019-06-11 15:39:23 -04:00
parent 7aa040aebf
commit 41adcfffc1
35 changed files with 1087 additions and 147 deletions

Binary file not shown.

View File

@ -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;
}
}
}

View 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
1 name size_nx size_wiiu alignment parse_size_nx parse_size_wiiu other_extensions multiplier constant subsystem details
2 BASE 0x20 0x14 8 0 0 1 0 General
3 * 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
4 sarc 0x68 0x3c 0x80 0 0 pack, bactorpack, bmodelsh, beventpack, stera, stats 1 0 General
5 bfres 0x1a8 0x13c 0x1000 complex complex 2.5 0x400000 General
6 bcamanim 0x50 0x2c 0x2000 complex complex 1 0x680 General 0x2f8 + graphics resources
7 batpl, bnfprl 0x40 0x24 4 0 0 1 0 General
8 bplacement 0x48 0x14 4 0 0 1 0 General
9 hks, lua 0x38 0x14 4 0 0 1 0 General
10 bactcapt 0x538 0x3b4 4 0 0 1 0x1000 ActorCaptureMgr
11 bitemico 0x60 0xd0 0x2000 0 0 1 0 UI
12 jpg 0x80 0x174 0x2000 0 0 1 0 UI
13 bmaptex 0x60 0xd0 0x2000 0 0 1 0 UI
14 bstftex 0x60 0xd0 0x2000 0 0 bmapopen, breviewtex 1 0 UI
15 bgdata 0x140 0xcc 4 0 0 5 0xc0000 GameData
16 bgsvdata 0x38 0x14 4 0 0 1 0x300000 GameData
17 hknm2 0x48 0x28 4 complex complex 1 0xb28 HavokAI
18 bmscdef 0x2a8 0x1fc 4 complex complex 1 0 Sound
19 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
20 bxml 0x778 0x4a8 4 complex complex 1 0x1000 ActorParam 0 or (4 * n) (depending on contents)
21 bgparamlist 0x2c0 0x248 4 complex complex 1 0xdb18 ActorParam complex. allocates depending on nodes that are present in the gparamlist
22 bmodellist 0x7d0 0x508 4 complex complex 2 0 ActorParam
23 baslist 0x410 0x2f4 4 complex complex 0 0x80000 ActorParam
24 baiprog 0x448 0x30c 4 complex complex 1 0x300000 ActorParam
25 bphysics 0x470 0x324 4 complex complex 6 0 ActorParam
26 bchemical 0x3c0 0x2cc 4 complex complex 0 0x2000 ActorParam
27 bas 0x3c8 0x2d0 4 complex complex 0 0x80000 ActorParam
28 batcllist 0x3f0 0x2e4 4 0 0 1 0x2000 ActorParam
29 batcl 0x428 0x344 4 complex complex 1 0x2000 ActorParam
30 baischedule 0x2b8 0x244 4 0 0 1 0x800 ActorParam
31 bdmgparam 0x11d0 0x9f0 4 0x790 0x3c0 1 0x20000 ActorParam
32 brgconfiglist 0x3d0 0x2d4 4 complex complex 1 0x2000 ActorParam
33 brgconfig 0x42d8 0x2acc 4 0 0 1 0x20000 ActorParam
34 brgbw 0x2c0 0x248 4 complex complex 1 0x20000 ActorParam
35 bawareness 0xb38 0x70c 4 0 0 1 0 ActorParam
36 bdrop 0x320 0x27c 4 complex complex 1 0x5000 ActorParam
37 bshop 0x320 0x27c 4 complex complex 1 0x20000 ActorParam
38 brecipe 0x320 0x27c 4 complex complex 1 0x20000 ActorParam
39 blod 0x3c0 0x2cc 4 0 0 1 0x20000 ActorParam
40 bbonectrl 0x8d0 0x564 4 complex complex 1 0x40000 ActorParam
41 blifecondition 0x4b0 0x35c 4 complex complex 1 0x20000 ActorParam
42 bumii 0x2b8 0x244 4 0 0 1 0 ActorParam
43 baniminfo 0x2c8 0x24c 4 complex complex 1.5 0 ActorParam
44 byaml 0x20 0x14 4 0 0 1 0 ActorParam
45 bassetting 0x260 0x1d8 4 complex complex 0 0x80000 ActorParam
46 hkrb 0x20 0x14 4 0 0 1 0x400 Physics
47 hkrg 0x20 0x14 4 0 0 1 0x400 Physics
48 bphyssb 0x5b0 0x384 4 complex complex 1 0x100000 Physics
49 hkcl 0xe8 0xb8 4 complex complex 2 0x2800 Physics
50 hksc 0x140 0xe8 4 complex complex 1.3 0x40000 Physics
51 hktmrb 0x48 0x28 4 complex complex 1 0x800 Physics
52 brgcon 0x48 0x28 4 complex complex 1 0x4000 Physics
53 esetlist 0x38 0x20 0x4000 0 0 1 0 Effect
54 bdemo 0xb20 0x6cc 4 0 0 1 0xb20 Event
55 bfevfl 0x40 0x24 4 0 0 1 0x40 Event
56 bfevtm 0x40 0x24 4 0 0 1 0x40 Event

View File

@ -76,6 +76,10 @@
<HintPath>..\Toolbox\Lib\CSCore.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="CsvHelper">
<HintPath>..\Toolbox\Lib\CsvHelper.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="EditorCoreCommon">
<HintPath>..\Toolbox\Lib\EditorCoreCommon.dll</HintPath>
<Private>False</Private>
@ -234,12 +238,10 @@
<Compile Include="FileFormats\Audio\Archives\BFGRP.cs" />
<Compile Include="FileFormats\GFBMDL\GFBMDL.cs" />
<Compile Include="FileFormats\Hashes\SAHT.cs" />
<Compile Include="FileFormats\SizeTables\RSTB.cs" />
<Compile Include="FileFormats\Shader\NSWShaderDecompile.cs" />
<Compile Include="FileFormats\Shader\NUSHDB.cs" />
<Compile Include="FileFormats\Shader\NVNSH.cs" />
<Compile Include="FileFormats\Shader\SHARCFBNX.cs" />
<Compile Include="FileFormats\SizeTables\TPFileSizeTable.cs" />
<Compile Include="FileFormats\Texture\BCLIM.cs" />
<Compile Include="FileFormats\Texture\BFLIM.cs" />
<Compile Include="FileFormats\Layout\BFLAN.cs" />
@ -1211,6 +1213,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="Resources\resource_factory_info.tsv" />
<None Include="Resources\TextureError.png" />
</ItemGroup>
<ItemGroup>

View File

@ -1 +1 @@
a5f8e3bc83ca333f1641f1a9eb9720cb2bff4cb6
81115f490d097ea68b62b86788a8bc08ded17c3e

View File

@ -216,6 +216,12 @@ namespace Switch_Toolbox.Library
Enum.TryParse(node.InnerText, out cameraMode);
Runtime.ViewportCameraMode = cameraMode;
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);
AppendGridSettings(doc, mainNode);
AppenPBRSettings(doc, mainNode);
AppendResourceTableSettings(doc, mainNode);
return doc;
}
@ -407,6 +414,14 @@ namespace Switch_Toolbox.Library
renderSettingsNode.AppendChild(createNode(doc, "bonePointSize", Runtime.bonePointSize.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)
{

View 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;
}
}
}
}

View File

@ -7,7 +7,7 @@ using Switch_Toolbox.Library.IO;
using Switch_Toolbox.Library;
using Syroot.BinaryData;
namespace FirstPlugin
namespace Switch_Toolbox.Library
{
public class TPFileSizeTable
{

View File

@ -226,7 +226,6 @@ namespace BarSlider
}
}
private void OnMouseUp(object sender, MouseEventArgs e)
{
if (TextEditorActive)

View 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;
}
}

View 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);
}
}
}

View 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>

View File

@ -56,11 +56,17 @@ namespace Switch_Toolbox.Library.IO
/// <returns></returns>
public void CheckByteOrderMark(uint ByteOrderMark)
{
if (ByteOrderMark == 0xFEFF)
SetByteOrder(ByteOrderMark == 0xFEFF);
}
public void SetByteOrder(bool IsBigEndian)
{
if (IsBigEndian)
ByteOrder = ByteOrder.BigEndian;
else
ByteOrder = ByteOrder.LittleEndian;
}
public string ReadSignature(int length, string ExpectedSignature)
{
string RealSignature = ReadString(length, Encoding.ASCII);
@ -71,6 +77,7 @@ namespace Switch_Toolbox.Library.IO
return RealSignature;
}
public long ReadOffset(bool IsRelative, Type OffsetType)
{
long pos = Position;

View File

@ -20,7 +20,7 @@ namespace Switch_Toolbox.Library.IO
}
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)
@ -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
//

View File

@ -1,8 +1,10 @@
using Syroot.BinaryData;
using System;
using System.IO;
using System.IO.Compression;
using OpenTK;
using System.Windows.Forms;
using Switch_Toolbox.Library.Forms;
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="EnableDialog">Toggle for showing compression dialog</param>
/// <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
if (FileFormat.IFileInfo == null)
@ -37,18 +39,71 @@ namespace Switch_Toolbox.Library.IO
FileFormat.IFileInfo.CompressedSize = (uint)FinalData.Length;
DetailsLog += "\n" + SatisfyFileTables(FileName, FinalData,
FileFormat.IFileInfo.DecompressedSize,
FileFormat.IFileInfo.CompressedSize,
FileFormat.IFileInfo.FileIsCompressed);
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;
}
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,
CompressionType CompressionType, string FileName, bool EnableDialog = true)
CompressionType CompressionType, string FileName, bool EnableDialog = true, string DetailsLog = "")
{
Cursor.Current = Cursors.WaitCursor;
byte[] FinalData = CompressFileFormat(data, FileIsCompressed, Alignment, CompressionType, FileName, EnableDialog);
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;
}

View File

@ -3,11 +3,77 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace System
{
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)
{
return new StringBuilder(value.Length * count).Insert(0, value, count).ToString();

View File

@ -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>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View File

@ -373,4 +373,7 @@
<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>
</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>

View 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
1 name size_nx size_wiiu alignment parse_size_nx parse_size_wiiu other_extensions multiplier constant subsystem details
2 BASE 0x20 0x14 8 0 0 1 0 General
3 * 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
4 sarc 0x68 0x3c 0x80 0 0 pack, bactorpack, bmodelsh, beventpack, stera, stats 1 0 General
5 bfres 0x1a8 0x13c 0x1000 complex complex 2.5 0x400000 General
6 bcamanim 0x50 0x2c 0x2000 complex complex 1 0x680 General 0x2f8 + graphics resources
7 batpl, bnfprl 0x40 0x24 4 0 0 1 0 General
8 bplacement 0x48 0x14 4 0 0 1 0 General
9 hks, lua 0x38 0x14 4 0 0 1 0 General
10 bactcapt 0x538 0x3b4 4 0 0 1 0x1000 ActorCaptureMgr
11 bitemico 0x60 0xd0 0x2000 0 0 1 0 UI
12 jpg 0x80 0x174 0x2000 0 0 1 0 UI
13 bmaptex 0x60 0xd0 0x2000 0 0 1 0 UI
14 bstftex 0x60 0xd0 0x2000 0 0 bmapopen, breviewtex 1 0 UI
15 bgdata 0x140 0xcc 4 0 0 5 0xc0000 GameData
16 bgsvdata 0x38 0x14 4 0 0 1 0x300000 GameData
17 hknm2 0x48 0x28 4 complex complex 1 0xb28 HavokAI
18 bmscdef 0x2a8 0x1fc 4 complex complex 1 0 Sound
19 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
20 bxml 0x778 0x4a8 4 complex complex 1 0x1000 ActorParam 0 or (4 * n) (depending on contents)
21 bgparamlist 0x2c0 0x248 4 complex complex 1 0xdb18 ActorParam complex. allocates depending on nodes that are present in the gparamlist
22 bmodellist 0x7d0 0x508 4 complex complex 2 0 ActorParam
23 baslist 0x410 0x2f4 4 complex complex 0 0x80000 ActorParam
24 baiprog 0x448 0x30c 4 complex complex 1 0x300000 ActorParam
25 bphysics 0x470 0x324 4 complex complex 6 0 ActorParam
26 bchemical 0x3c0 0x2cc 4 complex complex 0 0x2000 ActorParam
27 bas 0x3c8 0x2d0 4 complex complex 0 0x80000 ActorParam
28 batcllist 0x3f0 0x2e4 4 0 0 1 0x2000 ActorParam
29 batcl 0x428 0x344 4 complex complex 1 0x2000 ActorParam
30 baischedule 0x2b8 0x244 4 0 0 1 0x800 ActorParam
31 bdmgparam 0x11d0 0x9f0 4 0x790 0x3c0 1 0x20000 ActorParam
32 brgconfiglist 0x3d0 0x2d4 4 complex complex 1 0x2000 ActorParam
33 brgconfig 0x42d8 0x2acc 4 0 0 1 0x20000 ActorParam
34 brgbw 0x2c0 0x248 4 complex complex 1 0x20000 ActorParam
35 bawareness 0xb38 0x70c 4 0 0 1 0 ActorParam
36 bdrop 0x320 0x27c 4 complex complex 1 0x5000 ActorParam
37 bshop 0x320 0x27c 4 complex complex 1 0x20000 ActorParam
38 brecipe 0x320 0x27c 4 complex complex 1 0x20000 ActorParam
39 blod 0x3c0 0x2cc 4 0 0 1 0x20000 ActorParam
40 bbonectrl 0x8d0 0x564 4 complex complex 1 0x40000 ActorParam
41 blifecondition 0x4b0 0x35c 4 complex complex 1 0x20000 ActorParam
42 bumii 0x2b8 0x244 4 0 0 1 0 ActorParam
43 baniminfo 0x2c8 0x24c 4 complex complex 1.5 0 ActorParam
44 byaml 0x20 0x14 4 0 0 1 0 ActorParam
45 bassetting 0x260 0x1d8 4 complex complex 0 0x80000 ActorParam
46 hkrb 0x20 0x14 4 0 0 1 0x400 Physics
47 hkrg 0x20 0x14 4 0 0 1 0x400 Physics
48 bphyssb 0x5b0 0x384 4 complex complex 1 0x100000 Physics
49 hkcl 0xe8 0xb8 4 complex complex 2 0x2800 Physics
50 hksc 0x140 0xe8 4 complex complex 1.3 0x40000 Physics
51 hktmrb 0x48 0x28 4 complex complex 1 0x800 Physics
52 brgcon 0x48 0x28 4 complex complex 1 0x4000 Physics
53 esetlist 0x38 0x20 0x4000 0 0 1 0 Effect
54 bdemo 0xb20 0x6cc 4 0 0 1 0xb20 Event
55 bfevfl 0x40 0x24 4 0 0 1 0x40 Event
56 bfevtm 0x40 0x24 4 0 0 1 0x40 Event

View File

@ -15,6 +15,12 @@ namespace Switch_Toolbox.Library
public class Runtime
{
public static class ResourceTables
{
public static bool TpTable = false;
public static bool BotwTable = false;
}
public static string Mk8GamePath = "";
public static string Mk8dGamePath = "";
public static string SmoGamePath = "";

View File

@ -50,6 +50,9 @@
<HintPath>..\Toolbox\Lib\CSCore.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="CsvHelper">
<HintPath>..\Toolbox\Lib\CsvHelper.dll</HintPath>
</Reference>
<Reference Include="Cyotek.Windows.Forms.ImageBox">
<HintPath>..\Toolbox\Lib\Cyotek.Windows.Forms.ImageBox.dll</HintPath>
</Reference>
@ -220,6 +223,8 @@
<Compile Include="FileFormats\DAE\DAE.cs" />
<Compile Include="FileFormats\OBJ.cs" />
<Compile Include="FileFormats\R4G4.cs" />
<Compile Include="FileFormats\SizeTables\RSTB.cs" />
<Compile Include="FileFormats\SizeTables\TPFileSizeTable.cs" />
<Compile Include="Forms\Archive\ArchiveFilePanel.cs">
<SubType>UserControl</SubType>
</Compile>
@ -244,6 +249,12 @@
<Compile Include="Forms\Dialogs\ExportModelSettings.Designer.cs">
<DependentUpon>ExportModelSettings.cs</DependentUpon>
</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">
<SubType>UserControl</SubType>
</Compile>
@ -733,6 +744,9 @@
<EmbeddedResource Include="Forms\Dialogs\ExportModelSettings.resx">
<DependentUpon>ExportModelSettings.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Dialogs\STSaveLogDialog.resx">
<DependentUpon>STSaveLogDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Dialogs\STOptionsDialog.resx">
<DependentUpon>STOptionsDialog.cs</DependentUpon>
</EmbeddedResource>
@ -896,6 +910,7 @@
<None Include="Resources\mesh.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\resource_factory_info.tsv" />
<None Include="Resources\skeletonAnimation.png" />
</ItemGroup>
<ItemGroup>

View File

@ -34,6 +34,7 @@
this.chkBoxNormalMap = new Switch_Toolbox.Library.Forms.STCheckBox();
this.shadingComboBox = new System.Windows.Forms.ComboBox();
this.panel2 = new Switch_Toolbox.Library.Forms.STPanel();
this.uvChannelRB3 = new System.Windows.Forms.RadioButton();
this.uvChannelRB2 = new System.Windows.Forms.RadioButton();
this.uvChannelRB = new System.Windows.Forms.RadioButton();
this.displayBoundingBoxeChk = new Switch_Toolbox.Library.Forms.STCheckBox();
@ -112,7 +113,10 @@
this.chkUseSkyobx = new Switch_Toolbox.Library.Forms.STCheckBox();
this.stLabel15 = new Switch_Toolbox.Library.Forms.STLabel();
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.panel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.cameraMaxSpeedUD)).BeginInit();
@ -135,6 +139,7 @@
this.tabPage3.SuspendLayout();
this.stContextMenuStrip1.SuspendLayout();
this.tabPage4.SuspendLayout();
this.tabPage5.SuspendLayout();
this.SuspendLayout();
//
// contentContainer
@ -228,6 +233,18 @@
this.panel2.Size = new System.Drawing.Size(534, 293);
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
//
this.uvChannelRB2.AutoSize = true;
@ -791,6 +808,7 @@
this.stTabControl1.Controls.Add(this.tabPage2);
this.stTabControl1.Controls.Add(this.tabPage3);
this.stTabControl1.Controls.Add(this.tabPage4);
this.stTabControl1.Controls.Add(this.tabPage5);
this.stTabControl1.Location = new System.Drawing.Point(0, 25);
this.stTabControl1.myBackColor = System.Drawing.Color.Empty;
this.stTabControl1.Name = "stTabControl1";
@ -1187,17 +1205,50 @@
this.specularCubemapPathTB.Click += new System.EventHandler(this.cubemapPathTB_Click);
this.specularCubemapPathTB.TextChanged += new System.EventHandler(this.specularCubemapPathTB_TextChanged);
//
// uvChannelRB3
// tabPage5
//
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);
this.tabPage5.Controls.Add(this.chkTpFileTable);
this.tabPage5.Controls.Add(this.stLabel17);
this.tabPage5.Controls.Add(this.chkBotwFileTable);
this.tabPage5.Location = new System.Drawing.Point(4, 25);
this.tabPage5.Name = "tabPage5";
this.tabPage5.Padding = new System.Windows.Forms.Padding(3);
this.tabPage5.Size = new System.Drawing.Size(541, 395);
this.tabPage5.TabIndex = 4;
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
//
@ -1237,6 +1288,8 @@
this.stContextMenuStrip1.ResumeLayout(false);
this.tabPage4.ResumeLayout(false);
this.tabPage4.PerformLayout();
this.tabPage5.ResumeLayout(false);
this.tabPage5.PerformLayout();
this.ResumeLayout(false);
}
@ -1327,5 +1380,9 @@
private System.Windows.Forms.RadioButton uvChannelRB2;
private System.Windows.Forms.RadioButton uvChannelRB;
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;
}
}

View File

@ -85,6 +85,8 @@ namespace Toolbox
chkUseSkyobx.Checked = Runtime.PBR.UseSkybox;
chkDiffyseSkybox.Checked = Runtime.PBR.UseDiffuseSkyTexture;
chkDiffyseSkybox.Enabled = chkUseSkyobx.Checked;
chkBotwFileTable.Checked = Runtime.ResourceTables.BotwTable;
chkTpFileTable.Checked = Runtime.ResourceTables.TpTable;
displayBoundingBoxeChk.Checked = Runtime.renderBoundingBoxes;
@ -450,8 +452,11 @@ namespace Toolbox
FolderSelectDialog sfd = new FolderSelectDialog();
if (sfd.ShowDialog() == DialogResult.OK)
{
SMOPathTB.Text = sfd.SelectedPath;
Runtime.BotwGamePath = SMOPathTB.Text;
if (!IsValidBotwDirectory(sfd.SelectedPath))
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;
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.