mirror of
https://github.com/kwsch/pk3DS.git
synced 2026-10-02 13:57:14 -05:00
Finish Implementing RomFS building
Some tweaks to SciresM's code to make it a little more verbose/quick.
This commit is contained in:
15
pk3DS/Main.Designer.cs
generated
15
pk3DS/Main.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 { }
|
||||
}
|
||||
|
||||
115
pk3DS/RomFS.cs
115
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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user