Finish Implementing RomFS building

Some tweaks to SciresM's code to make it a little more verbose/quick.
This commit is contained in:
Kurt
2015-02-10 21:39:27 -08:00
parent eb5d7f8482
commit 39e89fb328
3 changed files with 112 additions and 66 deletions

15
pk3DS/Main.Designer.cs generated
View File

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

View File

@@ -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 <http://www.gnu.org/licenses/>. --*/
/*----------------------------------------------------------------------------*/
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 { }
}

View File

@@ -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)
{