From c60d2bfe2cc2ed467b2171ae531ceedc29a63834 Mon Sep 17 00:00:00 2001 From: AdAstra-LD <76622070+AdAstra-LD@users.noreply.github.com> Date: Mon, 4 Dec 2023 03:33:47 +0100 Subject: [PATCH] Restructured Trainer names length expansion patch --- DS_Map/Main Window.cs | 37 +++++++-------- DS_Map/ROMFiles/TrainerFile.cs | 2 +- DS_Map/ROMToolboxDialog.cs | 85 +++++++++++----------------------- DS_Map/RomInfo.cs | 76 ++++++++++++++++++++++++++---- 4 files changed, 110 insertions(+), 90 deletions(-) diff --git a/DS_Map/Main Window.cs b/DS_Map/Main Window.cs index 561a7b2..8c5efe3 100644 --- a/DS_Map/Main Window.cs +++ b/DS_Map/Main Window.cs @@ -8603,6 +8603,8 @@ namespace DSPRE { } private void SetupTrainerEditor() { disableHandlers = true; + + SetTrainerNameMaxLen(); SetupTrainerClassEncounterMusicTable(); /* Extract essential NARCs sub-archives*/ statusLabelMessage("Setting up Trainer Editor..."); @@ -9020,26 +9022,6 @@ namespace DSPRE { } private void trainerSaveCurrentButton_Click(object sender, EventArgs e) { - if (!ROMToolboxDialog.flag_TrainerNamesExpanded && trainerNameTextBox.Text.Length > TrainerFile.maxNameLen) { - DialogResult d2; - MessageBox.Show($"The length of this Trainer name exceeds {TrainerFile.maxNameLen} characters.", - "Trainer data could not be saved!", MessageBoxButtons.OK, MessageBoxIcon.Error); - - d2 = MessageBox.Show("Within the RomToolBox (found near the wild editor) you can expand this limit if you are working on an English or Spanish rom (for now).", - "Do you wish to go there now?", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d2 == DialogResult.Yes) { - romToolBoxToolStripMenuItem_Click(null, null); - } - return; - } - - if (trainerNameTextBox.Text.Length > ROMToolboxDialog.expandedTrainerNameLength) { - MessageBox.Show($"The length of this Trainer name exceeds {ROMToolboxDialog.expandedTrainerNameLength} characters.", - "Trainer data could not be saved!", MessageBoxButtons.OK, MessageBoxIcon.Error); - return; - - } - currentTrainerFile.trp.partyCount = (byte)partyCountUpDown.Value; currentTrainerFile.trp.chooseMoves = trainerMovesCheckBox.Checked; currentTrainerFile.trp.chooseItems = trainerItemsCheckBox.Checked; @@ -9115,7 +9097,20 @@ namespace DSPRE { UpdateCurrentTrainerName(newName: trainerNameTextBox.Text); UpdateCurrentTrainerShownName(); - MessageBox.Show("Trainer saved successfully!", "", MessageBoxButtons.OK, MessageBoxIcon.Information); + if (trainerNameTextBox.Text.Length > RomInfo.trainerNameMaxLen - 1) { //Subtract 1 to account for special end character. + //Expose a smaller limit to the user + if (RomInfo.trainerNameLenOffset >= 0) { + MessageBox.Show($"Trainer File saved successfully. However:\nYou attempted to save a Trainer whose name exceeds {RomInfo.trainerNameMaxLen-1} characters.\nThis may lead to issues in game." + + (ROMToolboxDialog.flag_TrainerNamesExpanded ? "\n\nIt's recommended that you use a shorter name." : "\n\nRefer to the ROM Toolbox to extend Trainer names."), + "Saved successfully, but...", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } else { + MessageBox.Show($"Trainer File saved successfully. However:\nThe Trainer name length could not be safely determined for this ROM.\n" + + $"You attempted to save a Trainer whose name exceeds {RomInfo.trainerNameMaxLen-1} characters.\nThis will most likely lead to issues in game.", + "Saved successfully, but...", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } else { + MessageBox.Show("Trainer saved successfully!", "Saved successfully", MessageBoxButtons.OK, MessageBoxIcon.Information); + } } private void UpdateCurrentTrainerShownName() { diff --git a/DS_Map/ROMFiles/TrainerFile.cs b/DS_Map/ROMFiles/TrainerFile.cs index 5e4bef2..567cf22 100644 --- a/DS_Map/ROMFiles/TrainerFile.cs +++ b/DS_Map/ROMFiles/TrainerFile.cs @@ -321,7 +321,7 @@ namespace DSPRE.ROMFiles { } } public class TrainerFile : RomFile { - public const int maxNameLen = 7; + public const int defaultNameLen = 7; //Does not include special \0 end character! public const int POKE_IN_PARTY = 6; public static readonly string NAME_NOT_FOUND = "NAME READ ERROR"; diff --git a/DS_Map/ROMToolboxDialog.cs b/DS_Map/ROMToolboxDialog.cs index ac2fb26..882130e 100644 --- a/DS_Map/ROMToolboxDialog.cs +++ b/DS_Map/ROMToolboxDialog.cs @@ -30,7 +30,7 @@ namespace DSPRE { public static bool overlay1MustBeRestoredFromBackup { get; private set; } = true; - public static int expandedTrainerNameLength = 12; + public static readonly int expandedTrainerNameLength = 12; #region Constructor public ROMToolboxDialog() { @@ -40,14 +40,15 @@ namespace DSPRE { if (RomInfo.gameLanguage == gLangEnum.English || RomInfo.gameLanguage == gLangEnum.Spanish) { CheckARM9ExpansionApplied(); - CheckExpandedTrainerNamespatchApplied(); } else { DisableARM9patch("Unsupported\nlanguage"); DisableBDHCamPatch("Unsupported\nlanguage"); DisableScrcmdRepointPatch("Unsupported\nlanguage"); - DisableTrainerNameExpansionPatch("Unsuported\nlanguage"); } + CheckExpandedTrainerNamesPatchApplied(); + + switch (RomInfo.gameFamily) { case gFamEnum.DP: DisableOverlay1patch("Unsupported"); @@ -316,33 +317,21 @@ namespace DSPRE { //throw new NotImplementedException(); } - public void CheckExpandedTrainerNamespatchApplied() { - if (!flag_TrainerNamesExpanded) { - uint position = 0x6AC32; - switch (RomInfo.gameFamily) { - case gFamEnum.DP: - if (RomInfo.gameLanguage.Equals(gLangEnum.English)) position = 0x6AC32; - else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x6AC8E; - break; - case gFamEnum.Plat: - if (RomInfo.gameLanguage.Equals(gLangEnum.English)) position = 0x791DE; - else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x7927E; - break; - case gFamEnum.HGSS: - if (RomInfo.gameLanguage.Equals(gLangEnum.English) || RomInfo.gameVersion.Equals(gVerEnum.SoulSilver)) position = 0x7342E; - else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x73426; - break; - } - byte initValue = DSUtils.ARM9.ReadByte(position); - if (initValue > (byte)TrainerFile.maxNameLen) { - DisableTrainerNameExpansionPatch("Already\nApplied"); - ROMToolboxDialog.flag_TrainerNamesExpanded = true; - ROMToolboxDialog.expandedTrainerNameLength = initValue; - } - } else { + public void CheckExpandedTrainerNamesPatchApplied() { + if (flag_TrainerNamesExpanded) { DisableTrainerNameExpansionPatch("Already\nApplied"); - } + } else { + if (RomInfo.trainerNameLenOffset < 0 ) { + DisableTrainerNameExpansionPatch("Unsupported"); + } else { + int v = RomInfo.SetTrainerNameMaxLen(); + if (v > TrainerFile.defaultNameLen+1) { + DisableTrainerNameExpansionPatch("Already\nApplied"); + ROMToolboxDialog.flag_TrainerNamesExpanded = true; + } + } + } } #endregion @@ -832,46 +821,24 @@ namespace DSPRE { // HeartGold Spain ARM9 at 0x73426 // SoulSilver USA ARM9 at 0x7342E // SoulSilver Spain ARM9 at 0x7342E // TODO: Verify - DialogResult d; - int position = 0x7342E; - bool gameFamGood = true; - d = MessageBox.Show($"Applying this patch will set the Trainer Name max length to {ROMToolboxDialog.expandedTrainerNameLength}.\n" + - "Please note that if you have modified the ARM9 these offsets may be wrong.\n" + - "If you have done so we encourage you to seek in your ARM9 for where to make the modification as your offset might change.\n\n" + + + DialogResult d = MessageBox.Show($"Applying this patch will set the Trainer Name max length to {ROMToolboxDialog.expandedTrainerNameLength-1} usable characters.\n" + "Are you sure you want to proceed?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); if (d == DialogResult.Yes) { - switch (RomInfo.gameFamily) { - case gFamEnum.DP: - if (RomInfo.gameLanguage.Equals(gLangEnum.English)) position = 0x6AC32; - else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x6AC8E; - else gameFamGood = false; - break; - case gFamEnum.Plat: - if (RomInfo.gameLanguage.Equals(gLangEnum.English)) position = 0x791DE; - else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x7927E; - else gameFamGood = false; - break; - case gFamEnum.HGSS: - if (RomInfo.gameLanguage.Equals(gLangEnum.English) || RomInfo.gameVersion.Equals(gVerEnum.SoulSilver)) position = 0x7342E; - else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) position = 0x73426; - else gameFamGood = false; - break; - } - if (gameFamGood) { - using (DSUtils.ARM9.Writer wr = new DSUtils.ARM9.Writer()) { - wr.BaseStream.Position = position; + try { + using (DSUtils.ARM9.Writer wr = new DSUtils.ARM9.Writer(RomInfo.trainerNameLenOffset)) { wr.Write((byte)ROMToolboxDialog.expandedTrainerNameLength); } + ROMToolboxDialog.flag_TrainerNamesExpanded = true; DisableTrainerNameExpansionPatch("Already applied"); expandTrainerNamesCB.Visible = true; - MessageBox.Show("Trainer Names have been expanded.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); - } else { - MessageBox.Show("Sorry this game language does not have a recorded offset for this patch.\n\n" + - "Reach out in our discord if you want to help researching it!", - "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); + RomInfo.SetTrainerNameMaxLen(); + MessageBox.Show("Trainer Names have been extended.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); + } catch (IOException) { + MessageBox.Show("ARM9 could not be written.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); diff --git a/DS_Map/RomInfo.cs b/DS_Map/RomInfo.cs index 5f18fe2..711bd20 100644 --- a/DS_Map/RomInfo.cs +++ b/DS_Map/RomInfo.cs @@ -65,6 +65,8 @@ namespace DSPRE { public static int trainerClassMessageNumber { get; private set; } public static int trainerNamesMessageNumber { get; private set; } public static int locationNamesTextNumber { get; private set; } + public static int trainerNameLenOffset { get; private set; } + public static int trainerNameMaxLen { get; private set; } public static string internalNamesLocation { get; private set; } public static readonly byte internalNameLength = 16; @@ -183,6 +185,7 @@ namespace DSPRE { SetLocationNamesTextNumber(); SetTrainerNamesMessageNumber(); SetTrainerClassMessageNumber(); + SetTrainerNameLenOffset(); /* System */ ScriptCommandParametersDict = BuildCommandParametersDatabase(gameFamily); @@ -742,7 +745,7 @@ namespace DSPRE { } } - private void SetItemScriptFileNumber() { + private static void SetItemScriptFileNumber() { switch (gameFamily) { case gFamEnum.DP: itemScriptFileNumber = 370; @@ -755,7 +758,7 @@ namespace DSPRE { break; } } - private void SetNullEncounterID() { + private static void SetNullEncounterID() { switch (gameFamily) { case gFamEnum.DP: case gFamEnum.Plat: @@ -767,7 +770,7 @@ namespace DSPRE { } } - private void SetAbilityNamesTextNumber() { + private static void SetAbilityNamesTextNumber() { switch (gameFamily) { case gFamEnum.DP: abilityNamesTextNumber = 552; @@ -783,7 +786,7 @@ namespace DSPRE { } } - private void SetAttackNamesTextNumber() { + private static void SetAttackNamesTextNumber() { switch (gameFamily) { case gFamEnum.DP: attackNamesTextNumber = 588; @@ -796,7 +799,7 @@ namespace DSPRE { break; } } - private void SetItemNamesTextNumber() { + private static void SetItemNamesTextNumber() { switch (gameFamily) { case gFamEnum.DP: itemNamesTextNumber = 344; @@ -809,7 +812,7 @@ namespace DSPRE { break; } } - private void SetLocationNamesTextNumber() { + private static void SetLocationNamesTextNumber() { switch (gameFamily) { case gFamEnum.DP: locationNamesTextNumber = 382; @@ -822,7 +825,7 @@ namespace DSPRE { break; } } - private void SetPokemonNamesTextNumber() { + private static void SetPokemonNamesTextNumber() { switch (gameFamily) { case gFamEnum.DP: pokemonNamesTextNumbers = new int[2] { 362, 363 }; @@ -835,7 +838,7 @@ namespace DSPRE { break; } } - private void SetTrainerNamesMessageNumber() { + private static void SetTrainerNamesMessageNumber() { switch (gameFamily) { case gFamEnum.DP: trainerNamesMessageNumber = 559; @@ -854,7 +857,7 @@ namespace DSPRE { break; } } - private void SetTrainerClassMessageNumber() { + private static void SetTrainerClassMessageNumber() { switch (gameFamily) { case gFamEnum.DP: trainerClassMessageNumber = 560; @@ -874,6 +877,61 @@ namespace DSPRE { } } + private static void SetTrainerNameLenOffset() { + switch (RomInfo.gameFamily) { + case gFamEnum.DP: + switch (RomInfo.gameLanguage) { + case gLangEnum.English: + trainerNameLenOffset = 0x6AC32; + break; + case gLangEnum.Spanish: + trainerNameLenOffset = 0x6AC8E; + break; + default: + trainerNameLenOffset = -1; + break; + } + + break; + case gFamEnum.Plat: + switch (RomInfo.gameLanguage) { + case gLangEnum.English: + trainerNameLenOffset = 0x791DE; + break; + case gLangEnum.Spanish: + case gLangEnum.German: + trainerNameLenOffset = 0x7927E; + break; + default: + trainerNameLenOffset = -1; + break; + } + + break; + case gFamEnum.HGSS: + if (RomInfo.gameLanguage.Equals(gLangEnum.English) || RomInfo.gameVersion.Equals(gVerEnum.SoulSilver)) { + trainerNameLenOffset = 0x7342E; + } else if (RomInfo.gameLanguage.Equals(gLangEnum.Spanish)) { + trainerNameLenOffset = 0x73426; + } else { + trainerNameLenOffset = -1; + } + + break; + } + } + + public static int SetTrainerNameMaxLen() { + if(trainerNameLenOffset < 0) { + trainerNameMaxLen = TrainerFile.defaultNameLen; + } else { + using (DSUtils.ARM9.Reader ar = new DSUtils.ARM9.Reader(trainerNameLenOffset)) { + trainerNameMaxLen = ar.ReadByte(); + } + } + return trainerNameMaxLen; + } + public string GetBuildingModelsDirPath(bool interior) => interior ? gameDirs[DirNames.interiorBuildingModels].unpackedDir : gameDirs[DirNames.exteriorBuildingModels].unpackedDir; public string GetRomNameFromWorkdir() => workDir.Substring(0, workDir.Length - folderSuffix.Length - 1); public static int GetHeaderCount() => (int)new FileInfo(internalNamesLocation).Length / internalNameLength;