diff --git a/BOTWToolset.sln b/BOTWToolset.sln new file mode 100644 index 0000000..c97e485 --- /dev/null +++ b/BOTWToolset.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30804.86 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BOTWToolset", "botw-toolset\BOTWToolset.csproj", "{9FE4680A-CD27-4835-844D-50543BEFF2D9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9FE4680A-CD27-4835-844D-50543BEFF2D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FE4680A-CD27-4835-844D-50543BEFF2D9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FE4680A-CD27-4835-844D-50543BEFF2D9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FE4680A-CD27-4835-844D-50543BEFF2D9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6F11E363-7B2E-44BA-94A6-ABEF9C9C1837} + EndGlobalSection +EndGlobal diff --git a/botw-toolset/App.config b/botw-toolset/App.config new file mode 100644 index 0000000..193aecc --- /dev/null +++ b/botw-toolset/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/botw-toolset/App.xaml b/botw-toolset/App.xaml new file mode 100644 index 0000000..5e00950 --- /dev/null +++ b/botw-toolset/App.xaml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/botw-toolset/App.xaml.cs b/botw-toolset/App.xaml.cs new file mode 100644 index 0000000..acda60e --- /dev/null +++ b/botw-toolset/App.xaml.cs @@ -0,0 +1,11 @@ +using System.Windows; + +namespace BOTWToolset +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + } +} diff --git a/botw-toolset/BOTWToolset.csproj b/botw-toolset/BOTWToolset.csproj new file mode 100644 index 0000000..9f93475 --- /dev/null +++ b/botw-toolset/BOTWToolset.csproj @@ -0,0 +1,119 @@ + + + + + Debug + AnyCPU + {9FE4680A-CD27-4835-844D-50543BEFF2D9} + WinExe + BOTWToolset + botw-toolset + v4.8 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + TabTSCB.xaml + + + MSBuild:Compile + Designer + + + App.xaml + Code + + + + + + + + + + + + + + Dashboard.xaml + Code + + + Designer + MSBuild:Compile + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + + + + \ No newline at end of file diff --git a/botw-toolset/Color.cs b/botw-toolset/Color.cs new file mode 100644 index 0000000..eede5ec --- /dev/null +++ b/botw-toolset/Color.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BOTWToolset +{ + struct Color + { + public byte R; + public byte G; + public byte B; + + public Color(byte r, byte g, byte b) + { + R = r; + G = g; + B = b; + } + } +} diff --git a/botw-toolset/Control/TabTSCB.xaml b/botw-toolset/Control/TabTSCB.xaml new file mode 100644 index 0000000..e19b97a --- /dev/null +++ b/botw-toolset/Control/TabTSCB.xaml @@ -0,0 +1,45 @@ + + + + diff --git a/botw-toolset/Control/TabTSCB.xaml.cs b/botw-toolset/Control/TabTSCB.xaml.cs new file mode 100644 index 0000000..9c4213f --- /dev/null +++ b/botw-toolset/Control/TabTSCB.xaml.cs @@ -0,0 +1,102 @@ +using BOTWToolset.IO.TSCB; +using Microsoft.Win32; +using System.Windows.Controls; +using BOTWToolset.Debugging; + +namespace BOTWToolset +{ + /// + /// Control tab for TSCB management + /// + public partial class TabTSCB : UserControl + { + public static string fileLocation; + public static TSCBInfo currentTSCBInfo; + + public TabTSCB() + { + InitializeComponent(); + } + + public void SetSidebarHeaderInfo(TSCBInfo t) + { + Signature.Text = t.Signature; + Version.Text = t.Version.ToString() + ".0.0.0"; // TODO: An actual version based off bytes should be done later + FileBaseOffset.Text = t.FileBaseOffset.ToString(); + WorldScale.Text = t.WorldScale.ToString(); + TerrainMaxHeight.Text = t.TerrainMaxHeight.ToString(); + MaterialInfoLength.Text = t.MaterialInfoLength.ToString(); + AreaArrayLength.Text = t.AreaArrayLength.ToString(); + TileSize.Text = t.TileSize.ToString(); + } + + public void ClearAllTabInfo() + { + // Clear sidebar header info + Signature.Clear(); + Version.Clear(); + FileBaseOffset.Clear(); + WorldScale.Clear(); + TerrainMaxHeight.Clear(); + MaterialInfoLength.Clear(); + AreaArrayLength.Clear(); + TileSize.Clear(); + + // Clear area display stack panel + TSCBAreaViewer.Children.Clear(); + } + + private void Menu_OpenFile(object sender, System.Windows.RoutedEventArgs e) + { + BOTWConsole.Log("Clicked File -> Open button"); + + var openFileDialog = new OpenFileDialog + { + InitialDirectory = @"C:\", + RestoreDirectory = true, + Title = "Select TSCB file", + DefaultExt = "tscb", + Filter = "TSCB files (*.tscb)|*.tscb", + CheckFileExists = true + }; + + if ((bool)openFileDialog.ShowDialog()) + { + BOTWConsole.Log("Opening file"); + + TSCBInfo t = TSCB.ReadFile(openFileDialog.FileName); + + // Set the current file location to the chosen file's location + fileLocation = openFileDialog.FileName; + + // Set the current TCSBInfo to the new TSCBInfo + currentTSCBInfo = t; + + // Set UI sidebar to have header info + SetSidebarHeaderInfo(t); + + // Allow the file to be saved + MenuFileSave.IsEnabled = true; + } + } + + private void Menu_CloseFile(object sender, System.Windows.RoutedEventArgs e) + { + BOTWConsole.Log("Clicked File -> Close button"); + + // Set the current TSCB info to nothing + currentTSCBInfo = null; + + // Clear sidebar header info + ClearAllTabInfo(); + + // Since there's no file open, don't allow saving + MenuFileSave.IsEnabled = false; + } + + private void Menu_SaveFile(object sender, System.Windows.RoutedEventArgs e) + { + BOTWConsole.Log("Clicked File -> Save button"); + } + } +} diff --git a/botw-toolset/Dashboard.xaml b/botw-toolset/Dashboard.xaml new file mode 100644 index 0000000..9f3624f --- /dev/null +++ b/botw-toolset/Dashboard.xaml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + diff --git a/botw-toolset/Dashboard.xaml.cs b/botw-toolset/Dashboard.xaml.cs new file mode 100644 index 0000000..a166d7e --- /dev/null +++ b/botw-toolset/Dashboard.xaml.cs @@ -0,0 +1,23 @@ +using BOTWToolset.IO.TSCB; +using System.Windows; +using BOTWToolset.Debugging; + +namespace BOTWToolset +{ + /// + /// Interaction logic for Dashboard.xaml + /// + public partial class Dashboard : Window + { + public const string VERSION = "1.0.0-pre-alpha"; + + public Dashboard() + { + InitializeComponent(); + + BOTWConsole.Log($"Breath of the Wild Toolkit - Version {VERSION}"); + + LabelVersion.Content = $"Version v{VERSION}"; + } + } +} diff --git a/botw-toolset/Debugging/BOTWConsole.cs b/botw-toolset/Debugging/BOTWConsole.cs new file mode 100644 index 0000000..425327e --- /dev/null +++ b/botw-toolset/Debugging/BOTWConsole.cs @@ -0,0 +1,33 @@ +using System.Linq; +using System.Windows; +using System.Windows.Controls; + +namespace BOTWToolset.Debugging +{ + static class BOTWConsole + { + private readonly static TextBox _console; + static BOTWConsole() + { + var dashboard = Application.Current.Windows.OfType().ToArray()[0]; + var tabControl = dashboard.tabTSCB; + _console = tabControl.TSCBConsole; + } + + public static void Log(object text) + { + _console.Text += text.ToString() + "\n"; + _console.ScrollToEnd(); // After adding the new text, scroll to the end + } + + public static void LogWarning(object text) + { + Log("[Warning]" + text); + } + + public static void LogError(object text) + { + Log("[ERROR]" + text); + } + } +} diff --git a/botw-toolset/IO/EXTM/Grass.cs b/botw-toolset/IO/EXTM/Grass.cs new file mode 100644 index 0000000..6ac80eb --- /dev/null +++ b/botw-toolset/IO/EXTM/Grass.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BOTWToolset.IO.EXTM +{ + /// + /// Stores info on grass data in an .extm file + /// + class Grass + { + public byte Height { get => _height; set => _height = value; } + private byte _height; + + public byte R { get => _r; set => _r = value; } + private byte _r; + + public byte G { get => _g; set => _g = value; } + private byte _g; + + public byte B { get => _b; set => _b = value; } + private byte _b; + } +} diff --git a/botw-toolset/IO/EXTM/GrassColor.cs b/botw-toolset/IO/EXTM/GrassColor.cs new file mode 100644 index 0000000..2546e35 --- /dev/null +++ b/botw-toolset/IO/EXTM/GrassColor.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BOTWToolset.IO.EXTM +{ + class GrassColor + { + public static readonly Color[] Colors = new Color[] + { + new Color(95, 142, 74), // Green grass + new Color(170, 193, 75), // Yellow grass + new Color(206, 122, 66), // Wood chips 00 + new Color(181, 107, 57), // Wood chips 01 + new Color(160, 95, 51), // Wood chips 02 + new Color(137, 81, 44), // Wood chips 03 + new Color(137, 106, 72), // Wood chips 04 reeds + new Color(79, 112, 68) // Wood chips 05 leaves + }; + } +} diff --git a/botw-toolset/IO/EXTM/Water.cs b/botw-toolset/IO/EXTM/Water.cs new file mode 100644 index 0000000..1fcef08 --- /dev/null +++ b/botw-toolset/IO/EXTM/Water.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BOTWToolset.IO.EXTM +{ + /// + /// Stores info on water data in an .extm file + /// + class Water + { + public ushort Height { get => _height; set => _height = value; } + private ushort _height; + + public ushort XAxisFlowRate { get => _xAxisFlowRate; set => _xAxisFlowRate = value; } + private ushort _xAxisFlowRate; + + public ushort ZAxisFlowRate { get => _zAxisFlowRate; set => _zAxisFlowRate = value; } + private ushort _zAxisFlowRate; + + public byte MaterialIndex { get => _matIndex; set => _matIndex = value; } + private byte _matIndex; + + public byte MaterialIndexChecksum { + get { + if (_matIndex != 0) + return (byte)(_matIndex + 3); + return _matIndex; + } + } + } +} diff --git a/botw-toolset/IO/EXTM/WaterColor.cs b/botw-toolset/IO/EXTM/WaterColor.cs new file mode 100644 index 0000000..533472d --- /dev/null +++ b/botw-toolset/IO/EXTM/WaterColor.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BOTWToolset.IO.EXTM +{ + class WaterColor + { + public static readonly Color[] Colors = new Color[] + { + new Color(73, 137, 255), // Water + new Color(114, 255, 210), // Hot water + new Color(173, 73, 255), // Poison water + new Color(255, 97, 0), // Lava + new Color(142, 211, 255), // Cold water + new Color(86, 44, 0), // Bog (mud) + new Color(102, 158, 255), // Clear water 01 + new Color(52, 99, 181) // Ocean + }; + } +} diff --git a/botw-toolset/IO/TSCB/AreaInfo.cs b/botw-toolset/IO/TSCB/AreaInfo.cs new file mode 100644 index 0000000..6c1e0db --- /dev/null +++ b/botw-toolset/IO/TSCB/AreaInfo.cs @@ -0,0 +1,69 @@ +namespace BOTWToolset.IO.TSCB +{ + /// + /// Stores area info for area data declared in a .tscb file. + /// + public class AreaInfo + { + public float PositionX { get => _positionX; set => _positionX = value; } + private float _positionX; + + public float PositionZ { get => _positionZ; set => _positionZ = value; } + private float _positionZ; + + public float AreaSize { get => _areaSize; set => _areaSize = value; } + private float _areaSize; + + public float MinTerrainHeight { get => _minTerrainHeight; set => _minTerrainHeight = value; } + private float _minTerrainHeight; + + public float MaxTerrainHeight { get => _maxTerrainHeight; set => _maxTerrainHeight = value; } + private float _maxTerrainHeight; + + public float MinWaterHeight { get => _minWaterHeight; set => _minWaterHeight = value; } + private float _minWaterHeight; + + public float MaxWaterHeight { get => _maxWaterHeight; set => _maxWaterHeight = value; } + private float _maxWaterHeight; + + public uint Unknown1 { get => _unknown1; set => _unknown1 = value; } + private uint _unknown1; + + public uint FileBase { get => _fileBase; set => _fileBase = value; } + private uint _fileBase; + + public uint Unknown2 { get => _unknown2; set => _unknown2 = value; } + private uint _unknown2; + + public uint Unknown3 { get => _unknown3; set => _unknown3 = value; } + private uint _unknown3; + + public uint ReferenceExtra { get => _refExtra; set => _refExtra = value; } + private uint _refExtra; + + public bool HasWater { get => _hasWater; set => _hasWater = value; } + private bool _hasWater = false; + + public bool HasGrass { get => _hasGrass; set => _hasGrass = value; } + private bool _hasGrass = false; + + public uint Offset; + + public AreaInfo(float x_pos, float z_pos, float area_size, float min_terrain_height, float max_terrain_height, + float min_water_height, float max_water_height, uint unknown_1, uint file_base, uint unknown_2, uint unknown_3, uint ref_extra) + { + PositionX = x_pos; + PositionZ = z_pos; + AreaSize = area_size; + MinTerrainHeight = min_terrain_height; + MaxTerrainHeight = max_terrain_height; + MinWaterHeight = min_water_height; + MaxWaterHeight = max_water_height; + Unknown1 = unknown_1; + FileBase = file_base; + Unknown2 = unknown_2; + Unknown3 = unknown_3; + ReferenceExtra = ref_extra; + } + } +} diff --git a/botw-toolset/IO/TSCB/MaterialInfo.cs b/botw-toolset/IO/TSCB/MaterialInfo.cs new file mode 100644 index 0000000..e0cfa1d --- /dev/null +++ b/botw-toolset/IO/TSCB/MaterialInfo.cs @@ -0,0 +1,32 @@ +namespace BOTWToolset.IO.TSCB +{ + /// + /// Stores material info for a material declared in a .tscb file. + /// + public class MaterialInfo + { + public uint MaterialIndex { get => _materialIndex; set => _materialIndex = value; } + private uint _materialIndex; + + public float TextureU { get => _textureU; set => _textureU = value; } + private float _textureU; + + public float TextureV { get => _textureV; set => _textureV = value; } + private float _textureV; + + public float Unknown1 { get => _unknown1; set => _unknown1 = value; } + private float _unknown1; + + public float Unknown2 { get => _unknown2; set => _unknown2 = value; } + private float _unknown2; + + public MaterialInfo(uint mat_index, float tex_u, float tex_v, float unk_1, float unk_2) + { + MaterialIndex = mat_index; + TextureU = tex_u; + TextureV = tex_v; + Unknown1 = unk_1; + Unknown2 = unk_2; + } + } +} diff --git a/botw-toolset/IO/TSCB/TSCB.cs b/botw-toolset/IO/TSCB/TSCB.cs new file mode 100644 index 0000000..f485d12 --- /dev/null +++ b/botw-toolset/IO/TSCB/TSCB.cs @@ -0,0 +1,144 @@ +using BOTWToolset.Debugging; +using System; +using System.IO; +using System.Linq; +using System.Windows; + +namespace BOTWToolset.IO.TSCB +{ + /// + /// Interacts with .tcsb files. + /// + static class TSCB + { + public static TSCBInfo ReadFile(string file) + { + if (File.Exists(file)) + { + TSCBInfo t = new TSCBInfo(); + + using (var r = new BinaryReader(File.Open(file, FileMode.Open))) + { + // Set header info from file on the new TSCBInfo + t.SetHeaderInfo(r); + + // Skip over mat info offsets + r.BaseStream.Seek((t.MaterialInfoLength * 4) + 4, SeekOrigin.Current); + + BOTWConsole.Log($"Offset before material iteration: {r.BaseStream.Position}"); + + // Initialize mat info array with provided length + t.MaterialInfo = new MaterialInfo[t.MaterialInfoLength]; + + // Initialize every mat info, then add to the array + for (int i = 0; i < t.MaterialInfoLength; i++) + { + uint index = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); // Reverse byte order - use big endian + float tex_u = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + float tex_v = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + float unk_1 = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + float unk_2 = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + + MaterialInfo matInfo = new MaterialInfo(index, tex_u, tex_v, unk_1, unk_2); + + t.MaterialInfo[i] = matInfo; + } + + BOTWConsole.Log($"Offset before area offset iteration: {r.BaseStream.Position}"); + + // Skip over area offsets (current position plus area array bytes) + r.BaseStream.Seek(t.AreaArrayLength * 4, SeekOrigin.Current); + + BOTWConsole.Log($"Offset before area iteration: {r.BaseStream.Position}"); + + t.AreaInfo = new AreaInfo[t.AreaArrayLength]; + + for (int i = 0; i < t.AreaArrayLength; i++) + { + uint offset = (uint)r.BaseStream.Position; + + float xpos = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); // Reverse byte order - use big endian + float zpos = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + float area_size = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + float min_terrain_height = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + float max_terrain_height = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + float min_water_height = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + float max_water_height = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + uint unk_1 = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); + + if (unk_1 == 0) + { // If this unknown isn't equal to 2, skip the extra byte coming after it + uint next_val = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); + + if (next_val == 1) //if the next value is extra unneeded info + { + + } else //else, if the value is valid + { + r.BaseStream.Seek(-4, SeekOrigin.Current); + } + } + + uint file_base = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); + uint unk_2 = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); + uint unk_3 = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); + uint ref_extra = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); + + AreaInfo areaInfo = new AreaInfo(xpos, zpos, area_size, min_terrain_height, max_terrain_height, min_water_height, + max_water_height, unk_1, file_base, unk_2, unk_3, ref_extra); + + areaInfo.Offset = offset; + + uint extra_info_len = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); //Usually 0, 4, or 8 + + if (ref_extra == 4) { + if (extra_info_len == 8) + { //Skip the extra "20" after the 8, as well as the extra info + areaInfo.HasGrass = true; + areaInfo.HasWater = true; + r.BaseStream.Seek(36, SeekOrigin.Current); + } + else //If the length is 4 + { + var bytes = r.ReadBytes(16).Reverse().ToArray(); + if (bytes[1] == 0) //If the 2nd byte is 0 + areaInfo.HasGrass = true; + else //Else if the 2nd byte should be anything else (should always be 1) + areaInfo.HasWater = true; + } + } else //If the extra info flags aren't set, go back 4 + { + r.BaseStream.Seek(-4, SeekOrigin.Current); + } + + t.AreaInfo[i] = areaInfo; + } + + BOTWConsole.Log($"Offset after area iteration: {r.BaseStream.Position} (should be {t.FileBaseOffset + 16})"); + + //Get the number of filenames by getting how many bytes they take up out of the entire file size + var filenames_count = (r.BaseStream.Length - (t.FileBaseOffset + 16)) / 12; + + BOTWConsole.Log($"Filename count: {filenames_count} (should be {t.AreaArrayLength})"); + + t.FileNames = new string[filenames_count]; + + r.BaseStream.Seek(t.FileBaseOffset + 16, SeekOrigin.Begin); // TODO: change this to 'current' later, or maybe even remove + + for (int i = 0; i < filenames_count; i++) + { + string filename = new string(r.ReadChars(12)); + + t.FileNames[i] = filename; + } + } + + return t; + } + else + { + throw new FileNotFoundException("Cannot find .tscb file to read."); + } + } + } +} diff --git a/botw-toolset/IO/TSCB/TSCBInfo.cs b/botw-toolset/IO/TSCB/TSCBInfo.cs new file mode 100644 index 0000000..ce38364 --- /dev/null +++ b/botw-toolset/IO/TSCB/TSCBInfo.cs @@ -0,0 +1,63 @@ +using System; +using System.IO; +using System.Linq; + +namespace BOTWToolset.IO.TSCB +{ + /// + /// Contains data for a TCSB file. + /// + public class TSCBInfo + { + public const byte HeaderLength = 48; // Length of the header, in bytes + + public string Signature { get => _signature; set => _signature = value; } + private string _signature; + + public uint Version { get => _version; set => _version = value; } + private uint _version; + + public uint FileBaseOffset { get => _fileBaseOffset; set => _fileBaseOffset = value; } + private uint _fileBaseOffset; + + public float WorldScale { get => _worldScale; set => _worldScale = value.Clamp(0f, 800.0f); } + private float _worldScale; + + public float TerrainMaxHeight { get => _terrainMaxHeight; set => _terrainMaxHeight = value.Clamp(0f, 800.0f); } + private float _terrainMaxHeight; + + public uint MaterialInfoLength { get => _materialInfoLength; set => _materialInfoLength = value; } + private uint _materialInfoLength; + + public MaterialInfo[] MaterialInfo; + + public uint AreaArrayLength { get => _areaArrayLength; set => _areaArrayLength = value; } + private uint _areaArrayLength; + + public AreaInfo[] AreaInfo; + + public float TileSize; + + public string[] FileNames; + + public void SetHeaderInfo(BinaryReader r) + { + Signature = new string(r.ReadChars(4)); + Version = r.ReadUInt32(); + + r.BaseStream.Seek(4, SeekOrigin.Current); // Skip 4 bytes of "00 00 00 01" + + FileBaseOffset = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); // Reverse byte order - use big endian + WorldScale = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + TerrainMaxHeight = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + MaterialInfoLength = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); + AreaArrayLength = BitConverter.ToUInt32(r.ReadBytes(4).Reverse().ToArray(), 0); + + r.BaseStream.Seek(8, SeekOrigin.Current);// Skip 8 bytes of padding + + TileSize = BitConverter.ToSingle(r.ReadBytes(4).Reverse().ToArray(), 0); + + r.BaseStream.Seek(4, SeekOrigin.Current); // Skip 4 bytes of "00 00 00 08" + } + } +} diff --git a/botw-toolset/MathExt.cs b/botw-toolset/MathExt.cs new file mode 100644 index 0000000..d06d20e --- /dev/null +++ b/botw-toolset/MathExt.cs @@ -0,0 +1,25 @@ +using System; + +namespace BOTWToolset +{ + /// + /// Extensions for Math. + /// + static class MathExt + { + /// + /// Clamps a value into a minimum and maximum range. + /// + /// + /// Value to clamp. + /// The minimum value to use. + /// The maximum value to use. + /// + public static T Clamp(this T val, T min, T max) where T : IComparable + { + if (val.CompareTo(min) < 0) return min; + else if (val.CompareTo(max) > 0) return max; + else return val; + } + } +} diff --git a/botw-toolset/Properties/AssemblyInfo.cs b/botw-toolset/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..7754527 --- /dev/null +++ b/botw-toolset/Properties/AssemblyInfo.cs @@ -0,0 +1,53 @@ +using System.Reflection; +using System.Runtime.InteropServices; +using System.Windows; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("botw-toolset")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("botw-toolset")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/botw-toolset/Properties/Resources.Designer.cs b/botw-toolset/Properties/Resources.Designer.cs new file mode 100644 index 0000000..ec5e6fe --- /dev/null +++ b/botw-toolset/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BOTWToolset.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("BOTWToolset.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/botw-toolset/Properties/Resources.resx b/botw-toolset/Properties/Resources.resx new file mode 100644 index 0000000..af7dbeb --- /dev/null +++ b/botw-toolset/Properties/Resources.resx @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/botw-toolset/Properties/Settings.Designer.cs b/botw-toolset/Properties/Settings.Designer.cs new file mode 100644 index 0000000..39c6fd7 --- /dev/null +++ b/botw-toolset/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace BOTWToolset.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/botw-toolset/Properties/Settings.settings b/botw-toolset/Properties/Settings.settings new file mode 100644 index 0000000..033d7a5 --- /dev/null +++ b/botw-toolset/Properties/Settings.settings @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/botw-toolset/Resources/Icons/document.png b/botw-toolset/Resources/Icons/document.png new file mode 100644 index 0000000..a08add6 Binary files /dev/null and b/botw-toolset/Resources/Icons/document.png differ diff --git a/botw-toolset/Resources/Icons/letter-z.png b/botw-toolset/Resources/Icons/letter-z.png new file mode 100644 index 0000000..ce77bc0 Binary files /dev/null and b/botw-toolset/Resources/Icons/letter-z.png differ diff --git a/botw-toolset/Resources/Icons/mountain.png b/botw-toolset/Resources/Icons/mountain.png new file mode 100644 index 0000000..221b31e Binary files /dev/null and b/botw-toolset/Resources/Icons/mountain.png differ diff --git a/botw-toolset/Resources/Icons/package.png b/botw-toolset/Resources/Icons/package.png new file mode 100644 index 0000000..1747193 Binary files /dev/null and b/botw-toolset/Resources/Icons/package.png differ diff --git a/botw-toolset/Resources/Icons/speaker.png b/botw-toolset/Resources/Icons/speaker.png new file mode 100644 index 0000000..3ef877e Binary files /dev/null and b/botw-toolset/Resources/Icons/speaker.png differ diff --git a/botw-toolset/Resources/Icons/text-file-2.png b/botw-toolset/Resources/Icons/text-file-2.png new file mode 100644 index 0000000..f318ab4 Binary files /dev/null and b/botw-toolset/Resources/Icons/text-file-2.png differ diff --git a/botw-toolset/Resources/Icons/text-file.png b/botw-toolset/Resources/Icons/text-file.png new file mode 100644 index 0000000..a32565c Binary files /dev/null and b/botw-toolset/Resources/Icons/text-file.png differ diff --git a/botw-toolset/Resources/Icons/triforce.png b/botw-toolset/Resources/Icons/triforce.png new file mode 100644 index 0000000..0418c49 Binary files /dev/null and b/botw-toolset/Resources/Icons/triforce.png differ