diff --git a/MP1_Trilogy_Rando_Generator/Form1.Designer.cs b/MP1_Trilogy_Rando_Generator/Form1.Designer.cs index 183a823..2c03f1b 100644 --- a/MP1_Trilogy_Rando_Generator/Form1.Designer.cs +++ b/MP1_Trilogy_Rando_Generator/Form1.Designer.cs @@ -114,8 +114,7 @@ private void InitializeComponent() this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(766, 33); this.label1.TabIndex = 0; - this.label1.Text = "No Trilogy ISO template for Prime 1 Randomizer detected! (Only NTSC-U supported f" + - "or now)"; + this.label1.Text = "No Metroid Prime Wii ISO template for Prime 1 Randomizer detected!"; this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // tableLayoutPanel7 @@ -154,7 +153,7 @@ private void InitializeComponent() this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(380, 36); this.button1.TabIndex = 2; - this.button1.Text = "Generate a template ISO for Prime 1 Randomizer"; + this.button1.Text = "Generate a template ISO for BashPrime\'s Randomizer"; this.button1.UseVisualStyleBackColor = true; this.button1.Click += new System.EventHandler(this.button1_Click); // @@ -223,7 +222,7 @@ private void InitializeComponent() this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(766, 29); this.label2.TabIndex = 1; - this.label2.Text = "BashPrime\'s Randomizer not found! (v2.5.0 or later required)"; + this.label2.Text = "BashPrime\'s Randomizer not found! (v2.6.0 or later required)"; this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; // // tableLayoutPanel5 @@ -317,8 +316,8 @@ private void InitializeComponent() // tableLayoutPanel4 // this.tableLayoutPanel4.ColumnCount = 2; - this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); - this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 60F)); + this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 40F)); this.tableLayoutPanel4.Controls.Add(this.label3, 0, 0); this.tableLayoutPanel4.Controls.Add(this.progressBar1, 1, 0); this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill; @@ -327,7 +326,6 @@ private void InitializeComponent() this.tableLayoutPanel4.Name = "tableLayoutPanel4"; this.tableLayoutPanel4.RowCount = 1; this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tableLayoutPanel4.Size = new System.Drawing.Size(784, 26); this.tableLayoutPanel4.TabIndex = 5; // @@ -336,7 +334,7 @@ private void InitializeComponent() this.label3.Dock = System.Windows.Forms.DockStyle.Fill; this.label3.Location = new System.Drawing.Point(3, 0); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(386, 26); + this.label3.Size = new System.Drawing.Size(464, 26); this.label3.TabIndex = 5; this.label3.Text = "Status : Idle"; this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; @@ -344,9 +342,9 @@ private void InitializeComponent() // progressBar1 // this.progressBar1.Dock = System.Windows.Forms.DockStyle.Fill; - this.progressBar1.Location = new System.Drawing.Point(395, 3); + this.progressBar1.Location = new System.Drawing.Point(473, 3); this.progressBar1.Name = "progressBar1"; - this.progressBar1.Size = new System.Drawing.Size(386, 20); + this.progressBar1.Size = new System.Drawing.Size(308, 20); this.progressBar1.TabIndex = 6; this.progressBar1.Visible = false; // @@ -364,8 +362,9 @@ private void InitializeComponent() this.MinimumSize = new System.Drawing.Size(800, 355); this.Name = "Form1"; this.ShowIcon = false; - this.Text = "Metroid Prime 1 - Trilogy Rando Generator v1.7"; + this.Text = "Metroid Prime 1 - Trilogy Rando Generator v1.8"; this.HelpButtonClicked += new System.ComponentModel.CancelEventHandler(this.helpBtn_Click); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.formClosing); this.Load += new System.EventHandler(this.Form1_Load); this.tableLayoutPanel1.ResumeLayout(false); this.groupBox1.ResumeLayout(false); diff --git a/MP1_Trilogy_Rando_Generator/Form1.cs b/MP1_Trilogy_Rando_Generator/Form1.cs index c5a43df..72f5563 100644 --- a/MP1_Trilogy_Rando_Generator/Form1.cs +++ b/MP1_Trilogy_Rando_Generator/Form1.cs @@ -1,8 +1,8 @@ -using MP1_Trilogy_Rando_Generator.Patcher; -using MP1_Trilogy_Rando_Generator.Utils; +using MP1_Trilogy_Rando_Generator.Utils; using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; using System.IO; using System.IO.Compression; using System.Linq; @@ -18,17 +18,37 @@ public partial class Form1 : Form static readonly List UsedDeveloperCodes = new List(); bool IsTemplateISOGenerated() { - return File.Exists("gc_template.iso") && Directory.Exists(".\\tmp\\wii"); + try + { + return File.Exists("gc_template.iso") && + Directory.Exists(".\\tmp\\wii") && + (IsMetroidPrimeTrilogyNTSC_UOrPAL(".\\tmp\\wii\\DATA\\sys\\boot.bin") || IsMetroidPrimeWiiNTSC_J(".\\tmp\\wii\\DATA\\sys\\boot.bin")); + } catch { + return false; + } + } + + bool IsMetroidPrimeTrilogyNTSC_UOrPAL(string fileName) + { + String GameID = GetGameID(fileName); + if (GameID.Substring(0, 3) != "R3M") + return false; + return GameID[3] == 'E' || GameID[3] == 'P'; + } + + bool IsMetroidPrimeWiiNTSC_J(string fileName) + { + String GameID = GetGameID(fileName); + return GameID.Substring(0, 3) == "R3I" && GameID[3] == 'J'; } - bool IsMetroidPrimeTrilogyNTSC(string fileName) + String GetGameID(string fileName) { + if (!File.Exists(fileName)) + return ""; using (var bR = new BinaryReader(File.OpenRead(fileName))) { - String GameID = Encoding.ASCII.GetString(bR.ReadBytes(6)); - if (GameID.Substring(0, 3) != "R3M") - return false; - return GameID[3] == 'E'; + return Encoding.ASCII.GetString(bR.ReadBytes(6)); } } @@ -83,7 +103,7 @@ private void Form1_Load(object sender, EventArgs e) UsedDeveloperCodes.AddRange(File.ReadAllLines("udc.bin")); if (IsTemplateISOGenerated()) { - this.label1.Text = "Trilogy ISO template for Prime 1 Randomizer detected!"; + this.label1.Text = "Metroid Prime Wii ISO template for Prime 1 Randomizer detected!"; this.button1.Enabled = false; this.button2.Enabled = true; } @@ -122,6 +142,7 @@ private void Form1_Load(object sender, EventArgs e) private void button1_Click(object sender, EventArgs e) { var wii_iso_path = default(String); + var GameID = default(String); MessageBox.Show(@"/!\ This operation can take 10 mins or more on a 5400 RPM HDD. So please be patient!"); @@ -144,12 +165,13 @@ private void button1_Click(object sender, EventArgs e) MessageBox.Show("Select a Wii iso"); continue; } - if (!IsMetroidPrimeTrilogyNTSC(openFileDialog.FileName)) + if (!IsMetroidPrimeTrilogyNTSC_UOrPAL(openFileDialog.FileName) && !IsMetroidPrimeWiiNTSC_J(openFileDialog.FileName)) { openFileDialog.FileName = ""; - MessageBox.Show("Select a Metroid Prime Trilogy NTSC-U iso"); + MessageBox.Show("Select a Metroid Prime Wii iso (NTSC-U/NTSC-J/PAL)"); continue; } + GameID = GetGameID(openFileDialog.FileName); wii_iso_path = openFileDialog.FileName; } if (dialogResult == DialogResult.Cancel) @@ -158,7 +180,7 @@ private void button1_Click(object sender, EventArgs e) } SetProgressStatus(0, 5); - SetStatus("Extracting Metroid Prime Trilogy ISO..."); + SetStatus("Extracting Metroid Prime Wii ISO..."); if (wii_iso_path.ToLower().EndsWith(".nkit.iso") || wii_iso_path.ToLower().EndsWith(".nkit.gcz")) { if (!NKitManager.ExtractISO(wii_iso_path)) @@ -170,7 +192,12 @@ private void button1_Click(object sender, EventArgs e) } try { - File.WriteAllBytes(@".\tmp\nkit\nkit_files.zip", Properties.Resources.R3ME01_nkit); + if(GameID == "R3ME01") + File.WriteAllBytes(@".\tmp\nkit\nkit_files.zip", Properties.Resources.R3ME01_nkit); + if (GameID == "R3MP01") + File.WriteAllBytes(@".\tmp\nkit\nkit_files.zip", Properties.Resources.R3MP01_nkit); + if (GameID == "R3IJ01") + File.WriteAllBytes(@".\tmp\nkit\nkit_files.zip", Properties.Resources.R3IJ01_nkit); ZipFile.ExtractToDirectory(@".\tmp\nkit\nkit_files.zip", @".\tmp\nkit\DATA"); File.Move(@".\tmp\nkit\DATA\files\main.dol", @".\tmp\nkit\DATA\sys\main.dol"); File.Delete(@".\tmp\nkit\nkit_files.zip"); @@ -205,44 +232,62 @@ private void button1_Click(object sender, EventArgs e) } SetProgressStatus(1, 5); - SetStatus("Backing up DOLs from Metroid Prime Trilogy..."); + SetStatus("Backing up original DOLs..."); if (!Directory.Exists(".\\tmp\\dol_backup\\")) Directory.CreateDirectory(".\\tmp\\dol_backup\\"); - File.Copy(".\\tmp\\wii\\DATA\\files\\rs5mp1_p.dol", ".\\tmp\\dol_backup\\rs5mp1_p.dol", true); + if(GameID == "R3IJ01") + File.Copy(".\\tmp\\wii\\DATA\\files\\rs5mp1jpn_p.dol", ".\\tmp\\dol_backup\\rs5mp1jpn_p.dol", true); + else + File.Copy(".\\tmp\\wii\\DATA\\files\\rs5mp1_p.dol", ".\\tmp\\dol_backup\\rs5mp1_p.dol", true); File.Copy(".\\tmp\\wii\\DATA\\files\\rs5fe_p.dol", ".\\tmp\\dol_backup\\rs5fe_p.dol", true); SetProgressStatus(2, 5); - SetStatus("Stripping MP2 and MP3 from Metroid Prime Trilogy..."); - - FileUtils.NullifyFiles(".\\tmp\\wii\\DATA\\files\\MP2", true); - FileUtils.NullifyFiles(".\\tmp\\wii\\DATA\\files\\MP3", true); - FileUtils.NullifyFiles(".\\tmp\\wii\\DATA\\files\\", "*.dol", "rs5mp1_p.dol", "rs5fe_p.dol"); - File.WriteAllBytes(".\\tmp\\wii\\DATA\\files\\fe\\Video\\FrontEnd\\attract01.thp", Properties.Resources.dummy); - File.WriteAllBytes(".\\tmp\\wii\\DATA\\files\\fe\\Video\\FrontEnd\\Attract02.thp", Properties.Resources.dummy); + SetStatus("Stripping unnecessary files from Metroid Prime ISO..."); File.WriteAllBytes(".\\tmp\\wii\\DATA\\files\\fe\\Video\\mp1\\attract01.thp", Properties.Resources.dummy); File.WriteAllBytes(".\\tmp\\wii\\DATA\\files\\fe\\Video\\mp1\\Attract02.thp", Properties.Resources.dummy); - Directory.Delete(".\\tmp\\wii\\DATA\\files\\fe\\Video\\mp2", true); - foreach (var file in Directory.EnumerateFiles(".\\tmp\\wii\\DATA\\files\\fe\\Video\\FrontEnd", "Menu_To_Game_MP2_*.thp")) - File.Delete(file); - foreach (var file in Directory.EnumerateFiles(".\\tmp\\wii\\DATA\\files\\fe\\Video\\FrontEnd", "Menu_To_Game_MP3_*.thp")) - File.Delete(file); Directory.Delete(".\\tmp\\wii\\DATA\\files\\fe\\Audio\\MP1_Bonus", true); - Directory.Delete(".\\tmp\\wii\\DATA\\files\\fe\\Audio\\MP2_Bonus", true); - Directory.Delete(".\\tmp\\wii\\DATA\\files\\fe\\Audio\\MP3_Bonus", true); + if (GameID != "R3IJ01") + { + File.WriteAllBytes(".\\tmp\\wii\\DATA\\files\\fe\\Video\\FrontEnd\\attract01.thp", Properties.Resources.dummy); + File.WriteAllBytes(".\\tmp\\wii\\DATA\\files\\fe\\Video\\FrontEnd\\Attract02.thp", Properties.Resources.dummy); + FileUtils.NullifyFiles(".\\tmp\\wii\\DATA\\files\\MP2", true); + FileUtils.NullifyFiles(".\\tmp\\wii\\DATA\\files\\MP3", true); + Directory.Delete(".\\tmp\\wii\\DATA\\files\\fe\\Video\\mp2", true); + foreach (var file in Directory.EnumerateFiles(".\\tmp\\wii\\DATA\\files\\fe\\Video\\FrontEnd", "Menu_To_Game_MP2_*.thp")) + File.Delete(file); + foreach (var file in Directory.EnumerateFiles(".\\tmp\\wii\\DATA\\files\\fe\\Video\\FrontEnd", "Menu_To_Game_MP3_*.thp")) + File.Delete(file); + Directory.Delete(".\\tmp\\wii\\DATA\\files\\fe\\Audio\\MP2_Bonus", true); + Directory.Delete(".\\tmp\\wii\\DATA\\files\\fe\\Audio\\MP3_Bonus", true); + FileUtils.NullifyFiles(".\\tmp\\wii\\DATA\\files\\", "*.dol", "rs5mp1_p.dol", "rs5fe_p.dol"); + } + else + FileUtils.NullifyFiles(".\\tmp\\wii\\DATA\\files\\", "*.dol", "rs5mp1jpn_p.dol", "rs5fe_p.dol"); SetProgressStatus(3, 5); - SetStatus("Copying resources from Metroid Prime Trilogy to Template ISO..."); + SetStatus("Copying resources from Metroid Prime Wii to Template ISO..."); Directory.CreateDirectory(".\\tmp\\gc\\files"); Directory.CreateDirectory(".\\tmp\\gc\\sys"); - DirectoryUtils.Copy(".\\tmp\\wii\\DATA\\files\\MP1", ".\\tmp\\gc\\files\\", true); + if (GameID == "R3IJ01") + { + DirectoryUtils.Copy(".\\tmp\\wii\\DATA\\files\\MP1JPN", ".\\tmp\\gc\\files\\", true); + File.Copy(".\\tmp\\dol_backup\\rs5mp1jpn_p.dol", ".\\tmp\\gc\\files\\default.dol", true); + } + else + { + DirectoryUtils.Copy(".\\tmp\\wii\\DATA\\files\\MP1", ".\\tmp\\gc\\files\\", true); + File.Copy(".\\tmp\\dol_backup\\rs5mp1_p.dol", ".\\tmp\\gc\\files\\default.dol", true); + } Directory.Delete(".\\tmp\\gc\\files\\RSO", true); Directory.Delete(".\\tmp\\gc\\files\\rhbm", true); - File.Copy(".\\tmp\\dol_backup\\rs5mp1_p.dol", ".\\tmp\\gc\\files\\default.dol", true); DirectoryUtils.Copy(".\\tmp\\wii\\DATA\\sys", ".\\tmp\\gc\\sys\\", true); - File.Copy(".\\tmp\\dol_backup\\rs5mp1_p.dol", ".\\tmp\\gc\\sys\\main.dol", true); + if (GameID == "R3IJ01") + File.Copy(".\\tmp\\dol_backup\\rs5mp1jpn_p.dol", ".\\tmp\\gc\\sys\\main.dol", true); + else + File.Copy(".\\tmp\\dol_backup\\rs5mp1_p.dol", ".\\tmp\\gc\\sys\\main.dol", true); FileUtils.Write(".\\tmp\\gc\\sys\\boot.bin", 0x18, (UInt32)0, true); FileUtils.Write(".\\tmp\\gc\\sys\\boot.bin", 0x1C, (UInt32)0xC2339F3D, true); File.WriteAllBytes(".\\tmp\\gc\\files\\Video\\02_start_fileselect_A.thp", Properties.Resources.dummy); @@ -253,15 +298,15 @@ private void button1_Click(object sender, EventArgs e) File.WriteAllBytes(".\\tmp\\gc\\files\\Video\\04_fileselect_playgame_C.thp", Properties.Resources.dummy); SetProgressStatus(4, 5); - SetStatus("Creating Trilogy ISO template to be used with BashPrime's Randomizer"); + SetStatus("Creating Metroid Prime Wii ISO template to be used with BashPrime's Randomizer"); - NodManager.CreateISO("gc_template.iso", true, FileUtils.Read(".\\tmp\\gc\\sys\\boot.bin", 0, 6) as String); + NodManager.CreateISO("gc_template.iso", true, GameID); SetProgressStatus(5, 5); SetStatus("Idle"); Directory.Delete(".\\tmp\\gc", true); - this.label1.Text = "Trilogy ISO template for BashPrime's Randomizer detected!"; + this.label1.Text = "Metroid Prime Wii ISO template for BashPrime's Randomizer detected!"; this.button1.Enabled = false; this.button2.Enabled = true; } @@ -270,7 +315,7 @@ private void button2_Click(object sender, EventArgs e) { File.Delete("gc_template.iso"); Directory.Delete("tmp", true); - this.label1.Text = "No Trilogy ISO template for BashPrime's Randomizer detected! (Only NTSC - U supported for now)"; + this.label1.Text = "No Metroid Prime Wii ISO template for BashPrime's Randomizer detected!"; this.button1.Enabled = true; this.button2.Enabled = false; } @@ -315,17 +360,24 @@ private void button4_Click(object sender, EventArgs e) var new_wii_iso_path = default(String); var gc_iso_filename = default(String); var spoiler_filename = default(String); - var DevCode = default(String); + var GameID = default(String); + var PatchedGameID = default(String); + var Pak_Path = default(String); String GameSettingsDolphinEmuPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + Path.DirectorySeparatorChar+ "Dolphin Emulator" + Path.DirectorySeparatorChar + "GameSettings" + Path.DirectorySeparatorChar; String curDir = Directory.GetCurrentDirectory(); if (!IsTemplateISOGenerated()) { - MessageBox.Show("Please click on \"Generate a template ISO for Prime 1 Randomizer\" before attempting to randomize!"); + MessageBox.Show("Please click on \"Generate a template ISO for BashPrime's Randomizer\" before attempting to randomize!"); return; } + if (!IsMetroidPrimeTrilogyNTSC_UOrPAL("gc_template.iso") && !IsMetroidPrimeWiiNTSC_J("gc_template.iso")) + return; + + GameID = GetGameID("gc_template.iso"); + if (appSettings.prime1RandomizerPath == "" || !File.Exists(appSettings.prime1RandomizerPath)) { MessageBox.Show("Please click on \"Locate BashPrime's Randomizer\" before attempting to randomize!"); @@ -351,7 +403,7 @@ private void button4_Click(object sender, EventArgs e) SetStatus("Running BashPrime's Randomizer..."); if (!RandomizerManager.Run(appSettings.prime1RandomizerPath)) { - MessageBox.Show("Prime 1 Randomizer haven't properly exited! Cancelling..."); + MessageBox.Show("BashPrime's Randomizer hasn't properly exited! Cancelling..."); patchSettingsBak.SaveToJson(); SetProgressStatus(5, 5); SetStatus("Idle"); @@ -392,14 +444,21 @@ private void button4_Click(object sender, EventArgs e) SetProgressStatus(2, 5); SetStatus("Replacing original PAKs with randomized PAKs...", i, gc_iso_files.Length); + Pak_Path = ".\\tmp\\wii\\DATA\\files\\MP1"; + if (GameID.Substring(2, 2) == "IJ") + Pak_Path += "JPN"; + File.Copy(".\\tmp\\dol_backup\\rs5fe_p.dol", ".\\tmp\\wii\\DATA\\sys\\main.dol", true); File.Copy(".\\tmp\\dol_backup\\rs5fe_p.dol", ".\\tmp\\wii\\DATA\\files\\rs5fe_p.dol", true); - File.Copy(".\\tmp\\dol_backup\\rs5mp1_p.dol", ".\\tmp\\wii\\DATA\\files\\rs5mp1_p.dol", true); + if(GameID[3] == 'J') + File.Copy(".\\tmp\\dol_backup\\rs5mp1jpn_p.dol", ".\\tmp\\wii\\DATA\\files\\rs5mp1jpn_p.dol", true); + else + File.Copy(".\\tmp\\dol_backup\\rs5mp1_p.dol", ".\\tmp\\wii\\DATA\\files\\rs5mp1_p.dol", true); foreach (var file in Directory.EnumerateFiles(".\\tmp\\gc\\files", "Metroid*.pak", SearchOption.TopDirectoryOnly)) - File.Copy(file, ".\\tmp\\wii\\DATA\\files\\MP1\\" + Path.GetFileName(file), true); + File.Copy(file, Pak_Path + "\\" + Path.GetFileName(file), true); - File.Copy(".\\tmp\\gc\\files\\NoARAM.pak", ".\\tmp\\wii\\DATA\\files\\MP1\\NoARAM.pak", true); + File.Copy(".\\tmp\\gc\\files\\NoARAM.pak", Pak_Path + "\\NoARAM.pak", true); File.Copy(".\\tmp\\gc\\files\\randomprime.txt", ".\\tmp\\wii\\DATA\\files\\randomprime.txt", true); Directory.Delete(".\\tmp\\gc", true); @@ -407,8 +466,12 @@ private void button4_Click(object sender, EventArgs e) SetProgressStatus(3, 5); SetStatus("Applying patches to MP1 executable...", i, gc_iso_files.Length); + PatchedGameID = GameID.Substring(0, 4) + RandomizeDeveloperCode(); + /* Applying patches to dol file */ + Patcher.Patcher.Init(PatchedGameID[3]); + if (randomizerSettings.skipFrigate) { if (randomizerSettings.spawnRoom == null) @@ -418,39 +481,45 @@ private void button4_Click(object sender, EventArgs e) SetStatus("Idle"); return; } - Patches.SetStartingArea(randomizerSettings.spawnRoom); + Patcher.Patcher.SetStartingArea(randomizerSettings.spawnRoom); } - DevCode = RandomizeDeveloperCode(); - //new DOL_AddSection_Patch(Patches.MP1_Dol_Path, DOL_AddSection_Patch.SectionType.TEXT, 0x80001800, 0x800).Apply(); //Patches.DisableHintSystem(true); - Patches.ApplySkipCutscenePatch(); - Patches.ApplyHeatProtectionPatch(randomizerSettings.heatProtection); - Patches.ApplySuitDamageReductionPatch(randomizerSettings.suitDamageReduction); - Patches.ApplyScanDashPatch(); - Patches.ApplyUnderwaterSlopeJumpFixPatch(true); - Patches.SetSaveFilename(DevCode + ".bin"); + Patcher.Patcher.ApplySkipCutscenePatch(); + Patcher.Patcher.ApplyHeatProtectionPatch(randomizerSettings.heatProtection); + Patcher.Patcher.ApplySuitDamageReductionPatch(randomizerSettings.suitDamageReduction); + Patcher.Patcher.ApplyScanDashPatch(); + Patcher.Patcher.ApplyUnderwaterSlopeJumpFixPatch(true); + Patcher.Patcher.SetSaveFilename(PatchedGameID.Substring(4, 2) + ".bin"); //Patches.ApplyInputPatch(); /* */ SetProgressStatus(4, 5); - SetStatus("Packing Metroid Prime Trilogy to " + ((String)comboBox1.SelectedItem).Substring(1).ToUpper() + " format...", i, gc_iso_files.Length); + SetStatus("Packing Metroid Prime Wii to " + ((String)comboBox1.SelectedItem).Substring(1).ToUpper() + " format...", i, gc_iso_files.Length); // WIT doesn't like complex paths so make the image in tmp folder then move back to the output folder if (((String)comboBox1.SelectedItem).ToLower().EndsWith(".ciso")) { - WITManager.CreateCompressISO(".\\tmp\\mpt.ciso", false, "R3ME" + DevCode); - if (File.Exists(GameSettingsDolphinEmuPath + "R3ME01.ini") && !File.Exists(GameSettingsDolphinEmuPath + "R3ME" + DevCode + ".ini")) - File.Copy(GameSettingsDolphinEmuPath + "R3ME01.ini", GameSettingsDolphinEmuPath + "R3ME" + DevCode + ".ini"); + WITManager.CreateCompressISO(".\\tmp\\mpt.ciso", false, PatchedGameID); + if (File.Exists(GameSettingsDolphinEmuPath + GameID + ".ini") && !File.Exists(GameSettingsDolphinEmuPath + PatchedGameID + ".ini")) + File.Copy(GameSettingsDolphinEmuPath + GameID + ".ini", GameSettingsDolphinEmuPath + PatchedGameID + ".ini"); } else if (((String)comboBox1.SelectedItem).ToLower().EndsWith(".wbfs")) - WITManager.CreateWBFS(".\\tmp\\mpt.wbfs", "R3ME" + DevCode); + WITManager.CreateWBFS(".\\tmp\\mpt.wbfs", PatchedGameID); if (File.Exists(this.textBox1.Text + "\\" + Path.GetFileNameWithoutExtension(gc_iso_filename) + (String)comboBox1.SelectedItem)) File.Delete(this.textBox1.Text + "\\" + Path.GetFileNameWithoutExtension(gc_iso_filename) + (String)comboBox1.SelectedItem); - File.Move(".\\tmp\\mpt" + (String)comboBox1.SelectedItem, this.textBox1.Text + "\\" + Path.GetFileNameWithoutExtension(gc_iso_filename) + (String)comboBox1.SelectedItem); + if ((String)comboBox1.SelectedItem == ".wbfs") + new_wii_iso_path = this.textBox1.Text + "\\" + Path.GetFileNameWithoutExtension(gc_iso_filename) + "["+ PatchedGameID + "]\\" + PatchedGameID + ".wbfs"; + else + new_wii_iso_path = this.textBox1.Text + "\\" + Path.GetFileNameWithoutExtension(gc_iso_filename) + (String)comboBox1.SelectedItem; + + if (!Directory.Exists(Path.GetDirectoryName(new_wii_iso_path))) + Directory.CreateDirectory(Path.GetDirectoryName(new_wii_iso_path)); + + File.Move(".\\tmp\\mpt" + (String)comboBox1.SelectedItem, new_wii_iso_path); if (File.Exists(".\\tmp" + spoiler_filename)) { @@ -496,5 +565,11 @@ private void helpBtn_Click(object sender, CancelEventArgs e) } e.Cancel = true; } + + private void formClosing(object sender, FormClosingEventArgs e) + { + // Closing any nod or wit application running + ProcessUtils.KillChildrenProcesses(Process.GetCurrentProcess().Id); + } } } diff --git a/MP1_Trilogy_Rando_Generator/MP1_Trilogy_Rando_Generator.csproj b/MP1_Trilogy_Rando_Generator/MP1_Trilogy_Rando_Generator.csproj index 8eecd4b..0ac91b3 100644 --- a/MP1_Trilogy_Rando_Generator/MP1_Trilogy_Rando_Generator.csproj +++ b/MP1_Trilogy_Rando_Generator/MP1_Trilogy_Rando_Generator.csproj @@ -47,6 +47,7 @@ True True + @@ -75,9 +76,12 @@ HelpForm.cs - - - + + + + + + @@ -86,9 +90,7 @@ - - - + @@ -109,7 +111,9 @@ True + + SettingsSingleFileGenerator @@ -124,7 +128,9 @@ - + + + diff --git a/MP1_Trilogy_Rando_Generator/NKitManager.cs b/MP1_Trilogy_Rando_Generator/NKitManager.cs index b92df44..d916a13 100644 --- a/MP1_Trilogy_Rando_Generator/NKitManager.cs +++ b/MP1_Trilogy_Rando_Generator/NKitManager.cs @@ -22,7 +22,9 @@ public static bool ExtractISO(string filename) { if (ndisc == null) throw new System.Exception(); - if (ndisc.ExtractBasicInfo().Id.Substring(0,6) != "R3ME01") + if (ndisc.ExtractBasicInfo().Id.Substring(0, 6) != "R3ME01" && + ndisc.ExtractBasicInfo().Id.Substring(0, 6) != "R3MP01" && + ndisc.ExtractBasicInfo().Id.Substring(0, 6) != "R3IJ01") throw new System.Exception(); ndisc.ExtractFiles(ext_f => true, (f, ext_f) => diff --git a/MP1_Trilogy_Rando_Generator/Patcher/DOL_AddSection_Patch.cs b/MP1_Trilogy_Rando_Generator/Patcher/DOL_AddSection_Patch.cs deleted file mode 100644 index 82bc879..0000000 --- a/MP1_Trilogy_Rando_Generator/Patcher/DOL_AddSection_Patch.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MP1_Trilogy_Rando_Generator.Patcher -{ - class DOL_AddSection_Patch : IDolPatch - { - public enum SectionType { - TEXT, - DATA - } - private readonly String Path; - private readonly UInt32 Address; - private readonly UInt32 Size; - private readonly SectionType Type; - - public DOL_AddSection_Patch(String path, SectionType type, UInt32 mem_addr, UInt32 size) : base(path) - { - this.Path = path; - this.Address = mem_addr; - this.Size = size; - this.Type = type; - } - - internal void AddTextSection() - { - if (this.textSections.Count + 1 > 7) - throw new Exception("Too much text sections are present! Cannot add a new text section"); - int i = this.textSections.Count; - UInt32 size = (UInt32)new FileInfo(this.Path).Length; - - using (var file = File.OpenWrite(this.Path)) - using (var writer = new BinaryWriter(file)) - { - writer.BaseStream.Position = i * 4; - writer.Write(BitConverter.GetBytes(size).Reverse().ToArray()); - writer.BaseStream.Position = 0x48 + i * 4; - writer.Write(BitConverter.GetBytes(this.Address).Reverse().ToArray()); - writer.BaseStream.Position = 0x90 + i * 4; - writer.Write(BitConverter.GetBytes(this.Size).Reverse().ToArray()); - - writer.BaseStream.Position = size; - for (i = 0; i < this.Size; i++) - writer.Write(0); - } - } - - internal void AddDataSection() - { - if (this.dataSections.Count + 1 > 11) - throw new Exception("Too much data sections are present! Cannot add a new data section"); - int i = this.textSections.Count; - UInt32 size = (UInt32)new FileInfo(this.Path).Length; - - using (var file = File.OpenWrite(this.Path)) - using (var writer = new BinaryWriter(file)) - { - writer.BaseStream.Position = 0x1C + i * 4; - writer.Write(BitConverter.GetBytes(size).Reverse().ToArray()); - writer.BaseStream.Position = 0x64 + i * 4; - writer.Write(BitConverter.GetBytes(this.Address).Reverse().ToArray()); - writer.BaseStream.Position = 0xAC + i * 4; - writer.Write(BitConverter.GetBytes(this.Size).Reverse().ToArray()); - - writer.BaseStream.Position = size; - for (i = 0; i < this.Size; i++) - writer.Write(0); - } - } - - internal override void Apply() - { - if (!File.Exists(this.Path)) - throw new FileNotFoundException(this.Path + " doesn't exist"); - if (this.Type == SectionType.TEXT) - this.AddTextSection(); - else if (this.Type == SectionType.DATA) - this.AddDataSection(); - else - throw new Exception("Unknown type of section"); - } - } -} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/DOL_Patch.cs b/MP1_Trilogy_Rando_Generator/Patcher/DOL_Patch.cs deleted file mode 100644 index b2ac712..0000000 --- a/MP1_Trilogy_Rando_Generator/Patcher/DOL_Patch.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; - -namespace MP1_Trilogy_Rando_Generator.Patcher -{ - class DOL_Patch : IDolPatch - { - private readonly String Path; - private readonly UInt32 Address; - private readonly Object Value; - - public DOL_Patch(String path, UInt32 addr, T val) : base(path) - { - this.Path = path; - this.Address = addr; - this.Value = val; - } - - bool OverwriteBytes(String filePath, UInt32 off, Object val) - { - try - { - byte[] buf = null; - if (val.GetType() == typeof(Int16)) - buf = BitConverter.GetBytes((Int16)val).Reverse().ToArray(); - if (val.GetType() == typeof(Int32)) - buf = BitConverter.GetBytes((Int32)val).Reverse().ToArray(); - if (val.GetType() == typeof(Int64)) - buf = BitConverter.GetBytes((Int64)val).Reverse().ToArray(); - if (val.GetType() == typeof(Byte)) - buf = new byte[] { (Byte)val }; - if (val.GetType() == typeof(UInt16)) - buf = BitConverter.GetBytes((UInt16)val).Reverse().ToArray(); - if (val.GetType() == typeof(UInt32)) - buf = BitConverter.GetBytes((UInt32)val).Reverse().ToArray(); - if (val.GetType() == typeof(UInt64)) - buf = BitConverter.GetBytes((UInt64)val).Reverse().ToArray(); - if (val.GetType() == typeof(Char)) - buf = new byte[] { (Byte)val }; - if (val.GetType() == typeof(Single)) - buf = BitConverter.GetBytes((Single)val).Reverse().ToArray(); - if (val.GetType() == typeof(Double)) - buf = BitConverter.GetBytes((Double)val).Reverse().ToArray(); - if (val.GetType() == typeof(String)) - buf = Encoding.ASCII.GetBytes(((String)val).ToCharArray(), 0, ((String)val).Length); - - using (var bW = new BinaryWriter(File.OpenWrite(filePath))) - { - bW.BaseStream.Position = this.GetFileAddress(off); - if (bW.BaseStream.Position == 0) - throw new Exception("Cannot patch at "+String.Format("0x{0:X8}", off)+"!\nMemory block isn't pre initialized!"); - if (buf != null) - bW.Write(buf); - } - return true; - } - catch - { - return false; - } - } - - internal override void Apply() - { - if (!OverwriteBytes(this.Path, this.Address, this.Value)) - { - Console.WriteLine("Failed to patch " + this.Path + "!"); - return; - } - } - } -} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/DOL_ScrollCode_Patch.cs b/MP1_Trilogy_Rando_Generator/Patcher/DOL_ScrollCode_Patch.cs deleted file mode 100644 index e4d9cf6..0000000 --- a/MP1_Trilogy_Rando_Generator/Patcher/DOL_ScrollCode_Patch.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; - -namespace MP1_Trilogy_Rando_Generator.Patcher -{ - class DOL_ScrollCode_Patch : IDolPatch - { - private readonly String Path; - private readonly UInt32 StartAddress; - private readonly UInt32 EndAddress; - private readonly Int32 Offset; - - public DOL_ScrollCode_Patch(String path, UInt32 start, UInt32 end, Int32 offset) : base(path) - { - var tmp = default(UInt32); - if(start > end) - { - tmp = end; - end = start; - start = tmp; - } - if(this.GetFileAddress((UInt32)(start + offset)) == 0 || - this.GetFileAddress((UInt32)(end + offset)) == 0) - throw new Exception("addr out of memory boundaries"); - this.Path = path; - this.StartAddress = start; - this.EndAddress = end; - this.Offset = offset; - } - - // [A3C - AA0] -= 4 - internal override void Apply() - { - var len = default(Int32); - var bytes = default(UInt32[]); - var i = default(Int32); - if(this.StartAddress % 4 != 0) - throw new Exception("StartAddress must be aligned to 4 bytes"); - if(this.EndAddress % 4 != 0) - throw new Exception("EndAddress must be aligned to 4 bytes"); - - len = (Int32)(EndAddress - StartAddress)/4; - bytes = new UInt32[len]; - - i = 0; - using (var file = File.OpenRead(Path)) - using (var bR = new BinaryReader(file)) - { - bR.BaseStream.Position = this.GetFileAddress(StartAddress); - if(bR.BaseStream.Position == 0) - throw new Exception("Cannot patch at " + String.Format("0x{0:X8}", StartAddress) + "!\nMemory block isn't pre initialized!"); - while (i < len) - bytes[i++] = BitConverter.ToUInt32(bR.ReadBytes(4), 0); - } - - i = 0; - using (var file = File.OpenWrite(Path)) - using (var bW = new BinaryWriter(file)) - { - bW.BaseStream.Position = this.GetFileAddress((UInt32)(StartAddress + Offset)); - if (bW.BaseStream.Position == 0) - throw new Exception("Cannot patch at " + String.Format("0x{0:X8}", StartAddress+Offset) + "!\nMemory block isn't pre initialized!"); - while(i + { + protected struct MemSection + { + public UInt32 FileAddress; + public UInt32 MemoryAddress; + public UInt32 Size; + } + + public enum PatchType + { + AddSection, + BytePatching, + ScrollCode + } + + public enum SectionType + { + TEXT, + DATA + } + + protected List textSections = new List(); + protected List dataSections = new List(); + + #region Add Section properties + private readonly UInt32 StartAddress; + private readonly UInt32 EndAddress; + private readonly Int32 Offset; + #endregion + + #region Byte Patching properties + private readonly UInt32 Address; + private readonly Object Value; + #endregion + + #region Scroll Code properties + private readonly UInt32 Size; + private readonly SectionType _SectionType; + #endregion + + private readonly String Path; + private readonly PatchType _PatchType; + + public DolPatch(String path) + { + int i = 0; + MemSection section = default(MemSection); + + if (!File.Exists(path)) + throw new FileNotFoundException(this.Path + " doesn't exist"); + + this.Path = path; + + using (var file = File.OpenRead(this.Path)) + using (var reader = new BinaryReader(file)) + { + for (i = 0; i < 7; i++) + { + section = new MemSection(); + reader.BaseStream.Position = i * 4; + section.FileAddress = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); + if (section.FileAddress != 0) + { + reader.BaseStream.Position = 0x48 + i * 4; + section.MemoryAddress = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); + reader.BaseStream.Position = 0x90 + i * 4; + section.Size = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); + textSections.Add(section); + } + } + for (i = 0; i < 11; i++) + { + section = new MemSection(); + reader.BaseStream.Position = 0x1C + i * 4; + section.FileAddress = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); + if (section.FileAddress != 0) + { + reader.BaseStream.Position = 0x64 + i * 4; + section.MemoryAddress = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); + reader.BaseStream.Position = 0xAC + i * 4; + section.Size = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); + dataSections.Add(section); + } + } + } + } + + public DolPatch(String path, UInt32 start, UInt32 end, Int32 offset) : this(path) + { + var tmp = default(UInt32); + if (start > end) + { + tmp = end; + end = start; + start = tmp; + } + if (this.GetFileAddress((UInt32)(start + offset)) == 0 || + this.GetFileAddress((UInt32)(end + offset)) == 0) + throw new Exception("addr out of memory boundaries"); + this.StartAddress = start; + this.EndAddress = end; + this.Offset = offset; + this._PatchType = PatchType.ScrollCode; + } + + public DolPatch(String path, SectionType type, UInt32 mem_addr, UInt32 size) : this(path) + { + this.Address = mem_addr; + this.Size = size; + this._SectionType = type; + this._PatchType = PatchType.AddSection; + } + + public DolPatch(String path, UInt32 addr, T val) : this(path) + { + this.Address = addr; + this.Value = val; + this._PatchType = PatchType.BytePatching; + } + + internal UInt32 GetFileAddress(UInt32 mem_addr) + { + foreach(var textSection in textSections) + if((mem_addr - textSection.MemoryAddress) < textSection.Size) + return textSection.FileAddress + (mem_addr - textSection.MemoryAddress); + foreach (var dataSection in dataSections) + if ((mem_addr - dataSection.MemoryAddress) < dataSection.Size) + return dataSection.FileAddress + (mem_addr - dataSection.MemoryAddress); + return 0; + } + + void AddTextSection() + { + if (this.textSections.Count + 1 > 7) + throw new Exception("Too much text sections are present! Cannot add a new text section"); + int i = this.textSections.Count; + UInt32 size = (UInt32)new FileInfo(this.Path).Length; + + using (var file = File.OpenWrite(this.Path)) + using (var writer = new BinaryWriter(file)) + { + writer.BaseStream.Position = i * 4; + writer.Write(BitConverter.GetBytes(size).Reverse().ToArray()); + writer.BaseStream.Position = 0x48 + i * 4; + writer.Write(BitConverter.GetBytes(this.Address).Reverse().ToArray()); + writer.BaseStream.Position = 0x90 + i * 4; + writer.Write(BitConverter.GetBytes(this.Size).Reverse().ToArray()); + + writer.BaseStream.Position = size; + for (i = 0; i < this.Size; i++) + writer.Write(0); + } + } + + void AddDataSection() + { + if (this.dataSections.Count + 1 > 11) + throw new Exception("Too much data sections are present! Cannot add a new data section"); + int i = this.textSections.Count; + UInt32 size = (UInt32)new FileInfo(this.Path).Length; + + using (var file = File.OpenWrite(this.Path)) + using (var writer = new BinaryWriter(file)) + { + writer.BaseStream.Position = 0x1C + i * 4; + writer.Write(BitConverter.GetBytes(size).Reverse().ToArray()); + writer.BaseStream.Position = 0x64 + i * 4; + writer.Write(BitConverter.GetBytes(this.Address).Reverse().ToArray()); + writer.BaseStream.Position = 0xAC + i * 4; + writer.Write(BitConverter.GetBytes(this.Size).Reverse().ToArray()); + + writer.BaseStream.Position = size; + for (i = 0; i < this.Size; i++) + writer.Write(0); + } + } + + bool OverwriteBytes(String filePath, UInt32 off, Object val) + { + try + { + byte[] buf = null; + if (val.GetType() == typeof(Int16)) + buf = BitConverter.GetBytes((Int16)val).Reverse().ToArray(); + if (val.GetType() == typeof(Int32)) + buf = BitConverter.GetBytes((Int32)val).Reverse().ToArray(); + if (val.GetType() == typeof(Int64)) + buf = BitConverter.GetBytes((Int64)val).Reverse().ToArray(); + if (val.GetType() == typeof(Byte)) + buf = new byte[] { (Byte)val }; + if (val.GetType() == typeof(UInt16)) + buf = BitConverter.GetBytes((UInt16)val).Reverse().ToArray(); + if (val.GetType() == typeof(UInt32)) + buf = BitConverter.GetBytes((UInt32)val).Reverse().ToArray(); + if (val.GetType() == typeof(UInt64)) + buf = BitConverter.GetBytes((UInt64)val).Reverse().ToArray(); + if (val.GetType() == typeof(Char)) + buf = new byte[] { (Byte)val }; + if (val.GetType() == typeof(Single)) + buf = BitConverter.GetBytes((Single)val).Reverse().ToArray(); + if (val.GetType() == typeof(Double)) + buf = BitConverter.GetBytes((Double)val).Reverse().ToArray(); + if (val.GetType() == typeof(String)) + buf = Encoding.ASCII.GetBytes(((String)val).ToCharArray(), 0, ((String)val).Length); + + using (var bW = new BinaryWriter(File.OpenWrite(filePath))) + { + bW.BaseStream.Position = this.GetFileAddress(off); + if (bW.BaseStream.Position == 0) + throw new Exception("Cannot patch at " + String.Format("0x{0:X8}", off) + "!\nMemory block isn't pre initialized!"); + if (buf != null) + bW.Write(buf); + } + return true; + } + catch + { + return false; + } + } + + internal void Apply() + { + var len = default(Int32); + var i = default(Int32); + var bytes = default(UInt32[]); + + if(_PatchType == PatchType.ScrollCode) + { + if (this.StartAddress % 4 != 0) + throw new Exception("StartAddress must be aligned to 4 bytes"); + if (this.EndAddress % 4 != 0) + throw new Exception("EndAddress must be aligned to 4 bytes"); + + len = (Int32)(EndAddress - StartAddress) / 4; + bytes = new UInt32[len]; + + i = 0; + using (var file = File.OpenRead(Path)) + using (var bR = new BinaryReader(file)) + { + bR.BaseStream.Position = this.GetFileAddress(StartAddress); + if (bR.BaseStream.Position == 0) + throw new Exception("Cannot patch at " + String.Format("0x{0:X8}", StartAddress) + "!\nMemory block isn't pre initialized!"); + while (i < len) + bytes[i++] = BitConverter.ToUInt32(bR.ReadBytes(4), 0); + } + + i = 0; + using (var file = File.OpenWrite(Path)) + using (var bW = new BinaryWriter(file)) + { + bW.BaseStream.Position = this.GetFileAddress((UInt32)(StartAddress + Offset)); + if (bW.BaseStream.Position == 0) + throw new Exception("Cannot patch at " + String.Format("0x{0:X8}", StartAddress + Offset) + "!\nMemory block isn't pre initialized!"); + while (i < bytes.Length) + bW.Write(BitConverter.GetBytes(bytes[i++])); + } + } + if(_PatchType == PatchType.AddSection) + { + if (this._SectionType == SectionType.TEXT) + this.AddTextSection(); + else if (this._SectionType == SectionType.DATA) + this.AddDataSection(); + else + throw new Exception("Unknown type of section"); + } + if (_PatchType == PatchType.BytePatching) + { + if (!OverwriteBytes(this.Path, this.Address, this.Value)) + throw new Exception("Failed to patch " + this.Path + "!"); + } + } + } +} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/IDolPatch.cs b/MP1_Trilogy_Rando_Generator/Patcher/IDolPatch.cs deleted file mode 100644 index 20ae93c..0000000 --- a/MP1_Trilogy_Rando_Generator/Patcher/IDolPatch.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; - -namespace MP1_Trilogy_Rando_Generator.Patcher -{ - class IDolPatch : IPatch - { - protected struct MemSection - { - public UInt32 FileAddress; - public UInt32 MemoryAddress; - public UInt32 Size; - } - - protected List textSections = new List(); - protected List dataSections = new List(); - - public IDolPatch(String path) - { - int i = 0; - MemSection section = default(MemSection); - using (var file = File.OpenRead(path)) - using (var reader = new BinaryReader(file)) - { - for (i = 0; i < 7; i++) - { - section = new MemSection(); - reader.BaseStream.Position = i * 4; - section.FileAddress = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); - if(section.FileAddress != 0) - { - reader.BaseStream.Position = 0x48 + i * 4; - section.MemoryAddress = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); - reader.BaseStream.Position = 0x90 + i * 4; - section.Size = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); - textSections.Add(section); - } - } - for (i = 0; i < 11; i++) - { - section = new MemSection(); - reader.BaseStream.Position = 0x1C + i * 4; - section.FileAddress = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); - if (section.FileAddress != 0) - { - reader.BaseStream.Position = 0x64 + i * 4; - section.MemoryAddress = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); - reader.BaseStream.Position = 0xAC + i * 4; - section.Size = BitConverter.ToUInt32(reader.ReadBytes(4).Reverse().ToArray(), 0); - dataSections.Add(section); - } - } - } - } - - internal UInt32 GetFileAddress(UInt32 mem_addr) - { - foreach(var textSection in textSections) - if((mem_addr - textSection.MemoryAddress) < textSection.Size) - return textSection.FileAddress + (mem_addr - textSection.MemoryAddress); - foreach (var dataSection in dataSections) - if ((mem_addr - dataSection.MemoryAddress) < dataSection.Size) - return dataSection.FileAddress + (mem_addr - dataSection.MemoryAddress); - return 0; - } - - internal override void Apply() - { - } - } -} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/IPatch.cs b/MP1_Trilogy_Rando_Generator/Patcher/IPatch.cs deleted file mode 100644 index 9edd14e..0000000 --- a/MP1_Trilogy_Rando_Generator/Patcher/IPatch.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MP1_Trilogy_Rando_Generator.Patcher -{ - abstract class IPatch - { - internal abstract void Apply(); - } -} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/Patcher.cs b/MP1_Trilogy_Rando_Generator/Patcher/Patcher.cs new file mode 100644 index 0000000..53f4521 --- /dev/null +++ b/MP1_Trilogy_Rando_Generator/Patcher/Patcher.cs @@ -0,0 +1,111 @@ +using System; + +namespace MP1_Trilogy_Rando_Generator.Patcher +{ + // Add suit damage reduction patch + class Patcher + { + static Patches._Trilogy patches = null; + + static UInt32 MakeJMP(UInt32 src, UInt32 dst) + { + return (UInt32)(0x48000000 + (dst - src)); + } + + /*static void WriteFunction(UInt32 address, UInt32[] opcodes) + { + UInt32 max_opcodes = (0x800 - (address - 0x80001800)) / 4; + if (opcodes.Length > max_opcodes) + throw new Exception("Cannot create function there's not enough memory allocated in that section"); + + for (int i = 0; i < opcodes.Length; i++) + new Patcher.DOL_Patch(MP1_Dol_Path, (UInt32)(address + i * 4), opcodes[i]).Apply(); + }*/ + + public static void Init(char Game_Region) + { + if (Game_Region == 'P') + patches = new Patches.PAL(); + if (Game_Region == 'E') + patches = new Patches.NTSC_U(); + if (Game_Region == 'J') + patches = new Patches.NTSC_J(); + } + + public static void SetStartingArea(Enums.SpawnRoom spawnRoom) + { + UInt16 MLVL_H = (UInt16)((spawnRoom.MLVL & 0xFFFF0000) >> 16); + UInt16 MLVL_L = (UInt16)(spawnRoom.MLVL & 0xFFFF); + if (MLVL_L > 0x7FFF) + MLVL_H++; + + if (patches == null) + return; + + patches.SetStartingArea(MLVL_H, MLVL_L, (UInt16)spawnRoom.MREA_ID); + } + + public static void ApplySkipCutscenePatch() + { + if (patches == null) + return; + + patches.ApplySkipCutscenePatch(); + } + + public static void ApplyHeatProtectionPatch(String type) + { + if (patches == null) + return; + + patches.ApplyHeatProtectionPatch(type); + } + + public static void ApplySuitDamageReductionPatch(String type) + { + if (patches == null) + return; + + patches.ApplySuitDamageReductionPatch(type); + } + + public static void ApplyScanDashPatch() + { + if (patches == null) + return; + + patches.ApplyScanDashPatch(); + } + + public static void ApplyUnderwaterSlopeJumpFixPatch(bool enabled) + { + if (patches == null) + return; + + patches.ApplyUnderwaterSlopeJumpFixPatch(enabled); + } + + public static void ApplyDisableSpringBallPatch() + { + if (patches == null) + return; + + patches.ApplyDisableSpringBallPatch(); + } + + public static void SetSaveFilename(String filename) + { + if (patches == null) + return; + + if (!filename.EndsWith(".bin")) + return; + if (filename.Length > 8) + return; + while (filename.Length < 8) + filename += "\0"; + + patches.SetSaveFilename(filename); + } + } +} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/Patches.cs b/MP1_Trilogy_Rando_Generator/Patcher/Patches.cs deleted file mode 100644 index 69431d1..0000000 --- a/MP1_Trilogy_Rando_Generator/Patcher/Patches.cs +++ /dev/null @@ -1,215 +0,0 @@ -using System; - -namespace MP1_Trilogy_Rando_Generator.Patcher -{ - // Add suit damage reduction patch - class Patches - { - internal static String MP1_Dol_Path = ".\\tmp\\wii\\DATA\\files\\rs5mp1_p.dol"; - static String FE_Dol_Path = ".\\tmp\\wii\\DATA\\files\\rs5fe_p.dol"; - static String Main_Dol_Path = ".\\tmp\\wii\\DATA\\sys\\main.dol"; - - static UInt32 MakeJMP(UInt32 src, UInt32 dst) - { - return (UInt32)(0x48000000 + (dst - src)); - } - - static void WriteFunction(UInt32 address, UInt32[] opcodes) - { - UInt32 max_opcodes = (0x800 - (address - 0x80001800)) / 4; - if (opcodes.Length > max_opcodes) - throw new Exception("Cannot create function there's not enough memory allocated in that section"); - - for (int i = 0; i < opcodes.Length; i++) - new Patcher.DOL_Patch(MP1_Dol_Path, (UInt32)(address + i * 4), opcodes[i]).Apply(); - } - - public static void SetStartingArea(Enums.SpawnRoom spawnRoom) - { - UInt16 MLVL_H = (UInt16)((spawnRoom.MLVL & 0xFFFF0000) >> 16); - UInt16 MLVL_L = (UInt16)(spawnRoom.MLVL & 0xFFFF); - if (MLVL_L > 0x7FFF) - MLVL_H++; - - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801098EC + 2, MLVL_H).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801098EC + 14, MLVL_L).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x800CD1F8 + 18, (UInt16)spawnRoom.MREA_ID).Apply(); - - // Set default MLVL in case of crash or save corruption - new Patcher.DOL_Patch(MP1_Dol_Path, 0x8010D278 + 2, MLVL_H).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x8010D278 + 14, MLVL_L).Apply(); - } - - public static void ApplyDisableHintSystemPatch() - { - /*if(enabled) - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80197268, (UInt32)0x4E800020).Apply(); // blr - else - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80197268, (UInt32)0x9421FFB0).Apply(); // stwu r1, -0x50(r1)*/ - } - - public static void ApplySkipCutscenePatch() - { - UInt32 addr = 0x801FC70C; - new Patcher.DOL_Patch(MP1_Dol_Path, addr, (UInt32)0x38600001).Apply(); // li r3, 1 - new Patcher.DOL_Patch(MP1_Dol_Path, addr + 4, (UInt32)0x4E800020).Apply(); // blr - } - - public static void ApplyHeatProtectionPatch(String type) - { - UInt32 addr = 0x801FEBCC; - UInt32 off = 0x48; - if (type == "Varia Only") - { - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off, (UInt32)0x7CC63850).Apply(); // subf r6, r6, r7 - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 4, (UInt32)0x7CC60034).Apply(); // cntlzw r6, r6 - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 8, (UInt32)0x80E408b4).Apply(); // lwz r7, 0x4b4(r4) - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 12, (UInt32)0x80E700E0).Apply(); // lwz r7, 0xe0(r7) - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 16, (UInt32)0x60000000).Apply(); // nop - } - } - - public static void ApplySuitDamageReductionPatch(String type) - { - UInt32 addr = 0x80229D1C; - UInt32 off = 0x114; - if (type == "Progressive") - { - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off, (UInt32)0x808300E0).Apply(); // lwz r4,0xe0(r3) - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 4, (UInt32)0x80A300D8).Apply(); // lwz r5,0xd8(r3) - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 8, (UInt32)0x7C842814).Apply(); // addc r4, r4, r5 - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 12, (UInt32)0x80A300E8).Apply(); // lwz r5,0xe8(r3) - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 16, (UInt32)0x7C842814).Apply(); // addc r4, r4, r5 - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 20, (UInt32)0x5484103A).Apply(); // rlwinm r4, r4, 0x2, 0x0, 0x1d - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 24, (UInt32)0x3CC08005).Apply(); // lis r6, -0x7ffb - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 28, (UInt32)0x38C69F2C).Apply(); // subi r6, r6, 0x60d4 - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 32, (UInt32)0x7C04342E).Apply(); // lfsx f0, r4, r6 - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 36, (UInt32)0x48000040).Apply(); // b 80229E94 - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 40, 0.0f).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 44, 0.1f).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 48, 0.2f).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 52, 0.5f).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, addr + off + 100, (UInt32)0xEFC0F7BC).Apply(); // fnmsubs f30, f0, f30, f30 - } - } - - public static void ApplyScanDashPatch() - { - // Allow scan dash - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801932FC + 0x38, (UInt32)0x48000018).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80194AF0 + 0x70, (UInt32)0x4800001C).Apply(); - // Stop dash when done with dash - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80192CC0, (UInt32)0x801F037C).Apply(); - } - - public static void ApplyUnderwaterSlopeJumpFixPatch(bool enabled) - { - new Patcher.DOL_Patch(MP1_Dol_Path, 0x8019569C, (UInt32)(enabled ? 0x3D40C0F0 : 0x4080002C)).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956A0, (UInt32)(enabled ? 0x3BBD24A1 : 0xEF60E024)).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956A4, (UInt32)(enabled ? 0x3BBD7FFF : 0x7FA3EB78)).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956A8, (UInt32)(enabled ? 0x915D0000 : 0x4BFFD8F5)).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956AC, (UInt32)(enabled ? 0x3BBD8000 : 0xC042A524)).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956B0, (UInt32)(enabled ? 0x3BBDDB60 : 0xEC1B0672)).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956B4, (UInt32)(enabled ? 0x48000014 : 0xEC42D828)).Apply(); - } - - public static void ApplyDisableSpringBallPatch() - { - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80147688, (UInt32)0x60000000).Apply(); - } - - public static void ApplyInputPatch() - { - // DPAD Up => 0x1074 | Hypermode - // DPAD Down => 0x1077 | Shoot missiles - // DPAD Right => 0x107A | R Button - // DPAD Left => 0x107D | L Button - // unused register r16, r18, r19 - // r1 => sp - // Hook(src, dst) where src is setting "this" to CPlayer::??? and dst is our custom function - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80182EBC, (UInt32)0x4BE7E944).Apply(); - - UInt32 custom_func_address = 0x80001800; - UInt32[] custom_func = new UInt32[] { - 0x8A1D107A, // lbz r16, 0x107A(r29) - 0x2C100001, // cmpwi r16, 1 - 0x4082000C, // bne 0x80001814 - 0x3A400006, // li r18, 6 - 0x925D0300, // stw r18, 0x300(r29) - 0x3E40FFFF, // lis r18, 0xFFFF - 0x3A527FFF, // addi r18, r18, 0x7FFF - 0x3A527FFF, // addi r18, r18, 0x7FFF - 0x3A520001, // addi r18, r18, 0x1 - 0x8A1D107D, // lbz r16, 0x107D(r29) - 0x2C100001, // cmpwi r16, 1 - 0x4082003C, // bne 0x80001868 - 0x925D0310, // stw r18, 0x310(r29) - 0x925D0314, // stw r18, 0x314(r29) - 0x925D0318, // stw r18, 0x318(r29) - 0x3A400002, // li r18, 2 - 0x925D0300, // stw r18, 0x300(r29) - 0x48000024, // b 0x80001868 - 0x827D0310, // lwz r19, 0x310(r29) - 0x7C120000, // cmpw r18, r19 - 0x40820018, // bne 0x80001868 - 0x3A600000, // li r19, 0 - 0x927D0310, // stw r19, 0x310(r29) - 0x927D0314, // stw r19, 0x314(r29) - 0x927D0318, // stw r19, 0x318(r29) - 0x927D0310, // stw r19, 0x300(r29) - 0x7E308838, // and r16, r17, r17 - 0x7E328838, // and r18, r17, r17 - 0x7E338838, // and r19, r17, r17 - 0x7FA3EB78, // mr r3, r29 - 0 // b 80001804 -> 80182EC0 - }; - - // set jump back to CPlayer::ProcessInput - custom_func[custom_func.Length - 1] = MakeJMP((UInt32)(custom_func_address + (custom_func.Length - 1) * 4), 0x80182EC0); - - WriteFunction(custom_func_address, custom_func); - - /*// Jump to our subroutine then call CPlayer::UpdateOrbitInput do our stuff and return to CPlayer::ProcessInput - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80182EB8, (UInt32)(enabled ? 0x480127E4 : 0x4801881D)).Apply(); - - // Check if Z Button or DPad Up were pressed - //new Patcher.DOL_Patch(MP1_Dol_Path, 0x80194680, (UInt32)(enabled ? 0x801D1060 : 0x801D0300)).Apply(); - - if(enabled) - new Patcher.DOL_ScrollCode_Patch(MP1_Dol_Path, 0x8019568C, 0x801956C8, -4).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80195698, (UInt32)(enabled ? 0x48000030 : 0x4080002C)).Apply(); // jmp to 801956C8 - new Patcher.DOL_Patch(MP1_Dol_Path, 0x8019569C, (UInt32)(enabled ? 0x48006038 : 0xEF60E024)).Apply(); // bl CPlayer::UpdateOrbitInput - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956A0, (UInt32)(enabled ? 0x89DD1074 : 0x7FA3EB78)).Apply(); // lbz r14, CPlayer[0x1074] aka DPad Up - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956A4, (UInt32)(enabled ? 0x89FD109B : 0x4BFFD8F5)).Apply(); // lbz r15, CPlayer[0x109B] aka Z Button - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956A8, (UInt32)(enabled ? 0x7DEE7378 : 0xC042A524)).Apply(); // set r14 to CPlayer[0x1074] or CPlayer[0x109B] - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956AC, (UInt32)(enabled ? 0x39E00001 : 0xEC1B0672)).Apply(); // li r15, 1 - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956B0, (UInt32)(enabled ? 0x7DCE7830 : 0xEC42D828)).Apply(); // multiply r14 by 2 - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956B4, (UInt32)(enabled ? 0x91DD0300 : 0xEC220072)).Apply(); // set CPlayer[0x300] to r14 - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956B8, (UInt32)(enabled ? 0x60000000 : 0xEC2106B2)).Apply(); // - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956BC, (UInt32)(enabled ? 0x60000000 : 0xEC20082A)).Apply(); // - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956C0, (UInt32)(enabled ? 0x60000000 : 0x48000028)).Apply(); // - new Patcher.DOL_Patch(MP1_Dol_Path, 0x801956C4, (UInt32)(enabled ? 0x4BFED7F8 : 0x60000000)).Apply(); // jump back to CPlayer::ProcessInput - if(!enabled) - { - new Patcher.DOL_ScrollCode_Patch(MP1_Dol_Path, 0x80195688, 0x801956C4, 4).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80195688, 0xFC00E040).Apply(); - } - - // Patch return of CPlayer::UpdateOrbitInput because it doesn't call the function but rather jump to it - new Patcher.DOL_Patch(MP1_Dol_Path, 0x8019BDB4, (UInt32)(enabled ? 0x428098EC : 0x4E800020)).Apply();*/ - } - - public static void SetSaveFilename(String filename) - { - if (!filename.EndsWith(".bin")) - return; - if (filename.Length > 8) - return; - while (filename.Length < 8) - filename += "\0"; - new Patcher.DOL_Patch(FE_Dol_Path, 0x8052FBA8, filename).Apply(); - new Patcher.DOL_Patch(Main_Dol_Path, 0x8052FBA8, filename).Apply(); - new Patcher.DOL_Patch(MP1_Dol_Path, 0x80475D48, filename).Apply(); - } - } -} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/Patches/NTSC_J.cs b/MP1_Trilogy_Rando_Generator/Patcher/Patches/NTSC_J.cs new file mode 100644 index 0000000..334651e --- /dev/null +++ b/MP1_Trilogy_Rando_Generator/Patcher/Patches/NTSC_J.cs @@ -0,0 +1,100 @@ +using System; + +namespace MP1_Trilogy_Rando_Generator.Patcher.Patches +{ + class NTSC_J : _Trilogy + { + internal static new String MP1_Dol_Path = ".\\tmp\\wii\\DATA\\files\\rs5mp1jpn_p.dol"; + + public override void SetStartingArea(UInt16 MLVL_H, UInt16 MLVL_L, UInt16 MREA_ID) + { + new DolPatch(MP1_Dol_Path, 0x80109EE0 + 2, MLVL_H).Apply(); + new DolPatch(MP1_Dol_Path, 0x80109EE0 + 14, MLVL_L).Apply(); + new DolPatch(MP1_Dol_Path, 0x800CD374 + 18, MREA_ID).Apply(); + + // Set default MLVL in case of crash or save corruption + new DolPatch(MP1_Dol_Path, 0x8010D86C + 2, MLVL_H).Apply(); + new DolPatch(MP1_Dol_Path, 0x8010D86C + 14, MLVL_L).Apply(); + } + + public override void ApplySkipCutscenePatch() + { + UInt32 addr = 0x801FD344; + new DolPatch(MP1_Dol_Path, addr, (UInt32)0x38600001).Apply(); // li r3, 1 + new DolPatch(MP1_Dol_Path, addr + 4, (UInt32)0x4E800020).Apply(); // blr + } + + public override void ApplyHeatProtectionPatch(String type) + { + UInt32 addr = 0x801FF788; + UInt32 off = 0x48; + if (type == "Varia Only") + { + new DolPatch(MP1_Dol_Path, addr + off, (UInt32)0x7CC63850).Apply(); // subf r6, r6, r7 + new DolPatch(MP1_Dol_Path, addr + off + 4, (UInt32)0x7CC60034).Apply(); // cntlzw r6, r6 + new DolPatch(MP1_Dol_Path, addr + off + 8, (UInt32)0x80E408b4).Apply(); // lwz r7, 0x4b4(r4) + new DolPatch(MP1_Dol_Path, addr + off + 12, (UInt32)0x80E700E0).Apply(); // lwz r7, 0xe0(r7) + new DolPatch(MP1_Dol_Path, addr + off + 16, (UInt32)0x60000000).Apply(); // nop + } + } + + public override void ApplySuitDamageReductionPatch(String type) + { + UInt32 addr = 0x8022A8D8; + UInt32 off = 0x114; + if (type == "Progressive") + { + new DolPatch(MP1_Dol_Path, addr + off, (UInt32)0x808300E0).Apply(); // lwz r4,0xe0(r3) + new DolPatch(MP1_Dol_Path, addr + off + 4, (UInt32)0x80A300D8).Apply(); // lwz r5,0xd8(r3) + new DolPatch(MP1_Dol_Path, addr + off + 8, (UInt32)0x7C842814).Apply(); // addc r4, r4, r5 + new DolPatch(MP1_Dol_Path, addr + off + 12, (UInt32)0x80A300E8).Apply(); // lwz r5,0xe8(r3) + new DolPatch(MP1_Dol_Path, addr + off + 16, (UInt32)0x7C842814).Apply(); // addc r4, r4, r5 + new DolPatch(MP1_Dol_Path, addr + off + 20, (UInt32)0x5484103A).Apply(); // rlwinm r4, r4, 0x2, 0x0, 0x1d + new DolPatch(MP1_Dol_Path, addr + off + 24, (UInt32)0x3CC08005).Apply(); // lis r6, -0x7ffb + new DolPatch(MP1_Dol_Path, addr + off + 28, (UInt32)0x38C69F2C).Apply(); // subi r6, r6, 0x60d4 + new DolPatch(MP1_Dol_Path, addr + off + 32, (UInt32)0x7C04342E).Apply(); // lfsx f0, r4, r6 + new DolPatch(MP1_Dol_Path, addr + off + 36, (UInt32)0x48000040).Apply(); // b 80229E94 + new DolPatch(MP1_Dol_Path, addr + off + 40, 0.0f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 44, 0.1f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 48, 0.2f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 52, 0.5f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 100, (UInt32)0xEFC0F7BC).Apply(); // fnmsubs f30, f0, f30, f30 + } + } + + public override void ApplyScanDashPatch() + { + // Allow scan dash + new DolPatch(MP1_Dol_Path, 0x80193E7C + 0x38, (UInt32)0x48000018).Apply(); + // ??? might help for dashing + new DolPatch(MP1_Dol_Path, 0x80195670 + 0x70, (UInt32)0x4800001C).Apply(); + // Stop dash when done with dash + new DolPatch(MP1_Dol_Path, 0x801937D0 + 0x70, (UInt32)0x881F037C).Apply(); + } + + public override void ApplyUnderwaterSlopeJumpFixPatch(bool enabled) + { + UInt32 addr = 0x80195E98; + UInt32 off = 0x384; + new DolPatch(MP1_Dol_Path, addr + off, (UInt32)(enabled ? 0x3D40C0F0 : 0x4080002C)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 4, (UInt32)(enabled ? 0x3BBD24A1 : 0xEF60E024)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 8, (UInt32)(enabled ? 0x3BBD7FFF : 0x7FA3EB78)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 12, (UInt32)(enabled ? 0x915D0000 : 0x4BFFD8F5)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 16, (UInt32)(enabled ? 0x3BBD8000 : 0xC042A5C4)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 20, (UInt32)(enabled ? 0x3BBDDB60 : 0xEC1B0672)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 24, (UInt32)(enabled ? 0x48000014 : 0xEC42D828)).Apply(); + } + + public override void ApplyDisableSpringBallPatch() + { + new DolPatch(MP1_Dol_Path, 0x80147C08 + 0x80, (UInt32)0x60000000).Apply(); + } + + public override void SetSaveFilename(String filename) + { + new DolPatch(FE_Dol_Path, 0x8052F788, filename).Apply(); + new DolPatch(Main_Dol_Path, 0x8052F788, filename).Apply(); + new DolPatch(MP1_Dol_Path, 0x80475030, filename).Apply(); + } + } +} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/Patches/NTSC_U.cs b/MP1_Trilogy_Rando_Generator/Patcher/Patches/NTSC_U.cs new file mode 100644 index 0000000..23a459d --- /dev/null +++ b/MP1_Trilogy_Rando_Generator/Patcher/Patches/NTSC_U.cs @@ -0,0 +1,187 @@ +using System; + +namespace MP1_Trilogy_Rando_Generator.Patcher.Patches +{ + class NTSC_U : _Trilogy + { + public override void SetStartingArea(UInt16 MLVL_H, UInt16 MLVL_L, UInt16 MREA_ID) + { + new DolPatch(MP1_Dol_Path, 0x801098EC + 2, MLVL_H).Apply(); + new DolPatch(MP1_Dol_Path, 0x801098EC + 14, MLVL_L).Apply(); + new DolPatch(MP1_Dol_Path, 0x800CD1F8 + 18, MREA_ID).Apply(); + + // Set default MLVL in case of crash or save corruption + new DolPatch(MP1_Dol_Path, 0x8010D278 + 2, MLVL_H).Apply(); + new DolPatch(MP1_Dol_Path, 0x8010D278 + 14, MLVL_L).Apply(); + } + + /*public static void ApplyDisableHintSystemPatch() // Could be used for hud memo in multiworld ? + { + if(enabled) + new DolPatch(MP1_Dol_Path, 0x80197268, (UInt32)0x4E800020).Apply(); // blr + else + new DolPatch(MP1_Dol_Path, 0x80197268, (UInt32)0x9421FFB0).Apply(); // stwu r1, -0x50(r1) + }*/ + + public override void ApplySkipCutscenePatch() + { + UInt32 addr = 0x801FC70C; + new DolPatch(MP1_Dol_Path, addr, (UInt32)0x38600001).Apply(); // li r3, 1 + new DolPatch(MP1_Dol_Path, addr + 4, (UInt32)0x4E800020).Apply(); // blr + } + + public override void ApplyHeatProtectionPatch(String type) + { + UInt32 addr = 0x801FEBCC; + UInt32 off = 0x48; + if (type == "Varia Only") + { + new DolPatch(MP1_Dol_Path, addr + off, (UInt32)0x7CC63850).Apply(); // subf r6, r6, r7 + new DolPatch(MP1_Dol_Path, addr + off + 4, (UInt32)0x7CC60034).Apply(); // cntlzw r6, r6 + new DolPatch(MP1_Dol_Path, addr + off + 8, (UInt32)0x80E408b4).Apply(); // lwz r7, 0x4b4(r4) + new DolPatch(MP1_Dol_Path, addr + off + 12, (UInt32)0x80E700E0).Apply(); // lwz r7, 0xe0(r7) + new DolPatch(MP1_Dol_Path, addr + off + 16, (UInt32)0x60000000).Apply(); // nop + } + } + + public override void ApplySuitDamageReductionPatch(String type) + { + UInt32 addr = 0x80229D1C; + UInt32 off = 0x114; + if (type == "Progressive") + { + new DolPatch(MP1_Dol_Path, addr + off, (UInt32)0x808300E0).Apply(); // lwz r4,0xe0(r3) + new DolPatch(MP1_Dol_Path, addr + off + 4, (UInt32)0x80A300D8).Apply(); // lwz r5,0xd8(r3) + new DolPatch(MP1_Dol_Path, addr + off + 8, (UInt32)0x7C842814).Apply(); // addc r4, r4, r5 + new DolPatch(MP1_Dol_Path, addr + off + 12, (UInt32)0x80A300E8).Apply(); // lwz r5,0xe8(r3) + new DolPatch(MP1_Dol_Path, addr + off + 16, (UInt32)0x7C842814).Apply(); // addc r4, r4, r5 + new DolPatch(MP1_Dol_Path, addr + off + 20, (UInt32)0x5484103A).Apply(); // rlwinm r4, r4, 0x2, 0x0, 0x1d + new DolPatch(MP1_Dol_Path, addr + off + 24, (UInt32)0x3CC08005).Apply(); // lis r6, -0x7ffb + new DolPatch(MP1_Dol_Path, addr + off + 28, (UInt32)0x38C69F2C).Apply(); // subi r6, r6, 0x60d4 + new DolPatch(MP1_Dol_Path, addr + off + 32, (UInt32)0x7C04342E).Apply(); // lfsx f0, r4, r6 + new DolPatch(MP1_Dol_Path, addr + off + 36, (UInt32)0x48000040).Apply(); // b 80229E94 + new DolPatch(MP1_Dol_Path, addr + off + 40, 0.0f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 44, 0.1f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 48, 0.2f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 52, 0.5f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 100, (UInt32)0xEFC0F7BC).Apply(); // fnmsubs f30, f0, f30, f30 + } + } + + public override void ApplyScanDashPatch() + { + // Allow scan dash + new DolPatch(MP1_Dol_Path, 0x801932FC + 0x38, (UInt32)0x48000018).Apply(); + // ??? might help for dashing + new DolPatch(MP1_Dol_Path, 0x80194AF0 + 0x70, (UInt32)0x4800001C).Apply(); + // Stop dash when done with dash + new DolPatch(MP1_Dol_Path, 0x80192C50 + 0x70, (UInt32)0x881F037C).Apply(); + } + + public override void ApplyUnderwaterSlopeJumpFixPatch(bool enabled) + { + UInt32 addr = 0x80195318; + UInt32 off = 0x384; + new DolPatch(MP1_Dol_Path, addr + off, (UInt32)(enabled ? 0x3D40C0F0 : 0x4080002C)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 4, (UInt32)(enabled ? 0x3BBD24A1 : 0xEF60E024)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 8, (UInt32)(enabled ? 0x3BBD7FFF : 0x7FA3EB78)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 12, (UInt32)(enabled ? 0x915D0000 : 0x4BFFD8F5)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 16, (UInt32)(enabled ? 0x3BBD8000 : 0xC042A524)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 20, (UInt32)(enabled ? 0x3BBDDB60 : 0xEC1B0672)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 24, (UInt32)(enabled ? 0x48000014 : 0xEC42D828)).Apply(); + } + + public override void ApplyDisableSpringBallPatch() + { + new DolPatch(MP1_Dol_Path, 0x80147608 + 0x80, (UInt32)0x60000000).Apply(); + } + + public override void SetSaveFilename(String filename) + { + new DolPatch(FE_Dol_Path, 0x8052FBA8, filename).Apply(); + new DolPatch(Main_Dol_Path, 0x8052FBA8, filename).Apply(); + new DolPatch(MP1_Dol_Path, 0x80475D48, filename).Apply(); + } + + /*public static void ApplyInputPatch() + { + // DPAD Up => 0x1074 | Hypermode + // DPAD Down => 0x1077 | Shoot missiles + // DPAD Right => 0x107A | R Button + // DPAD Left => 0x107D | L Button + // unused register r16, r18, r19 + // r1 => sp + // Hook(src, dst) where src is setting "this" to CPlayer::??? and dst is our custom function + new DolPatch(MP1_Dol_Path, 0x80182EBC, (UInt32)0x4BE7E944).Apply(); + + UInt32 custom_func_address = 0x80001800; + UInt32[] custom_func = new UInt32[] { + 0x8A1D107A, // lbz r16, 0x107A(r29) + 0x2C100001, // cmpwi r16, 1 + 0x4082000C, // bne 0x80001814 + 0x3A400006, // li r18, 6 + 0x925D0300, // stw r18, 0x300(r29) + 0x3E40FFFF, // lis r18, 0xFFFF + 0x3A527FFF, // addi r18, r18, 0x7FFF + 0x3A527FFF, // addi r18, r18, 0x7FFF + 0x3A520001, // addi r18, r18, 0x1 + 0x8A1D107D, // lbz r16, 0x107D(r29) + 0x2C100001, // cmpwi r16, 1 + 0x4082003C, // bne 0x80001868 + 0x925D0310, // stw r18, 0x310(r29) + 0x925D0314, // stw r18, 0x314(r29) + 0x925D0318, // stw r18, 0x318(r29) + 0x3A400002, // li r18, 2 + 0x925D0300, // stw r18, 0x300(r29) + 0x48000024, // b 0x80001868 + 0x827D0310, // lwz r19, 0x310(r29) + 0x7C120000, // cmpw r18, r19 + 0x40820018, // bne 0x80001868 + 0x3A600000, // li r19, 0 + 0x927D0310, // stw r19, 0x310(r29) + 0x927D0314, // stw r19, 0x314(r29) + 0x927D0318, // stw r19, 0x318(r29) + 0x927D0310, // stw r19, 0x300(r29) + 0x7E308838, // and r16, r17, r17 + 0x7E328838, // and r18, r17, r17 + 0x7E338838, // and r19, r17, r17 + 0x7FA3EB78, // mr r3, r29 + 0 // b 80001804 -> 80182EC0 + }; + + // set jump back to CPlayer::ProcessInput + custom_func[custom_func.Length - 1] = MakeJMP((UInt32)(custom_func_address + (custom_func.Length - 1) * 4), 0x80182EC0); + + WriteFunction(custom_func_address, custom_func); + + // Jump to our subroutine then call CPlayer::UpdateOrbitInput do our stuff and return to CPlayer::ProcessInput + new DolPatch(MP1_Dol_Path, 0x80182EB8, (UInt32)(enabled ? 0x480127E4 : 0x4801881D)).Apply(); + + // Check if Z Button or DPad Up were pressed + //new DolPatch(MP1_Dol_Path, 0x80194680, (UInt32)(enabled ? 0x801D1060 : 0x801D0300)).Apply(); + + if(enabled) + new DolPatch(MP1_Dol_Path, 0x8019568C, 0x801956C8, -4).Apply(); + new DolPatch(MP1_Dol_Path, 0x80195698, (UInt32)(enabled ? 0x48000030 : 0x4080002C)).Apply(); // jmp to 801956C8 + new DolPatch(MP1_Dol_Path, 0x8019569C, (UInt32)(enabled ? 0x48006038 : 0xEF60E024)).Apply(); // bl CPlayer::UpdateOrbitInput + new DolPatch(MP1_Dol_Path, 0x801956A0, (UInt32)(enabled ? 0x89DD1074 : 0x7FA3EB78)).Apply(); // lbz r14, CPlayer[0x1074] aka DPad Up + new DolPatch(MP1_Dol_Path, 0x801956A4, (UInt32)(enabled ? 0x89FD109B : 0x4BFFD8F5)).Apply(); // lbz r15, CPlayer[0x109B] aka Z Button + new DolPatch(MP1_Dol_Path, 0x801956A8, (UInt32)(enabled ? 0x7DEE7378 : 0xC042A524)).Apply(); // set r14 to CPlayer[0x1074] or CPlayer[0x109B] + new DolPatch(MP1_Dol_Path, 0x801956AC, (UInt32)(enabled ? 0x39E00001 : 0xEC1B0672)).Apply(); // li r15, 1 + new DolPatch(MP1_Dol_Path, 0x801956B0, (UInt32)(enabled ? 0x7DCE7830 : 0xEC42D828)).Apply(); // multiply r14 by 2 + new DolPatch(MP1_Dol_Path, 0x801956B4, (UInt32)(enabled ? 0x91DD0300 : 0xEC220072)).Apply(); // set CPlayer[0x300] to r14 + new DolPatch(MP1_Dol_Path, 0x801956B8, (UInt32)(enabled ? 0x60000000 : 0xEC2106B2)).Apply(); // + new DolPatch(MP1_Dol_Path, 0x801956BC, (UInt32)(enabled ? 0x60000000 : 0xEC20082A)).Apply(); // + new DolPatch(MP1_Dol_Path, 0x801956C0, (UInt32)(enabled ? 0x60000000 : 0x48000028)).Apply(); // + new DolPatch(MP1_Dol_Path, 0x801956C4, (UInt32)(enabled ? 0x4BFED7F8 : 0x60000000)).Apply(); // jump back to CPlayer::ProcessInput + if(!enabled) + { + new DolPatch(MP1_Dol_Path, 0x80195688, 0x801956C4, 4).Apply(); + new DolPatch(MP1_Dol_Path, 0x80195688, 0xFC00E040).Apply(); + } + + // Patch return of CPlayer::UpdateOrbitInput because it doesn't call the function but rather jump to it + new DolPatch(MP1_Dol_Path, 0x8019BDB4, (UInt32)(enabled ? 0x428098EC : 0x4E800020)).Apply(); + }*/ + } +} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/Patches/PAL.cs b/MP1_Trilogy_Rando_Generator/Patcher/Patches/PAL.cs new file mode 100644 index 0000000..747c7d5 --- /dev/null +++ b/MP1_Trilogy_Rando_Generator/Patcher/Patches/PAL.cs @@ -0,0 +1,98 @@ +using System; + +namespace MP1_Trilogy_Rando_Generator.Patcher.Patches +{ + class PAL : _Trilogy + { + public override void SetStartingArea(UInt16 MLVL_H, UInt16 MLVL_L, UInt16 MREA_ID) + { + new DolPatch(MP1_Dol_Path, 0x80109A08 + 2, MLVL_H).Apply(); + new DolPatch(MP1_Dol_Path, 0x80109A08 + 14, MLVL_L).Apply(); + new DolPatch(MP1_Dol_Path, 0x800CD348 + 18, MREA_ID).Apply(); + + // Set default MLVL in case of crash or save corruption + new DolPatch(MP1_Dol_Path, 0x8010D394 + 2, MLVL_H).Apply(); + new DolPatch(MP1_Dol_Path, 0x8010D394 + 14, MLVL_L).Apply(); + } + + public override void ApplySkipCutscenePatch() + { + UInt32 addr = 0x801FCA60; + new DolPatch(MP1_Dol_Path, addr, (UInt32)0x38600001).Apply(); // li r3, 1 + new DolPatch(MP1_Dol_Path, addr + 4, (UInt32)0x4E800020).Apply(); // blr + } + + public override void ApplyHeatProtectionPatch(String type) + { + UInt32 addr = 0x801FEF20; + UInt32 off = 0x48; + if (type == "Varia Only") + { + new DolPatch(MP1_Dol_Path, addr + off, (UInt32)0x7CC63850).Apply(); // subf r6, r6, r7 + new DolPatch(MP1_Dol_Path, addr + off + 4, (UInt32)0x7CC60034).Apply(); // cntlzw r6, r6 + new DolPatch(MP1_Dol_Path, addr + off + 8, (UInt32)0x80E408b4).Apply(); // lwz r7, 0x4b4(r4) + new DolPatch(MP1_Dol_Path, addr + off + 12, (UInt32)0x80E700E0).Apply(); // lwz r7, 0xe0(r7) + new DolPatch(MP1_Dol_Path, addr + off + 16, (UInt32)0x60000000).Apply(); // nop + } + } + + public override void ApplySuitDamageReductionPatch(String type) + { + UInt32 addr = 0x8022A070; + UInt32 off = 0x114; + if (type == "Progressive") + { + new DolPatch(MP1_Dol_Path, addr + off, (UInt32)0x808300E0).Apply(); // lwz r4,0xe0(r3) + new DolPatch(MP1_Dol_Path, addr + off + 4, (UInt32)0x80A300D8).Apply(); // lwz r5,0xd8(r3) + new DolPatch(MP1_Dol_Path, addr + off + 8, (UInt32)0x7C842814).Apply(); // addc r4, r4, r5 + new DolPatch(MP1_Dol_Path, addr + off + 12, (UInt32)0x80A300E8).Apply(); // lwz r5,0xe8(r3) + new DolPatch(MP1_Dol_Path, addr + off + 16, (UInt32)0x7C842814).Apply(); // addc r4, r4, r5 + new DolPatch(MP1_Dol_Path, addr + off + 20, (UInt32)0x5484103A).Apply(); // rlwinm r4, r4, 0x2, 0x0, 0x1d + new DolPatch(MP1_Dol_Path, addr + off + 24, (UInt32)0x3CC08005).Apply(); // lis r6, -0x7ffb + new DolPatch(MP1_Dol_Path, addr + off + 28, (UInt32)0x38C69F2C).Apply(); // subi r6, r6, 0x60d4 + new DolPatch(MP1_Dol_Path, addr + off + 32, (UInt32)0x7C04342E).Apply(); // lfsx f0, r4, r6 + new DolPatch(MP1_Dol_Path, addr + off + 36, (UInt32)0x48000040).Apply(); // b 80229E94 + new DolPatch(MP1_Dol_Path, addr + off + 40, 0.0f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 44, 0.1f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 48, 0.2f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 52, 0.5f).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 100, (UInt32)0xEFC0F7BC).Apply(); // fnmsubs f30, f0, f30, f30 + } + } + + public override void ApplyScanDashPatch() + { + // Allow scan dash + new DolPatch(MP1_Dol_Path, 0x80193594 + 0x38, (UInt32)0x48000018).Apply(); + // ??? might help for dashing + new DolPatch(MP1_Dol_Path, 0x80194D88 + 0x70, (UInt32)0x4800001C).Apply(); + // Stop dash when done with dash + new DolPatch(MP1_Dol_Path, 0x80192EE8 + 0x70, (UInt32)0x881F037C).Apply(); + } + + public override void ApplyUnderwaterSlopeJumpFixPatch(bool enabled) + { + UInt32 addr = 0x801955B0; + UInt32 off = 0x384; + new DolPatch(MP1_Dol_Path, addr + off, (UInt32)(enabled ? 0x3D40C0F0 : 0x4080002C)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 4, (UInt32)(enabled ? 0x3BBD24A1 : 0xEF60E024)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 8, (UInt32)(enabled ? 0x3BBD7FFF : 0x7FA3EB78)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 12, (UInt32)(enabled ? 0x915D0000 : 0x4BFFD8F5)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 16, (UInt32)(enabled ? 0x3BBD8000 : 0xC042A51C)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 20, (UInt32)(enabled ? 0x3BBDDB60 : 0xEC1B0672)).Apply(); + new DolPatch(MP1_Dol_Path, addr + off + 24, (UInt32)(enabled ? 0x48000014 : 0xEC42D828)).Apply(); + } + + public override void ApplyDisableSpringBallPatch() + { + new DolPatch(MP1_Dol_Path, 0x80147758 + 0x80, (UInt32)0x60000000).Apply(); + } + + public override void SetSaveFilename(String filename) + { + new DolPatch(FE_Dol_Path, 0x805340A8, filename).Apply(); + new DolPatch(Main_Dol_Path, 0x805340A8, filename).Apply(); + new DolPatch(MP1_Dol_Path, 0x80479268, filename).Apply(); + } + } +} diff --git a/MP1_Trilogy_Rando_Generator/Patcher/Patches/_Trilogy.cs b/MP1_Trilogy_Rando_Generator/Patcher/Patches/_Trilogy.cs new file mode 100644 index 0000000..f814d34 --- /dev/null +++ b/MP1_Trilogy_Rando_Generator/Patcher/Patches/_Trilogy.cs @@ -0,0 +1,20 @@ +using System; + +namespace MP1_Trilogy_Rando_Generator.Patcher.Patches +{ + abstract class _Trilogy + { + internal static String MP1_Dol_Path = ".\\tmp\\wii\\DATA\\files\\rs5mp1_p.dol"; + internal static String FE_Dol_Path = ".\\tmp\\wii\\DATA\\files\\rs5fe_p.dol"; + internal static String Main_Dol_Path = ".\\tmp\\wii\\DATA\\sys\\main.dol"; + + public abstract void SetStartingArea(UInt16 MLVL_H, UInt16 MLVL_L, UInt16 MREA_ID); + public abstract void ApplySkipCutscenePatch(); + public abstract void ApplyHeatProtectionPatch(String type); + public abstract void ApplySuitDamageReductionPatch(String type); + public abstract void ApplyScanDashPatch(); + public abstract void ApplyUnderwaterSlopeJumpFixPatch(bool enabled); + public abstract void ApplyDisableSpringBallPatch(); + public abstract void SetSaveFilename(String filename); + } +} diff --git a/MP1_Trilogy_Rando_Generator/Properties/Resources.Designer.cs b/MP1_Trilogy_Rando_Generator/Properties/Resources.Designer.cs index 8001ce7..9b8c3c8 100644 --- a/MP1_Trilogy_Rando_Generator/Properties/Resources.Designer.cs +++ b/MP1_Trilogy_Rando_Generator/Properties/Resources.Designer.cs @@ -70,6 +70,16 @@ internal static byte[] dummy { } } + /// + /// Recherche une ressource localisée de type System.Byte[]. + /// + internal static byte[] R3IJ01_nkit { + get { + object obj = ResourceManager.GetObject("R3IJ01_nkit", resourceCulture); + return ((byte[])(obj)); + } + } + /// /// Recherche une ressource localisée de type System.Byte[]. /// @@ -79,5 +89,15 @@ internal static byte[] R3ME01_nkit { return ((byte[])(obj)); } } + + /// + /// Recherche une ressource localisée de type System.Byte[]. + /// + internal static byte[] R3MP01_nkit { + get { + object obj = ResourceManager.GetObject("R3MP01_nkit", resourceCulture); + return ((byte[])(obj)); + } + } } } diff --git a/MP1_Trilogy_Rando_Generator/Properties/Resources.resx b/MP1_Trilogy_Rando_Generator/Properties/Resources.resx index a3c0b7b..248cf75 100644 --- a/MP1_Trilogy_Rando_Generator/Properties/Resources.resx +++ b/MP1_Trilogy_Rando_Generator/Properties/Resources.resx @@ -121,7 +121,13 @@ ..\embed_res\dummy.thp;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\embed_res\R3IJ01_nkit.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + ..\embed_res\R3ME01_nkit.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + ..\embed_res\R3MP01_nkit.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + \ No newline at end of file diff --git a/MP1_Trilogy_Rando_Generator/Utils/ProcessUtils.cs b/MP1_Trilogy_Rando_Generator/Utils/ProcessUtils.cs new file mode 100644 index 0000000..b59b239 --- /dev/null +++ b/MP1_Trilogy_Rando_Generator/Utils/ProcessUtils.cs @@ -0,0 +1,30 @@ +using System.Diagnostics; +using System.Management; + +namespace MP1_Trilogy_Rando_Generator.Utils +{ + internal class ProcessUtils + { + internal static void KillChildrenProcesses(int id) + { + var searcher = default(ManagementObjectSearcher); + var collection = default(ManagementObjectCollection); + var childProcessId = default(int); + + searcher = new ManagementObjectSearcher("SELECT * FROM Win32_Process WHERE ParentProcessId=" + Process.GetCurrentProcess().Id); + collection = searcher.Get(); + if (collection.Count > 0) + { + foreach (var item in collection) + { + childProcessId = (int)item["ProcessId"]; + if (childProcessId != id) + { + KillChildrenProcesses(childProcessId); + Process.GetProcessById(childProcessId).Kill(); + } + } + } + } + } +} \ No newline at end of file diff --git a/MP1_Trilogy_Rando_Generator/embed_res/R3IJ01_nkit.zip b/MP1_Trilogy_Rando_Generator/embed_res/R3IJ01_nkit.zip new file mode 100644 index 0000000..8546f73 Binary files /dev/null and b/MP1_Trilogy_Rando_Generator/embed_res/R3IJ01_nkit.zip differ diff --git a/MP1_Trilogy_Rando_Generator/embed_res/R3MP01_nkit.zip b/MP1_Trilogy_Rando_Generator/embed_res/R3MP01_nkit.zip new file mode 100644 index 0000000..507c47c Binary files /dev/null and b/MP1_Trilogy_Rando_Generator/embed_res/R3MP01_nkit.zip differ