From 39e89fb32809c45c1852e6ad438d8764dee931b9 Mon Sep 17 00:00:00 2001 From: Kurt Date: Tue, 10 Feb 2015 21:39:27 -0800 Subject: [PATCH] Finish Implementing RomFS building Some tweaks to SciresM's code to make it a little more verbose/quick. --- pk3DS/Main.Designer.cs | 15 +++--- pk3DS/Main.cs | 48 +++++++++++++++-- pk3DS/RomFS.cs | 115 ++++++++++++++++++++++------------------- 3 files changed, 112 insertions(+), 66 deletions(-) diff --git a/pk3DS/Main.Designer.cs b/pk3DS/Main.Designer.cs index cd5189b..d167d29 100644 --- a/pk3DS/Main.Designer.cs +++ b/pk3DS/Main.Designer.cs @@ -70,7 +70,7 @@ private void InitializeComponent() // // TB_Path // - this.TB_Path.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.TB_Path.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.TB_Path.Location = new System.Drawing.Point(93, 14); this.TB_Path.Name = "TB_Path"; @@ -80,7 +80,7 @@ private void InitializeComponent() // // GB_RomFS // - this.GB_RomFS.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.GB_RomFS.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.GB_RomFS.Controls.Add(this.B_Maison); this.GB_RomFS.Controls.Add(this.B_EggMove); @@ -265,7 +265,7 @@ private void InitializeComponent() // // pBar1 // - this.pBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.pBar1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.pBar1.Location = new System.Drawing.Point(12, 241); this.pBar1.Name = "pBar1"; @@ -284,7 +284,7 @@ private void InitializeComponent() // // GB_ExeFS // - this.GB_ExeFS.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + this.GB_ExeFS.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.GB_ExeFS.Controls.Add(this.B_Pickup); this.GB_ExeFS.Controls.Add(this.B_Mart); @@ -340,8 +340,8 @@ private void InitializeComponent() // // RTB_Status // - this.RTB_Status.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) + this.RTB_Status.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.RTB_Status.Location = new System.Drawing.Point(12, 263); this.RTB_Status.Name = "RTB_Status"; @@ -408,5 +408,4 @@ private void InitializeComponent() private System.Windows.Forms.Button B_TMHM; public System.Windows.Forms.RichTextBox RTB_Status; } -} - +} \ No newline at end of file diff --git a/pk3DS/Main.cs b/pk3DS/Main.cs index 59b2894..1c58e10 100644 --- a/pk3DS/Main.cs +++ b/pk3DS/Main.cs @@ -1,4 +1,19 @@ -using System; +/*----------------------------------------------------------------------------*/ +/*-- This program is free software: you can redistribute it and/or modify --*/ +/*-- it under the terms of the GNU General Public License as published by --*/ +/*-- the Free Software Foundation, either version 3 of the License, or --*/ +/*-- (at your option) any later version. --*/ +/*-- --*/ +/*-- This program is distributed in the hope that it will be useful, --*/ +/*-- but WITHOUT ANY WARRANTY; without even the implied warranty of --*/ +/*-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --*/ +/*-- GNU General Public License for more details. --*/ +/*-- --*/ +/*-- You should have received a copy of the GNU General Public License --*/ +/*-- along with this program. If not, see . --*/ +/*----------------------------------------------------------------------------*/ + +using System; using System.IO; using System.Threading; using System.Windows.Forms; @@ -25,7 +40,7 @@ public Main() TB_Path.DragDrop += tabMain_DragDrop; // Rebuilding Functionality - // GB_RomFS.Click += rebuildRomFS; // Not tested, need some verification first. + GB_RomFS.Click += rebuildRomFS; // Not tested, need some verification first. GB_ExeFS.Click += rebuildExeFS; // Reload Previous Editing Files if the file exists @@ -227,6 +242,7 @@ private void tabMain_DragDrop(object sender, DragEventArgs e) // RomFS Subform Items private void rebuildRomFS(object sender, EventArgs e) { + if (threads > 0) { Util.Alert("Please wait for all operations to finish first."); return; } if (RomFS != null) { if (Util.Prompt(MessageBoxButtons.YesNo, "Rebuild RomFS?") == DialogResult.Yes) @@ -235,7 +251,19 @@ private void rebuildRomFS(object sender, EventArgs e) sfd.FileName = "romfs.bin"; sfd.Filter = "Binary File|*.*"; if (sfd.ShowDialog() == DialogResult.OK) - { new Thread(() => { threads++; RomFSTool.BuildRomFS(RomFS, null, pBar1); threads--; }).Start(); } + { + new Thread(() => + { + updateStatus(Environment.NewLine + "Building RomFS binary. Please wait until the program finishes."); + + threads++; + RomFSTool.BuildRomFS(sfd.FileName, RomFS, RTB_Status, pBar1); + threads--; + + updateStatus("RomFS binary saved." + Environment.NewLine); + Util.Alert("Wrote RomFS binary:", sfd.FileName); + }).Start(); + } } } } @@ -552,8 +580,18 @@ public void updateStatus(string status, bool preBreak = true) try { if (RTB_Status.InvokeRequired) - RTB_Status.Invoke((MethodInvoker)delegate { RTB_Status.AppendText(((preBreak) ? Environment.NewLine : "") + status); }); - else RTB_Status.AppendText(status + Environment.NewLine); + RTB_Status.Invoke((MethodInvoker)delegate + { + RTB_Status.AppendText(((preBreak) ? Environment.NewLine : "") + status); + RTB_Status.SelectionStart = RTB_Status.Text.Length; + RTB_Status.ScrollToCaret(); + }); + else + { + RTB_Status.AppendText(status + Environment.NewLine); + RTB_Status.SelectionStart = RTB_Status.Text.Length; + RTB_Status.ScrollToCaret(); + } } catch { } } diff --git a/pk3DS/RomFS.cs b/pk3DS/RomFS.cs index 18fe736..d1984d2 100644 --- a/pk3DS/RomFS.cs +++ b/pk3DS/RomFS.cs @@ -12,16 +12,40 @@ public partial class RomFSTool { internal const int PADDING_ALIGN = 16; internal static string ROOT_DIR; - internal static string TempFile; + internal static string TempFile = "tempRomFS.bin"; + internal static string OutFile; internal const uint ROMFS_UNUSED_ENTRY = 0xFFFFFFFF; - internal static void BuildRomFS(string path, RichTextBox TB_Progress = null, ProgressBar PB_Show = null) + internal static void updateTB(RichTextBox RTB, string progress) { - ROOT_DIR = path; + try + { + if (RTB.InvokeRequired) + RTB.Invoke((MethodInvoker)delegate + { + RTB.AppendText(Environment.NewLine + progress); + RTB.SelectionStart = RTB.Text.Length; + RTB.ScrollToCaret(); + }); + else + { + RTB.SelectionStart = RTB.Text.Length; + RTB.ScrollToCaret(); + RTB.AppendText(progress + Environment.NewLine); + } + } + catch { } + } + internal static void BuildRomFS(string outfile, string infile, RichTextBox TB_Progress = null, ProgressBar PB_Show = null) + { + OutFile = outfile; + ROOT_DIR = infile; + if (File.Exists(TempFile)) File.Delete(TempFile); + FileNameTable FNT = new FileNameTable(ROOT_DIR); RomfsFile[] RomFiles = new RomfsFile[FNT.NumFiles]; LayoutManager.Input[] In = new LayoutManager.Input[FNT.NumFiles]; - TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Creating Layout..."))); + updateTB(TB_Progress, "Creating Layout..."); for (int i = 0; i < FNT.NumFiles; i++) { In[i] = new LayoutManager.Input(); @@ -39,9 +63,9 @@ internal static void BuildRomFS(string path, RichTextBox TB_Progress = null, Pro } using (MemoryStream memoryStream = new MemoryStream()) { - TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Creating RomFS MetaData..."))); + updateTB(TB_Progress, "Creating RomFS MetaData..."); BuildRomFSHeader(memoryStream, RomFiles, ROOT_DIR); - MakeRomFSData(RomFiles, memoryStream); + MakeRomFSData(RomFiles, memoryStream, TB_Progress, PB_Show); } } @@ -56,8 +80,7 @@ internal static ulong Align(ulong input, ulong alignsize) } internal static void MakeRomFSData(RomfsFile[] RomFiles, MemoryStream metadata, RichTextBox TB_Progress = null, ProgressBar PB_Show = null) { - TempFile = Path.GetRandomFileName(); - TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Computing IVFC Header Data..."))); + updateTB(TB_Progress, "Computing IVFC Header Data..."); IVFCInfo ivfc = new IVFCInfo(); ivfc.Levels = new IVFCLevel[3]; for (int i = 0; i < ivfc.Levels.Length; i++) @@ -100,14 +123,11 @@ internal static void MakeRomFSData(RomfsFile[] RomFiles, MemoryStream metadata, byte[] metadataArray = metadata.ToArray(); OutFileStream.Write(metadataArray, 0, metadataArray.Length); long baseOfs = OutFileStream.Position; - TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Writing Level 2 Data..."))); - PB_Show.Invoke((Action)(() => - { - PB_Show.Minimum = 0; - PB_Show.Maximum = RomFiles.Length; - PB_Show.Value = 0; - PB_Show.Step = 1; - })); + updateTB(TB_Progress, "Writing Level 2 Data..."); + if (PB_Show.InvokeRequired) + PB_Show.Invoke((MethodInvoker)delegate { PB_Show.Minimum = 0; PB_Show.Step = 1; PB_Show.Value = 0; PB_Show.Maximum = RomFiles.Length; }); + else { PB_Show.Minimum = 0; PB_Show.Step = 1; PB_Show.Value = 0; PB_Show.Maximum = RomFiles.Length; } + for (int i = 0; i < RomFiles.Length; i++) { OutFileStream.Seek((long)(baseOfs + (long)RomFiles[i].Offset), SeekOrigin.Begin); @@ -120,7 +140,9 @@ internal static void MakeRomFSData(RomfsFile[] RomFiles, MemoryStream metadata, OutFileStream.Write(buffer, 0, buffer.Length); } } - PB_Show.Invoke((Action)(() => PB_Show.PerformStep())); + if (PB_Show.InvokeRequired) + PB_Show.Invoke((MethodInvoker)delegate { PB_Show.PerformStep(); }); + else { PB_Show.PerformStep(); } } long hashBaseOfs = (long)Align((ulong)OutFileStream.Position, ivfc.Levels[2].BlockSize); long hOfs = (long)Align(MasterHashLen, ivfc.Levels[0].BlockSize); @@ -128,15 +150,13 @@ internal static void MakeRomFSData(RomfsFile[] RomFiles, MemoryStream metadata, SHA256Managed sha = new SHA256Managed(); for (int i = ivfc.Levels.Length - 1; i >= 0; i--) { - TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Computing Level " + i + " Hashes..."))); + updateTB(TB_Progress, "Computing Level " + i + " Hashes..."); byte[] buffer = new byte[(int)ivfc.Levels[i].BlockSize]; - PB_Show.Invoke((Action)(() => - { - PB_Show.Minimum = 0; - PB_Show.Maximum = (int)(ivfc.Levels[i].DataLength / ivfc.Levels[i].BlockSize); - PB_Show.Value = 0; - PB_Show.Step = 1; - })); + + if (PB_Show.InvokeRequired) + PB_Show.Invoke((MethodInvoker)delegate { PB_Show.Minimum = 0; PB_Show.Step = 1; PB_Show.Value = 0; PB_Show.Maximum = (int)(ivfc.Levels[i].DataLength / ivfc.Levels[i].BlockSize); }); + else { PB_Show.Minimum = 0; PB_Show.Step = 1; PB_Show.Value = 0; PB_Show.Maximum = (int)(ivfc.Levels[i].DataLength / ivfc.Levels[i].BlockSize); } + for (long ofs = 0; ofs < (long)ivfc.Levels[i].DataLength; ofs += ivfc.Levels[i].BlockSize) { OutFileStream.Seek(hOfs, SeekOrigin.Begin); @@ -146,7 +166,9 @@ internal static void MakeRomFSData(RomfsFile[] RomFiles, MemoryStream metadata, OutFileStream.Seek(cOfs, SeekOrigin.Begin); OutFileStream.Write(hash, 0, hash.Length); cOfs = OutFileStream.Position; - PB_Show.Invoke((Action)(() => PB_Show.PerformStep())); + if (PB_Show.InvokeRequired) + PB_Show.Invoke((MethodInvoker)delegate { PB_Show.PerformStep(); }); + else { PB_Show.PerformStep(); } } if (i == 2) { @@ -182,21 +204,11 @@ internal static void MakeRomFSData(RomfsFile[] RomFiles, MemoryStream metadata, if (OutFileStream != null) OutFileStream.Dispose(); } - TB_Progress.Invoke((Action)(() => UpdateTB_Progress("RomFS Super Block Hash: " + ByteArrayToString(SuperBlockHash)))); - TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Prompting to Save..."))); - SaveFileDialog sfd = new SaveFileDialog(); - TB_Progress.Invoke((Action)(() => - { - if (sfd.ShowDialog() == DialogResult.OK) - { - - TB_Progress.Invoke((Action)(() => UpdateTB_Progress("Writing Binary to " + sfd.FileName + "..."))); - Thread thread = new Thread(() => WriteBinary(TempFile, sfd.FileName)); - thread.IsBackground = true; - thread.Start(); - - } - })); + updateTB(TB_Progress, "RomFS Super Block Hash: " + ByteArrayToString(SuperBlockHash)); + updateTB(TB_Progress, "Saving to destination..."); + + if (File.Exists(OutFile)) File.Delete(OutFile); + File.Move(TempFile, OutFile); } internal static void WriteBinary(string tempFile, string outFile, RichTextBox TB_Progress = null, ProgressBar PB_Show = null) { @@ -207,13 +219,11 @@ internal static void WriteBinary(string tempFile, string outFile, RichTextBox TB using (FileStream fileStream = new FileStream(tempFile, FileMode.Open, FileAccess.Read)) { uint BUFFER_SIZE = 0x100000; - PB_Show.Invoke((Action)(() => - { - PB_Show.Minimum = 0; - PB_Show.Maximum = (int)(fileStream.Length / BUFFER_SIZE); - PB_Show.Value = 0; - PB_Show.Step = 1; - })); + + if (PB_Show.InvokeRequired) + PB_Show.Invoke((MethodInvoker)delegate { PB_Show.Minimum = 0; PB_Show.Step = 1; PB_Show.Value = 0; PB_Show.Maximum = (int)(fileStream.Length / BUFFER_SIZE); }); + else { PB_Show.Minimum = 0; PB_Show.Step = 1; PB_Show.Value = 0; PB_Show.Maximum = (int)(fileStream.Length / BUFFER_SIZE); } + byte[] buffer = new byte[BUFFER_SIZE]; while (true) { @@ -221,7 +231,9 @@ internal static void WriteBinary(string tempFile, string outFile, RichTextBox TB if (count != 0) { writer.Write(buffer, 0, count); - PB_Show.Invoke((Action)(() => PB_Show.PerformStep())); + if (PB_Show.InvokeRequired) + PB_Show.Invoke((MethodInvoker)delegate { PB_Show.PerformStep(); }); + else { PB_Show.PerformStep(); } } else break; @@ -231,10 +243,7 @@ internal static void WriteBinary(string tempFile, string outFile, RichTextBox TB } } File.Delete(TempFile); - TB_Progress.Invoke((Action)(() => - { - MessageBox.Show("Wrote RomFS to " + outFile + "."); - })); + Util.Alert("Wrote RomFS to path:", outFile); } internal static string ByteArrayToString(byte[] input) {