diff --git a/pk3DS/Main.cs b/pk3DS/Main.cs
index fcbd7c6..0ad0d24 100644
--- a/pk3DS/Main.cs
+++ b/pk3DS/Main.cs
@@ -65,7 +65,8 @@ public Main()
public static string ExeFSPath;
public static string ExHeaderPath;
public volatile int threads;
- private static string[] allGARCs = { "gametext", "storytext", "personal", "trpoke", "trdata", "evolution", "megaevo", "levelup", "eggmove", "item", "move", "maisonpkS", "maisontrS", "maisonpkN", "maisontrN" };
+ internal volatile static int Language;
+ internal static string[] allGARCs = { "gametext", "storytext", "personal", "trpoke", "trdata", "evolution", "megaevo", "levelup", "eggmove", "item", "move", "maisonpkS", "maisontrS", "maisonpkN", "maisontrN" };
private bool skipBoth;
// Main Form Methods
@@ -113,6 +114,9 @@ private void B_Open_Click(object sender, EventArgs e)
}
private void changeLanguage(object sender, EventArgs e)
{
+ if (CB_Lang.InvokeRequired)
+ CB_Lang.Invoke((MethodInvoker)delegate { Language = CB_Lang.SelectedIndex; });
+ else Language = CB_Lang.SelectedIndex;
if (!GB_RomFS.Enabled) return;
new Thread(() =>
{
@@ -601,13 +605,12 @@ private void L_SubTools_Click(object sender, EventArgs e)
}
// GARC Requests
- public string getGARCFileName(string requestedGARC)
+ private string getGARCFileName(string requestedGARC)
+ {
+ return getGARCFileName(requestedGARC, Language);
+ }
+ internal static string getGARCFileName(string requestedGARC, int lang)
{
- int lang = 0;
- if (CB_Lang.InvokeRequired)
- CB_Lang.Invoke((MethodInvoker)delegate { lang = CB_Lang.SelectedIndex; });
- else lang = CB_Lang.SelectedIndex;
-
string ans = "";
switch (requestedGARC)
{
@@ -633,7 +636,7 @@ public string getGARCFileName(string requestedGARC)
}
return ans;
}
- public string getGARCPath(int A, int B, int C)
+ internal static string getGARCPath(int A, int B, int C)
{
return String.Format("{0}a{0}{1}{0}{2}{0}{3}", Path.DirectorySeparatorChar, A, B, C);
}
diff --git a/pk3DS/Subforms/Patch.Designer.cs b/pk3DS/Subforms/Patch.Designer.cs
new file mode 100644
index 0000000..1c838fc
--- /dev/null
+++ b/pk3DS/Subforms/Patch.Designer.cs
@@ -0,0 +1,143 @@
+namespace pk3DS
+{
+ partial class Patch
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.CHKLB_GARCs = new System.Windows.Forms.CheckedListBox();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.label1 = new System.Windows.Forms.Label();
+ this.B_PatchCIA = new System.Windows.Forms.Button();
+ this.CHK_Lang = new System.Windows.Forms.CheckBox();
+ this.RTB_GARCs = new System.Windows.Forms.RichTextBox();
+ this.label2 = new System.Windows.Forms.Label();
+ this.SuspendLayout();
+ //
+ // CHKLB_GARCs
+ //
+ this.CHKLB_GARCs.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)));
+ this.CHKLB_GARCs.FormattingEnabled = true;
+ this.CHKLB_GARCs.Location = new System.Drawing.Point(12, 12);
+ this.CHKLB_GARCs.Name = "CHKLB_GARCs";
+ this.CHKLB_GARCs.Size = new System.Drawing.Size(150, 289);
+ this.CHKLB_GARCs.TabIndex = 0;
+ //
+ // textBox1
+ //
+ this.textBox1.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.textBox1.Location = new System.Drawing.Point(168, 28);
+ this.textBox1.Name = "textBox1";
+ this.textBox1.ReadOnly = true;
+ this.textBox1.Size = new System.Drawing.Size(104, 20);
+ this.textBox1.TabIndex = 1;
+ this.textBox1.Text = "a/#/* -> a#/*";
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(168, 12);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(109, 13);
+ this.label1.TabIndex = 2;
+ this.label1.Text = "ExeFS Path Override:";
+ //
+ // B_PatchCIA
+ //
+ this.B_PatchCIA.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+ this.B_PatchCIA.Location = new System.Drawing.Point(168, 278);
+ this.B_PatchCIA.Name = "B_PatchCIA";
+ this.B_PatchCIA.Size = new System.Drawing.Size(104, 23);
+ this.B_PatchCIA.TabIndex = 3;
+ this.B_PatchCIA.Text = "Redirect [CIA]";
+ this.B_PatchCIA.UseVisualStyleBackColor = true;
+ this.B_PatchCIA.Click += new System.EventHandler(this.B_PatchCIA_Click);
+ //
+ // CHK_Lang
+ //
+ this.CHK_Lang.AutoSize = true;
+ this.CHK_Lang.Location = new System.Drawing.Point(171, 54);
+ this.CHK_Lang.Name = "CHK_Lang";
+ this.CHK_Lang.Size = new System.Drawing.Size(110, 17);
+ this.CHK_Lang.TabIndex = 4;
+ this.CHK_Lang.Text = "Patch Languages";
+ this.CHK_Lang.UseVisualStyleBackColor = true;
+ //
+ // RTB_GARCs
+ //
+ this.RTB_GARCs.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)));
+ this.RTB_GARCs.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.RTB_GARCs.Location = new System.Drawing.Point(168, 90);
+ this.RTB_GARCs.Name = "RTB_GARCs";
+ this.RTB_GARCs.Size = new System.Drawing.Size(75, 160);
+ this.RTB_GARCs.TabIndex = 5;
+ this.RTB_GARCs.Text = "";
+ //
+ // label2
+ //
+ this.label2.AutoSize = true;
+ this.label2.Location = new System.Drawing.Point(165, 74);
+ this.label2.Name = "label2";
+ this.label2.Size = new System.Drawing.Size(72, 13);
+ this.label2.TabIndex = 6;
+ this.label2.Text = "Extra GARCs:";
+ //
+ // Patch
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.ClientSize = new System.Drawing.Size(284, 312);
+ this.Controls.Add(this.label2);
+ this.Controls.Add(this.RTB_GARCs);
+ this.Controls.Add(this.CHK_Lang);
+ this.Controls.Add(this.B_PatchCIA);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.textBox1);
+ this.Controls.Add(this.CHKLB_GARCs);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
+ this.MaximizeBox = false;
+ this.MinimizeBox = false;
+ this.Name = "Patch";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "Patch Manager";
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.CheckedListBox CHKLB_GARCs;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Button B_PatchCIA;
+ private System.Windows.Forms.CheckBox CHK_Lang;
+ private System.Windows.Forms.RichTextBox RTB_GARCs;
+ private System.Windows.Forms.Label label2;
+ }
+}
\ No newline at end of file
diff --git a/pk3DS/Subforms/Patch.cs b/pk3DS/Subforms/Patch.cs
new file mode 100644
index 0000000..297678c
--- /dev/null
+++ b/pk3DS/Subforms/Patch.cs
@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Specialized;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+
+namespace pk3DS
+{
+ public partial class Patch : Form
+ {
+ public Patch()
+ {
+ InitializeComponent();
+ RTB_GARCs.Clear();
+ CHKLB_GARCs.Items.Clear();
+ foreach (string s in Main.allGARCs)
+ CHKLB_GARCs.Items.Add(s);
+ }
+
+ internal static bool patchExeFS(string path, string[] oldstr, string[] newstr, ref string result, string outPath = null)
+ {
+ int ctr = 0;
+ if (oldstr.Length != newstr.Length)
+ {
+ result = "Input replacements do not match output replacements.";
+ return false;
+ }
+
+ string text = File.ReadAllText(path, Encoding.Unicode);
+ for (int i = 0; i < oldstr.Length; i++)
+ {
+ if (!text.Contains(oldstr[i]))
+ result += "Does not contain " + oldstr + Environment.NewLine;
+ else
+ ctr++;
+
+ text = text.Replace(oldstr[i], newstr[i]);
+ }
+
+ if (ctr == 0)
+ { result = "Did not find the old path strings to replace."; return false; }
+ result += String.Format("Redirected {0} file paths.", ctr);
+ File.WriteAllText(outPath ?? path, text, Encoding.Unicode);
+ return true;
+ }
+ internal static string exportGARCs(string[] garcPaths, string[] newPaths, string parentRomFS, string patchFolder)
+ {
+ if (Directory.Exists(patchFolder))
+ Directory.Delete(patchFolder, true);
+ Directory.CreateDirectory(patchFolder);
+
+ // Stuff files into new patch folder
+ for (int i = 0; i < garcPaths.Length; i++)
+ {
+ if ((garcPaths[i] ?? "").Length == 0) continue;
+ string folder = Path.GetDirectoryName(newPaths[i]);
+ Directory.CreateDirectory(folder);
+ File.Copy(Path.Combine(parentRomFS, garcPaths[i]), folder);
+ }
+ return patchFolder;
+ }
+
+ private void B_PatchCIA_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ string[] garcs = getGARCs();
+ string[] garcPaths = getPaths(garcs);
+
+ const string oldROM = "rom:/a/";
+ const string newROM = "rom2:/a";
+
+ string[] newPaths = (string[]) garcPaths.Clone();
+
+ // Patch the reference
+ for (int i = 0; i < newPaths.Length; i++)
+ {
+ int posA = newPaths[i].LastIndexOf(oldROM, StringComparison.Ordinal);
+ newPaths[i] = (posA == -1) ? null : newPaths[i].Remove(posA, oldROM.Length).Insert(posA, newROM);
+ }
+ string patchFolder = String.Format("{0} ({1})", "Patch", new DateTime().ToString("yyMMdd@HHmmss"));
+ string result = "";
+ if (!patchExeFS(Main.ExeFSPath, garcPaths, newPaths, ref result, Path.Combine(patchFolder, ".code.bin")))
+ return;
+
+ Util.Alert("Patch contents saved to:" + Environment.NewLine + exportGARCs(garcPaths, newPaths, Main.RomFSPath, patchFolder), result);
+ }
+ catch (Exception ex)
+ { Util.Error("Could not create patch:", ex.ToString()); }
+ }
+
+ private string[] getGARCs()
+ {
+ StringCollection sc = new StringCollection();
+ foreach (int indexChecked in CHKLB_GARCs.CheckedIndices)
+ sc.Add(CHKLB_GARCs.Items[indexChecked].ToString());
+
+ string[] rtbLines = RTB_GARCs.Lines;
+ foreach (string s in rtbLines.Where(s => s.Length == 7 && !sc.Contains(s.Replace('/', Path.DirectorySeparatorChar))))
+ sc.Add(s.Replace('/', Path.DirectorySeparatorChar));
+
+ string[] garcs = new string[sc.Count];
+ sc.CopyTo(garcs, 0);
+ return garcs;
+ }
+ private string[] getPaths(string[] sc)
+ {
+ bool languages = CHK_Lang.Checked;
+ StringCollection paths = new StringCollection();
+ foreach (string s in sc)
+ if (!languages || (s != "gametext" || s != "storytext"))
+ paths.Add(Main.getGARCFileName(s, Main.Language));
+ else
+ for (int l = 0; l < 8; l++)
+ paths.Add(Main.getGARCFileName(s, l));
+
+ string[] garcs = new string[paths.Count];
+ paths.CopyTo(garcs, 0);
+ return garcs;
+ }
+ }
+}
diff --git a/pk3DS/Subforms/Patch.resx b/pk3DS/Subforms/Patch.resx
new file mode 100644
index 0000000..1af7de1
--- /dev/null
+++ b/pk3DS/Subforms/Patch.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/pk3DS/pk3DS.csproj b/pk3DS/pk3DS.csproj
index f5137c0..c732edb 100644
--- a/pk3DS/pk3DS.csproj
+++ b/pk3DS/pk3DS.csproj
@@ -65,6 +65,12 @@
+
+ Form
+
+
+ Patch.cs
+
Form
@@ -207,6 +213,9 @@
Main.cs
+
+ Patch.cs
+
TitleScreen.cs