From 910844fb1bfb7ab2609c0a2c02a5999bc54b4ba5 Mon Sep 17 00:00:00 2001 From: AdAstra-LD <76622070+AdAstra-LD@users.noreply.github.com> Date: Wed, 26 Jun 2024 01:01:41 +0200 Subject: [PATCH 1/4] Restored trainer name encryption This reverts commit 23b19eff548340dafc864f638627e2a0871380cf. --- DS_Map/DSPRE.csproj | 1 + DS_Map/Main Window.cs | 8 +- DS_Map/MessageEnc/EncryptText.cs | 387 +++++++++++++++++++++ DS_Map/PatchToolboxDialog.cs | 555 ++++++++++++++++++++---------- DS_Map/PatchToolboxDialog.resx | 18 +- DS_Map/ROMFiles/TextArchive.cs | 339 ++++++++----------- DS_Map/ROMFiles/TrainerFile.cs | 2 +- DS_Map/RomInfo.cs | 559 +++++++++++++++++++++++-------- 8 files changed, 1348 insertions(+), 521 deletions(-) create mode 100644 DS_Map/MessageEnc/EncryptText.cs diff --git a/DS_Map/DSPRE.csproj b/DS_Map/DSPRE.csproj index 5f4fb2d..61a6b37 100644 --- a/DS_Map/DSPRE.csproj +++ b/DS_Map/DSPRE.csproj @@ -190,6 +190,7 @@ LearnsetEditor.cs + Form diff --git a/DS_Map/Main Window.cs b/DS_Map/Main Window.cs index 4f3df37..5cdf5de 100644 --- a/DS_Map/Main Window.cs +++ b/DS_Map/Main Window.cs @@ -7813,7 +7813,7 @@ namespace DSPRE { private void SetupTrainerEditor() { Helpers.DisableHandlers(); - SetTrainerNameMaxLen(); + //SetTrainerNameMaxLen(); SetupTrainerClassEncounterMusicTable(); /* Extract essential NARCs sub-archives*/ Helpers.statusLabelMessage("Setting up Trainer Editor..."); @@ -8324,15 +8324,15 @@ namespace DSPRE { UpdateCurrentTrainerName(newName: trainerNameTextBox.Text); UpdateCurrentTrainerShownName(); - if (trainerNameTextBox.Text.Length > RomInfo.trainerNameMaxLen - 1) { //Subtract 1 to account for special end character. + if (trainerNameTextBox.Text.Length > RomInfo.trainerNameMaxLen) { //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." + + MessageBox.Show($"Trainer File saved successfully. However:\nYou attempted to save a Trainer whose name exceeds {RomInfo.trainerNameMaxLen} characters.\nThis may lead to issues in game." + (PatchToolboxDialog.flag_TrainerNamesExpanded ? "\n\nIt's recommended that you use a shorter name." : "\n\nRefer to the Patch 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.", + $"You attempted to save a Trainer whose name exceeds {RomInfo.trainerNameMaxLen} characters.\nThis will most likely lead to issues in game.", "Saved successfully, but...", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } else { diff --git a/DS_Map/MessageEnc/EncryptText.cs b/DS_Map/MessageEnc/EncryptText.cs new file mode 100644 index 0000000..54db1c1 --- /dev/null +++ b/DS_Map/MessageEnc/EncryptText.cs @@ -0,0 +1,387 @@ +using DSPRE.Resources; +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using static DSPRE.RomInfo; + +namespace DSPRE.MessageEnc +{ + public static class EncryptText + { + private static readonly Dictionary GetCharDictionary = TextDatabase.readTextDictionary; + private static readonly Dictionary WriteCharDictionary = TextDatabase.writeTextDictionary; + + private static string DecodeCharacter(int textChar) + { + if (GetCharDictionary.TryGetValue(textChar, out var character)) + { + return character; + } + else + { + return $"\\x{textChar:X4}"; + } + } + + public static string DecodeMessage(BinaryReader reader, int key, int offset, int size) + { + bool hasSpecialCharacter = false; + bool isCompressed = false; + reader.BaseStream.Position = offset; + StringBuilder decode = new StringBuilder(""); + for (int j = 0; j < size; j++) + { + int textChar = (reader.ReadUInt16()) ^ key; + switch (textChar) + { + case 0xE000: + decode.Append("\\n"); + break; + + case 0x25BC: + decode.Append("\\r"); + break; + + case 0x25BD: + decode.Append("\\f"); + break; + + case 0xF100: + isCompressed = true; + break; + + case 0xFFFE: + decode.Append("\\v"); + hasSpecialCharacter = true; + break; + + case 0xFFFF: + decode.Append(""); + break; + + default: + if (hasSpecialCharacter) + { + decode.Append(textChar.ToString("X4")); + hasSpecialCharacter = false; + } + if (isCompressed) + { + int shift = 0; + int trans = 0; + while (true) + { + int compChar = textChar >> shift; + if (shift >= 0xF) + { + shift -= 0xF; + if (shift > 0) + { + compChar = (trans | ((textChar << (9 - shift)) & 0x1FF)); + if ((compChar & 0xFF) == 0xFF) + { + break; + } + if (compChar != 0x0 && compChar != 0x1) + { + decode.Append(DecodeCharacter(compChar)); + } + } + } + else + { + compChar = (textChar >> shift) & 0x1FF; + if ((compChar & 0xFF) == 0xFF) + { + break; + } + if (compChar != 0x0 && compChar != 0x1) + { + decode.Append(DecodeCharacter(compChar)); + } + shift += 9; + if (shift < 0xF) + { + trans = (textChar >> shift) & 0x1FF; + shift += 9; + } + key += 0x493D; + key &= 0xFFFF; + textChar = Convert.ToUInt16(reader.ReadUInt16() ^ key); + j++; + } + } + decode.Append(""); + } + else + { + decode.Append(DecodeCharacter(textChar)); + } + break; + } + key += 0x493D; + key &= 0xFFFF; + } + return decode.ToString(); + } + + public static List ReadMessageArchive(FileStream fileStream, bool discardLines) + { + int initialKey = 0; + int stringCount = 0; + List messagesString = new List(); + bool success = false; + using (BinaryReader reader = new BinaryReader(fileStream)) + { + try + { + stringCount = reader.ReadUInt16(); + success = true; + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + reader.Close(); + fileStream.Close(); + throw; + } + + if (success) + { + try + { + initialKey = reader.ReadUInt16(); + if (!discardLines) + { + int[] offsets = new int[stringCount]; + int[] sizes = new int[stringCount]; + int key = (initialKey * 0x2FD) & 0xFFFF; + + for (int i = 0; i < stringCount; i++) + { + int key2 = (key * (i + 1) & 0xFFFF); + int actualKey = key2 | (key2 << 16); + offsets[i] = ((int)reader.ReadUInt32()) ^ actualKey; + sizes[i] = ((int)reader.ReadUInt32()) ^ actualKey; + } + for (int i = 0; i < stringCount; i++) + { + key = (0x91BD3 * (i + 1)) & 0xFFFF; + messagesString.Add(DecodeMessage(reader, key, offsets[i], sizes[i])); + } + } + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + reader.Close(); + fileStream.Close(); + throw; + } + } + } + + fileStream.Close(); + return messagesString; + } + + private static int[] EncodeMessage(string message, bool isTrainerName = false) + { + List encoded = new List(); + int compressionBuffer = 0; + int bit = 0; + if (isTrainerName) + { + encoded.Add(0xF100); + } + var charArray = message.ToCharArray(); + string characterId; + for (int i = 0; i < charArray.Length; i++) + { + switch (charArray[i]) + { + case '\\': + switch (charArray[i + 1]) + { + case 'r': + encoded.Add(0x25BC); + i++; + break; + + case 'n': + encoded.Add(0xE000); + i++; + break; + + case 'f': + encoded.Add(0x25BD); + i++; + break; + + case 'v': + encoded.Add(0xFFFE); + characterId = $"{charArray[i + 2]}{charArray[i + 3]}{charArray[i + 4]}{charArray[i + 5]}"; + encoded.Add((int)Convert.ToUInt32(characterId, 16)); + i += 5; + break; + + case 'x': + if (charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '0') + { + encoded.Add(0x0000); + i += 5; + break; + } + else if (charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '1') + { + encoded.Add(0x0001); + i += 5; + break; + } + else + { + characterId = $"{charArray[i + 2]}{charArray[i + 3]}{charArray[i + 4]}{charArray[i + 5]}"; + encoded.Add((int)Convert.ToUInt32(characterId, 16)); + i += 5; + break; + } + } + break; + + case '[': + switch (charArray[i + 1]) + { + case 'P': + encoded.Add(0x01E0); + i += 3; + break; + + case 'M': + encoded.Add(0x01E1); + i += 3; + break; + } + break; + + default: + + WriteCharDictionary.TryGetValue(charArray[i], out int code); + if (isTrainerName) + { + compressionBuffer |= code << bit; + bit += 9; + if (bit >= 15) + { + bit -= 15; + encoded.Add((int)Convert.ToUInt32(compressionBuffer & 0x7FFF)); + compressionBuffer >>= 15; + } + } + else + { + encoded.Add(code); + } + break; + } + } + if (isTrainerName && bit > 1) + { + compressionBuffer |= (0xFFFF << bit); + encoded.Add((int)Convert.ToUInt32(compressionBuffer & 0x7FFF)); + } + encoded.Add(0xFFFF); + return encoded.ToArray(); + } + + private static List EncodeMessages(List messages, bool isTrainerName = false) + { + List encoded = new List(); + foreach (var message in messages) + { + encoded.Add(EncodeMessage(message, isTrainerName)); + } + return encoded; + } + + private static int GetInitialKey(string filePath) + { + int initialKey = 0; + var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); + using (BinaryReader reader = new BinaryReader(fileStream)) + { + try + { + reader.BaseStream.Position = 2; + initialKey = reader.ReadUInt16(); + reader.Close(); + fileStream.Close(); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + reader.Close(); + fileStream.Close(); + throw; + } + } + return initialKey; + } + + public static bool WriteMessageArchive(int messageArchiveId, List messages, bool isTrainerName = false) + { + string filePath = $"{gameDirs[DirNames.textArchives].unpackedDir}\\{messageArchiveId:D4}"; + int initialKey = GetInitialKey(filePath); + + var stream = new MemoryStream(); + using (BinaryWriter writer = new BinaryWriter(stream)) + { + try + { + List encoded = EncodeMessages(messages, isTrainerName); + int encodedSize = encoded.Count; + writer.Write((ushort)encodedSize); + writer.Write((ushort)initialKey); + int key = (initialKey * 0x2FD) & 0xFFFF; + int key2 = 0; + int actualKey = 0; + int offset = 0x4 + (encodedSize * 8); + int[] stringLengths = new int[encodedSize]; + + for (int i = 0; i < encodedSize; i++) + { + key2 = (key * (i + 1) & 0xFFFF); + actualKey = key2 | (key2 << 16); + writer.Write(offset ^ actualKey); + int[] currentString = encoded[i]; + int length = encoded[i].Length; + stringLengths[i] = length; + writer.Write(length ^ actualKey); + offset += length * 2; + } + for (int i = 0; i < encodedSize; i++) + { + key = (0x91BD3 * (i + 1)) & 0xFFFF; + int[] currentMessage = encoded[i]; + for (int j = 0; j < stringLengths[i] - 1; j++) + { + writer.Write((ushort)(currentMessage[j] ^ key)); + key += 0x493D; + key &= 0xFFFF; + } + writer.Write((ushort)(0xFFFF ^ key)); + System.IO.File.WriteAllBytes(filePath, stream.ToArray()); + } + } + catch (Exception ex) + { + writer.Close(); + Console.WriteLine(ex.Message); + return false; + throw; + } + } + return true; + } + } +} \ No newline at end of file diff --git a/DS_Map/PatchToolboxDialog.cs b/DS_Map/PatchToolboxDialog.cs index 249775c..f9dfd87 100644 --- a/DS_Map/PatchToolboxDialog.cs +++ b/DS_Map/PatchToolboxDialog.cs @@ -13,8 +13,10 @@ using System.Threading.Tasks; using static DSPRE.Resources.ROMToolboxDB.ToolboxDB; using static NSMBe4.ROM; -namespace DSPRE { - public partial class PatchToolboxDialog : Form { +namespace DSPRE +{ + public partial class PatchToolboxDialog : Form + { public static uint expandedARMfileID = ToolboxDB.syntheticOverlayFileNumbersDB[RomInfo.gameFamily]; public static bool flag_standardizedItems { get; private set; } = false; @@ -33,14 +35,19 @@ namespace DSPRE { public static readonly int expandedTrainerNameLength = 12; #region Constructor - public PatchToolboxDialog() { + + public PatchToolboxDialog() + { InitializeComponent(); CheckStandardizedItems(); - if (RomInfo.gameLanguage == GameLanguages.English || RomInfo.gameLanguage == GameLanguages.Spanish) { + if (RomInfo.gameLanguage == GameLanguages.English || RomInfo.gameLanguage == GameLanguages.Spanish) + { CheckARM9ExpansionApplied(); - } else { + } + else + { DisableARM9patch("Unsupported\nlanguage"); DisableBDHCamPatch("Unsupported\nlanguage"); DisableScrcmdRepointPatch("Unsupported\nlanguage"); @@ -48,8 +55,8 @@ namespace DSPRE { CheckExpandedTrainerNamesPatchApplied(); - - switch (RomInfo.gameFamily) { + switch (RomInfo.gameFamily) + { case GameFamilies.DP: DisableOverlay1patch("Unsupported"); DisableDynamicHeadersPatch("Unsupported"); @@ -57,28 +64,35 @@ namespace DSPRE { DisableScrcmdRepointPatch("Unsupported"); DisableKillTextureAnimationsPatch("Unsupported"); break; + case GameFamilies.Plat: DisableOverlay1patch("Unsupported"); DisableMatrixExpansionPatch("Unsupported"); DisableScrcmdRepointPatch("Unsupported"); DisableKillTextureAnimationsPatch("Unsupported"); - if (RomInfo.gameLanguage == GameLanguages.English || RomInfo.gameLanguage == GameLanguages.Spanish) { + if (RomInfo.gameLanguage == GameLanguages.English || RomInfo.gameLanguage == GameLanguages.Spanish) + { CheckBDHCamPatchApplied(); } CheckDynamicHeadersPatchApplied(); break; + case GameFamilies.HGSS: - if (!OverlayUtils.OverlayTable.IsDefaultCompressed(1)) { + if (!OverlayUtils.OverlayTable.IsDefaultCompressed(1)) + { DisableOverlay1patch("Already applied"); overlay1CB.Visible = true; } - if (RomInfo.gameLanguage == GameLanguages.English || RomInfo.gameLanguage == GameLanguages.Spanish) { + if (RomInfo.gameLanguage == GameLanguages.English || RomInfo.gameLanguage == GameLanguages.Spanish) + { CheckBDHCamPatchApplied(); CheckMatrixExpansionApplied(); CheckScrcmdRepointPatchApplied(); - } else { + } + else + { DisableMatrixExpansionPatch("Unsupported\nlanguage"); DisableScrcmdRepointPatch("Unsupported\nlanguage"); } @@ -89,67 +103,89 @@ namespace DSPRE { } #region Patch Disable - private void DisableOverlay1patch(string reason) { + + private void DisableOverlay1patch(string reason) + { overlay1uncomprButton.Enabled = false; overlay1uncompressedLBL.Enabled = false; overlay1patchtextLBL.Enabled = false; overlay1uncomprButton.Text = reason; } - private void DisableBDHCamPatch(string reason) { + + private void DisableBDHCamPatch(string reason) + { BDHCamPatchButton.Enabled = false; BDHCamPatchLBL.Enabled = false; BDHCamPatchTextLBL.Enabled = false; BDHCamARM9requiredLBL.Enabled = false; BDHCamPatchButton.Text = reason; } - private void DisableARM9patch(string reason) { + + private void DisableARM9patch(string reason) + { applyARM9ExpansionButton.Enabled = false; arm9expansionTextLBL.Enabled = false; arm9expansionLBL.Enabled = false; applyARM9ExpansionButton.Text = reason; } - private void DisableDynamicHeadersPatch(string reason) { + + private void DisableDynamicHeadersPatch(string reason) + { applyDynamicHeadersButton.Enabled = false; dynamicHeadersTextLBL.Enabled = false; dynamicHeadersLBL.Enabled = false; applyDynamicHeadersButton.Text = reason; } - private void DisableMatrixExpansionPatch(string reason) { + + private void DisableMatrixExpansionPatch(string reason) + { expandMatrixButton.Enabled = false; matrixExpansionLBL.Enabled = false; matrixExpansionTextLBL.Enabled = false; expandMatrixButton.Text = reason; } - private void DisableStandardizeItemsPatch(string reason) { + + private void DisableStandardizeItemsPatch(string reason) + { applyItemStandardizeButton.Enabled = false; standardizePatchLBL.Enabled = false; standardizePatchTextLBL.Enabled = false; applyItemStandardizeButton.Text = reason; } - private void DisableScrcmdRepointPatch(string reason) { + + private void DisableScrcmdRepointPatch(string reason) + { repointScrcmdButton.Enabled = false; repointScrcmdLBL.Enabled = false; repointScrcmdTextLBL.Enabled = false; scrcmdARM9requiredLBL.Enabled = false; repointScrcmdButton.Text = reason; } - private void DisableKillTextureAnimationsPatch(string reason) { + + private void DisableKillTextureAnimationsPatch(string reason) + { disableTextureAnimationsButton.Enabled = false; disableTextureAnimationsLBL.Enabled = false; disableTextureAnimationsTextLBL.Enabled = false; disableTextureAnimationsButton.Text = reason; } - private void DisableTrainerNameExpansionPatch(string reason) { + + private void DisableTrainerNameExpansionPatch(string reason) + { expandTrainerNamesButton.Enabled = false; expandTrainerNamesLBL.Enabled = false; expandTrainerNamesTextLBL.Enabled = false; expandTrainerNamesButton.Text = reason; } - #endregion - #endregion - #region Patch - private static bool CheckFilesArm9ExpansionApplied() { + #endregion Patch Disable + + #endregion Constructor + + #region Patch + + private static bool CheckFilesArm9ExpansionApplied() + { ARM9PatchData data = new ARM9PatchData(); byte[] branchCode = DSUtils.HexStringToByteArray(data.branchString); @@ -164,13 +200,16 @@ namespace DSPRE { return true; } - public static bool CheckFilesBDHCamPatchApplied() { + + public static bool CheckFilesBDHCamPatchApplied() + { BDHCAMPatchData data = new BDHCAMPatchData(); byte[] branchCode = DSUtils.HexStringToByteArray(data.branchString); byte[] branchCodeRead = ARM9.ReadBytes(data.branchOffset, branchCode.Length); - if (branchCode.Length != branchCodeRead.Length || !branchCode.SequenceEqual(branchCodeRead)) { + if (branchCode.Length != branchCodeRead.Length || !branchCode.SequenceEqual(branchCodeRead)) + { return false; } @@ -182,7 +221,6 @@ namespace DSPRE { if (overlayCode1.Length != overlayCode1Read.Length || !overlayCode1.SequenceEqual(overlayCode1Read)) return false; - byte[] overlayCode2 = DSUtils.HexStringToByteArray(data.overlayString2); byte[] overlayCode2Read = DSUtils.ReadFromFile(overlayFilePath, data.overlayOffset2, overlayCode2.Length); //Write new overlayCode1 if (overlayCode2.Length != overlayCode2Read.Length || !overlayCode2.SequenceEqual(overlayCode2Read)) @@ -195,11 +233,16 @@ namespace DSPRE { return true; } - public static bool CheckFilesMatrixExpansionApplied() { - foreach (KeyValuePair kv in ToolboxDB.matrixExpansionDB) { - foreach (uint offset in kv.Key) { + + public static bool CheckFilesMatrixExpansionApplied() + { + foreach (KeyValuePair kv in ToolboxDB.matrixExpansionDB) + { + foreach (uint offset in kv.Key) + { int languageOffset = 0; - if (RomInfo.romID == "IPKE" || RomInfo.romID == "IPGE" || RomInfo.romID == "IPGS") { + if (RomInfo.romID == "IPKE" || RomInfo.romID == "IPGE" || RomInfo.romID == "IPGS") + { languageOffset = +8; } @@ -211,24 +254,33 @@ namespace DSPRE { } return true; } - public static bool CheckScriptsStandardizedItemNumbers() { + + public static bool CheckScriptsStandardizedItemNumbers() + { ScriptFile itemScript = new ScriptFile(RomInfo.itemScriptFileNumber); - if (itemScript.allScripts.Count - 1 < new TextArchive(RomInfo.itemNamesTextNumber).messages.Count) { + if (itemScript.allScripts.Count - 1 < new TextArchive(RomInfo.itemNamesTextNumber).messages.Count) + { return false; } - for (ushort i = 0; i < itemScript.allScripts.Count - 1; i++) { - if (BitConverter.ToUInt16(itemScript.allScripts[i].commands[0].cmdParams[1], 0) != i || BitConverter.ToUInt16(itemScript.allScripts[i].commands[1].cmdParams[1], 0) != 1) { + for (ushort i = 0; i < itemScript.allScripts.Count - 1; i++) + { + if (BitConverter.ToUInt16(itemScript.allScripts[i].commands[0].cmdParams[1], 0) != i || BitConverter.ToUInt16(itemScript.allScripts[i].commands[1].cmdParams[1], 0) != 1) + { return false; } } return true; } - public bool CheckStandardizedItems() { + + public bool CheckStandardizedItems() + { DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.scripts }); - if (!PatchToolboxDialog.flag_standardizedItems) { - if (!PatchToolboxDialog.CheckScriptsStandardizedItemNumbers()) { + if (!PatchToolboxDialog.flag_standardizedItems) + { + if (!PatchToolboxDialog.CheckScriptsStandardizedItemNumbers()) + { return false; } } @@ -239,9 +291,13 @@ namespace DSPRE { DisableStandardizeItemsPatch("Already applied"); return true; } - public bool CheckMatrixExpansionApplied() { - if (!PatchToolboxDialog.flag_MatrixExpansionApplied) { - if (!PatchToolboxDialog.CheckFilesMatrixExpansionApplied()) { + + public bool CheckMatrixExpansionApplied() + { + if (!PatchToolboxDialog.flag_MatrixExpansionApplied) + { + if (!PatchToolboxDialog.CheckFilesMatrixExpansionApplied()) + { return false; } } @@ -251,10 +307,15 @@ namespace DSPRE { expandedMatrixCB.Visible = true; return true; } + public string backupSuffix = ".backup"; - private bool CheckARM9ExpansionApplied() { - if (!PatchToolboxDialog.flag_arm9Expanded) { - if (!PatchToolboxDialog.CheckFilesArm9ExpansionApplied()) { + + private bool CheckARM9ExpansionApplied() + { + if (!PatchToolboxDialog.flag_arm9Expanded) + { + if (!PatchToolboxDialog.CheckFilesArm9ExpansionApplied()) + { return false; } } @@ -263,7 +324,8 @@ namespace DSPRE { arm9patchCB.Visible = true; DisableARM9patch("Already applied"); - switch (RomInfo.gameFamily) { + switch (RomInfo.gameFamily) + { case GameFamilies.Plat: case GameFamilies.HGSS: BDHCamARM9requiredLBL.Visible = false; @@ -275,9 +337,13 @@ namespace DSPRE { return true; } - public bool CheckDynamicHeadersPatchApplied() { - if (!flag_DynamicHeadersPatchApplied) { - if (!PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + + public bool CheckDynamicHeadersPatchApplied() + { + if (!flag_DynamicHeadersPatchApplied) + { + if (!PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) + { return false; } } @@ -289,21 +355,26 @@ namespace DSPRE { return true; } - public static bool CheckFilesDynamicHeadersPatchApplied() { + public static bool CheckFilesDynamicHeadersPatchApplied() + { DynamicHeadersPatchData data = new DynamicHeadersPatchData(); ushort initValue = BitConverter.ToUInt16(ARM9.ReadBytes(data.initOffset, 0x2), 0); return initValue == 0xB500; } - public bool CheckBDHCamPatchApplied() { - if (!CheckARM9ExpansionApplied()) { + public bool CheckBDHCamPatchApplied() + { + if (!CheckARM9ExpansionApplied()) + { BDHCamARM9requiredLBL.Visible = true; DisableBDHCamPatch("ARM9 not expanded!"); return false; } - if (!PatchToolboxDialog.flag_BDHCamPatchApplied) { - if (!PatchToolboxDialog.CheckFilesBDHCamPatchApplied()) { + if (!PatchToolboxDialog.flag_BDHCamPatchApplied) + { + if (!PatchToolboxDialog.CheckFilesBDHCamPatchApplied()) + { return false; } } @@ -313,41 +384,56 @@ namespace DSPRE { DisableBDHCamPatch("Already applied"); return true; } - public void CheckScrcmdRepointPatchApplied() { + + public void CheckScrcmdRepointPatchApplied() + { //throw new NotImplementedException(); } - public void CheckExpandedTrainerNamesPatchApplied() { - if (flag_TrainerNamesExpanded) { + public void CheckExpandedTrainerNamesPatchApplied() + { + if (flag_TrainerNamesExpanded) + { DisableTrainerNameExpansionPatch("Already\nApplied"); - } else { - if (RomInfo.trainerNameLenOffset < 0 ) { + } + else + { + if (RomInfo.trainerNameLenOffset < 0) + { DisableTrainerNameExpansionPatch("Unsupported"); - } else { - int v = RomInfo.SetTrainerNameMaxLen(); - - if (v > TrainerFile.defaultNameLen+1) { + } + else + { + if (RomInfo.trainerNameMaxLen > TrainerFile.defaultNameLen) + { DisableTrainerNameExpansionPatch("Already\nApplied"); PatchToolboxDialog.flag_TrainerNamesExpanded = true; } } } } - #endregion + + #endregion Patch #region Button Actions - private void SentenceCasePatchButton_Click(object sender, EventArgs e) { + + private void SentenceCasePatchButton_Click(object sender, EventArgs e) + { DialogResult d; d = MessageBox.Show("Confirming this process will apply the following changes:\n\n" + "- Every Pokémon name will be converted to Sentence Case." + "\n\n" + "Do you wish to continue?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.Yes) { - Parallel.ForEach(RomInfo.pokemonNamesTextNumbers, ID => { + if (d == DialogResult.Yes) + { + Parallel.ForEach(RomInfo.pokemonNamesTextNumbers, ID => + { TextArchive pokeName = new TextArchive(ID); - Parallel.For(1, pokeName.messages.Count, i => { - if (pokeName.messages[i].Length <= 1) { + Parallel.For(1, pokeName.messages.Count, i => + { + if (pokeName.messages[i].Length <= 1) + { i++; } @@ -357,20 +443,27 @@ namespace DSPRE { }); //sentenceCaseCB.Visible = true; MessageBox.Show("Pokémon names have been converted to Sentence Case.", "Operation successful", MessageBoxButtons.OK, MessageBoxIcon.Information); - } else { + } + else + { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); } } - private void BDHCAMPatchButton_Click(object sender, EventArgs e) { + + private void BDHCAMPatchButton_Click(object sender, EventArgs e) + { BDHCAMPatchData data = new BDHCAMPatchData(); - if (RomInfo.gameFamily == GameFamilies.HGSS) { - if (OverlayUtils.OverlayTable.IsDefaultCompressed(data.overlayNumber)) { + if (RomInfo.gameFamily == GameFamilies.HGSS) + { + if (OverlayUtils.OverlayTable.IsDefaultCompressed(data.overlayNumber)) + { DialogResult d1 = MessageBox.Show("It is STRONGLY recommended to configure Overlay1 as uncompressed before proceeding.\n\n" + "More details in the following dialog.\n\n" + "Do you want to know more?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d1 == DialogResult.Yes) { + if (d1 == DialogResult.Yes) + { overlay1uncomprButton_Click(null, null); } } @@ -387,15 +480,18 @@ namespace DSPRE { "Do you wish to continue?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d2 == DialogResult.Yes) { + if (d2 == DialogResult.Yes) + { File.Copy(RomInfo.arm9Path, RomInfo.arm9Path + backupSuffix, overwrite: true); - try { + try + { ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.branchString), data.branchOffset); //Write new branchOffset /* Write to overlayfile */ string overlayFilePath = OverlayUtils.GetPath(data.overlayNumber); - if (OverlayUtils.IsCompressed(data.overlayNumber)) { + if (OverlayUtils.IsCompressed(data.overlayNumber)) + { OverlayUtils.Decompress(data.overlayNumber); } @@ -407,7 +503,9 @@ namespace DSPRE { /*Write Expanded ARM9 File*/ DSUtils.WriteToFile(fullFilePath, data.subroutine, BDHCAMPatchData.BDHCamSubroutineOffset); - } catch { + } + catch + { MessageBox.Show("Operation failed. It is strongly advised that you restore the arm9 and overlay from their respective backups.", "Something went wrong", MessageBoxButtons.OK, MessageBoxIcon.Error); return; @@ -419,22 +517,29 @@ namespace DSPRE { BDHCamCB.Visible = true; MessageBox.Show("The BDHCAM patch has been applied.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); - } else { + } + else + { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); } } - private void overlay1uncomprButton_Click(object sender, EventArgs e) { - if (ConfigureOverlay1Uncompressed()) { + + private void overlay1uncomprButton_Click(object sender, EventArgs e) + { + if (ConfigureOverlay1Uncompressed()) + { DisableOverlay1patch("Already applied"); overlay1CB.Visible = true; } } - public static bool ConfigureOverlay1Uncompressed() { + public static bool ConfigureOverlay1Uncompressed() + { bool isCompressed = false; string stringDecompressOverlay = ""; - if (OverlayUtils.IsCompressed(1)) { + if (OverlayUtils.IsCompressed(1)) + { isCompressed = true; stringDecompressOverlay = "- Overlay 1 will be decompressed.\n\n"; } @@ -445,42 +550,50 @@ namespace DSPRE { "Do you wish to continue?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.Yes) { + if (d == DialogResult.Yes) + { OverlayUtils.OverlayTable.SetDefaultCompressed(1, false); - if (isCompressed) { + if (isCompressed) + { OverlayUtils.Decompress(1); } MessageBox.Show("Overlay1 is now configured as uncompressed.", "Operation successful", MessageBoxButtons.OK, MessageBoxIcon.Information); return true; - } else { + } + else + { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); return false; } } - private void ApplyItemStandardizeButton_Click(object sender, EventArgs e) { + private void ApplyItemStandardizeButton_Click(object sender, EventArgs e) + { DialogResult d = MessageBox.Show("This process will apply the following changes:\n\n" + "- Item scripts will be rearranged to follow the natural, ascending index order.\n\n" + "- Any unsaved change to the current Event File will be discarded.\n\n", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.Yes) { - + if (d == DialogResult.Yes) + { DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.scripts }); DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.eventFiles }); - if (PatchToolboxDialog.flag_standardizedItems) { + if (PatchToolboxDialog.flag_standardizedItems) + { AlreadyApplied(); - } else { - + } + else + { // Load item script file data ScriptFile itemScriptFile = new ScriptFile(RomInfo.itemScriptFileNumber); // Create map for: script no. -> vanilla item int[] vanillaItemsArray = new int[itemScriptFile.allScripts.Count - 1]; - for (int i = 0; i < itemScriptFile.allScripts.Count - 1; i++) { + for (int i = 0; i < itemScriptFile.allScripts.Count - 1; i++) + { vanillaItemsArray[i] = BitConverter.ToInt16(itemScriptFile.allScripts[i].commands[0].cmdParams[1], 0); }; @@ -488,18 +601,21 @@ namespace DSPRE { int cnt = Filesystem.GetEventFileCount(); (int itemScrMin, int itemScrMax) = (7000, 8000); - for (int i = 0; i < cnt; i++) { + for (int i = 0; i < cnt; i++) + { bool dirty = false; EventFile eventFile = new EventFile(i); - for (int j = 0; j < eventFile.overworlds.Count; j++) { + for (int j = 0; j < eventFile.overworlds.Count; j++) + { // If ow is marked as an item, or in the rare case it is not but script no. falls within item script range: bool isItem = eventFile.overworlds[j].type == (ushort)Overworld.OwType.ITEM || (eventFile.overworlds[j].scriptNumber >= itemScrMin && eventFile.overworlds[j].scriptNumber <= itemScrMax); - if (isItem) { + if (isItem) + { int itemScriptID = eventFile.overworlds[j].scriptNumber - (itemScrMin - 1); eventFile.overworlds[j].scriptNumber = (ushort)(itemScrMin + vanillaItemsArray[itemScriptID - 1]); dirty = true; @@ -507,23 +623,27 @@ namespace DSPRE { } // Save event file - if (dirty) { + if (dirty) + { eventFile.SaveToFileDefaultDir(i, showSuccessMessage: false); } }; //Distortion world - turnback cave Griseous Orb fix - if (gameFamily.Equals(GameFamilies.Plat)) { + if (gameFamily.Equals(GameFamilies.Plat)) + { string ow9path = OverlayUtils.GetPath(9); int ow9offs = 0x8E20 + 10; int itemScriptID; - using (DSUtils.EasyReader ewr = new DSUtils.EasyReader(ow9path, ow9offs)) { + using (DSUtils.EasyReader ewr = new DSUtils.EasyReader(ow9path, ow9offs)) + { itemScriptID = ewr.ReadUInt16() - (itemScrMin - 1); } - using (DSUtils.EasyWriter ewr = new DSUtils.EasyWriter(ow9path, ow9offs)) { + using (DSUtils.EasyWriter ewr = new DSUtils.EasyWriter(ow9path, ow9offs)) + { ewr.Write((ushort)(itemScrMin + vanillaItemsArray[itemScriptID - 1])); } } @@ -534,8 +654,8 @@ namespace DSPRE { itemScriptFile.allScripts.Clear(); - for (ushort i = 0; i < itemCount; i++) { - + for (ushort i = 0; i < itemCount; i++) + { List cmdList = new List { new ScriptCommand("SetVar 0x8008 " + i), new ScriptCommand("SetVar 0x8009 0x1"), @@ -556,11 +676,15 @@ namespace DSPRE { itemNumbersCB.Visible = true; PatchToolboxDialog.flag_standardizedItems = true; } - } else { + } + else + { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); } } - private void ApplyARM9ExpansionButton_Click(object sender, EventArgs e) { + + private void ApplyARM9ExpansionButton_Click(object sender, EventArgs e) + { ARM9PatchData data = new ARM9PatchData(); DialogResult d = MessageBox.Show("Confirming this process will apply the following changes:\n\n" + @@ -571,25 +695,29 @@ namespace DSPRE { "Do you wish to continue?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.Yes) { + if (d == DialogResult.Yes) + { File.Copy(RomInfo.arm9Path, RomInfo.arm9Path + backupSuffix, overwrite: true); - try { + try + { ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.branchString), data.branchOffset); //Write new branchOffset ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.initString), data.initOffset); //Write new initOffset string fullFilePath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + expandedARMfileID.ToString("D4"); File.Delete(fullFilePath); - using (BinaryWriter f = new BinaryWriter(File.Create(fullFilePath))) { + using (BinaryWriter f = new BinaryWriter(File.Create(fullFilePath))) + { for (int i = 0; i < 0x16000; i++) - f.Write((byte)0x00); // Write Expanded ARM9 File + f.Write((byte)0x00); // Write Expanded ARM9 File } DisableARM9patch("Already applied"); arm9patchCB.Visible = true; PatchToolboxDialog.flag_arm9Expanded = true; - switch (RomInfo.gameFamily) { + switch (RomInfo.gameFamily) + { case GameFamilies.Plat: case GameFamilies.HGSS: BDHCamPatchButton.Text = "Apply Patch"; @@ -601,28 +729,37 @@ namespace DSPRE { } MessageBox.Show("The ARM9's usable memory has been expanded.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); - } catch { + } + catch + { MessageBox.Show("Operation failed. It is strongly advised that you restore the arm9 backup (arm9.bin" + backupSuffix + ").", "Something went wrong", MessageBoxButtons.OK, MessageBoxIcon.Error); } - } else { + } + else + { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); } } - private void expandMatrixButton_Click(object sender, EventArgs e) { + + private void expandMatrixButton_Click(object sender, EventArgs e) + { string listOfChanges = ""; int languageOffset = 0; - if (RomInfo.romID == "IPKE" || RomInfo.romID == "IPGE" || RomInfo.romID == "IPGS") { + if (RomInfo.romID == "IPKE" || RomInfo.romID == "IPGE" || RomInfo.romID == "IPGS") + { languageOffset = +8; } - foreach (KeyValuePair kv in ToolboxDB.matrixExpansionDB) { + foreach (KeyValuePair kv in ToolboxDB.matrixExpansionDB) + { listOfChanges += " - Replace " + (kv.Value.Length / 3 + 1) + " bytes of data at arm9 offset"; if (kv.Key.Length > 1) listOfChanges += "s"; - for (int i = 0; i < kv.Key.Length; i++) { + for (int i = 0; i < kv.Key.Length; i++) + { listOfChanges += " 0x" + (kv.Key[i] - ARM9.address + languageOffset).ToString("X"); if (i < kv.Key.Length - 1) @@ -637,14 +774,20 @@ namespace DSPRE { "Do you wish to continue?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.Yes) { - try { - foreach (KeyValuePair kv in ToolboxDB.matrixExpansionDB) { - foreach (uint offset in kv.Key) { + if (d == DialogResult.Yes) + { + try + { + foreach (KeyValuePair kv in ToolboxDB.matrixExpansionDB) + { + foreach (uint offset in kv.Key) + { ARM9.WriteBytes(DSUtils.HexStringToByteArray(kv.Value), (uint)(offset - ARM9.address + languageOffset)); } } - } catch { + } + catch + { MessageBox.Show("Operation failed. It is strongly advised that you restore the arm9 backup (arm9.bin" + backupSuffix + ").", "Something went wrong", MessageBoxButtons.OK, MessageBoxIcon.Error); } @@ -652,18 +795,23 @@ namespace DSPRE { expandedMatrixCB.Visible = true; PatchToolboxDialog.flag_MatrixExpansionApplied = true; MessageBox.Show("Matrix 0 can now be freely expanded up to twice its size.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); - } else { + } + else + { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); } } - private void dynamicHeadersButton_Click(object sender, EventArgs e) { + + private void dynamicHeadersButton_Click(object sender, EventArgs e) + { DynamicHeadersPatchData data = new DynamicHeadersPatchData(); var headersDir = RomInfo.gameDirs[DirNames.dynamicHeaders]; bool specialCase = RomInfo.gameFamily == GameFamilies.HGSS && RomInfo.gameLanguage != GameLanguages.Japanese && RomInfo.gameLanguage != GameLanguages.Spanish; string specialCaseChanges = ""; - if (specialCase) { + if (specialCase) + { specialCaseChanges = "- Replace " + (data.specialCaseData1.Length / 3 + 1) + " bytes of data at arm9 offset 0x" + (data.specialCaseOffset1 + data.pointerDiff).ToString("X") + " with " + '\n' + data.specialCaseData1 + "\n\n" + "- Replace " + (data.specialCaseData2.Length / 3 + 1) + " bytes of data at arm9 offset 0x" + (data.specialCaseOffset2 + data.pointerDiff).ToString("X") + " with " + '\n' + data.specialCaseData2 + "\n\n" + "- Replace " + (data.specialCaseData3.Length / 3 + 1) + " bytes of data at arm9 offset 0x" + (data.specialCaseOffset3 + data.pointerDiff).ToString("X") + " with " + '\n' + data.specialCaseData3 + "\n\n"; @@ -681,10 +829,12 @@ namespace DSPRE { "Do you wish to continue?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.Yes) { + if (d == DialogResult.Yes) + { File.Copy(RomInfo.arm9Path, RomInfo.arm9Path + backupSuffix, overwrite: true); - try { + try + { /* Write main routine (HG USA): 00 B5 push (lr) @@ -701,7 +851,7 @@ namespace DSPRE { **BRANCHES FOR OTHER VERSIONS/LANGUAGES: - HG ESP (IPKS): + HG ESP (IPKS): CC F7 5C F9 bl 0x02007524 @Load_Memory DF F7 4D FC bl 0x0201AB0C @Free_Memory @@ -712,7 +862,7 @@ namespace DSPRE { Plat USA (CPUE): CC F7 48 FD bl 0x02006AC0 @Load_Memory DE F7 C7 F8 bl 0x020181C4 @Free_Memory - + Plat ESP (CPUS), ITA (CPUI), FRA (CPUF), GER (CPUD): CC F7 00 FD bl 0x02006AD4 @Load_Memory CC F7 74 FC bl 0x02018234 @Free_Memory @@ -725,7 +875,7 @@ namespace DSPRE { ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.initString), data.initOffset); /* - Neutralize instances of (HeaderID * 0x18) so the base offset which the data is read from is always 0x0: - + Replace this: 18 21 mov r1, #0x18 41 43 mul r1, r0 @@ -733,9 +883,9 @@ namespace DSPRE { with this: 19 00 lsl r1, r3, 0 C0 46 nop - + - Change pointers to header fields, from (ARM9_HEADER_TABLE_OFFSET + n) to simply (0 + n) - + * for ESP HG (IPKS): subtract 0x8 from every reference offset * for JAP HG (IPKJ) and SS (IPGJ): subtract 0x448 from every reference offset * for Plat ESP, ITA, FRA, GER, JAP: add 0xA4 to every reference offset @@ -743,14 +893,16 @@ namespace DSPRE { */ - foreach (Tuple reference in DynamicHeadersPatchData.dynamicHeadersPointersDB[RomInfo.gameFamily]) { + foreach (Tuple reference in DynamicHeadersPatchData.dynamicHeadersPointersDB[RomInfo.gameFamily]) + { ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.REFERENCE_STRING), (uint)(reference.Item1 + data.pointerDiff)); uint pointerValue = BitConverter.ToUInt32(ARM9.ReadBytes((uint)(reference.Item2 + data.pointerDiff), 4), 0) - RomInfo.headerTableOffset - ARM9.address; ARM9.WriteBytes(BitConverter.GetBytes(pointerValue), (uint)(reference.Item2 + data.pointerDiff)); } - if (specialCase) { - /* Special case: at 0x3B522 (non-JAP and non-Spanish HG offset) there is an instruction + if (specialCase) + { + /* Special case: at 0x3B522 (non-JAP and non-Spanish HG offset) there is an instruction between the (mov r1, #0x18) and (mul r1, r0) commands, so we must handle this separately */ ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.specialCaseData1), (uint)(data.specialCaseOffset1 + data.pointerDiff)); @@ -763,11 +915,12 @@ namespace DSPRE { Directory.CreateDirectory(headersDir.unpackedDir); /* Now move the headers data from arm9 to the new directory. Upon saving the ROM, - the data will be packed into a NARC and replace a/0/5/0 in HGSS or + the data will be packed into a NARC and replace a/0/5/0 in HGSS or debug/cb_edit/d_test.narc in Platinum */ int headerCount = RomInfo.GetHeaderCount(); - for (int i = 0; i < headerCount; i++) { + for (int i = 0; i < headerCount; i++) + { byte[] headerData = MapHeader.LoadFromARM9((ushort)i).ToByteArray(); DSUtils.WriteToFile(headersDir.unpackedDir + "\\" + i.ToString("D4"), headerData); } @@ -777,26 +930,35 @@ namespace DSPRE { PatchToolboxDialog.flag_DynamicHeadersPatchApplied = true; MessageBox.Show("The headers are now dynamically allocated in memory.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); - } catch { + } + catch + { MessageBox.Show("Operation failed. It is strongly advised that you restore the arm9 backup (arm9.bin" + backupSuffix + ").", "Something went wrong", MessageBoxButtons.OK, MessageBoxIcon.Error); } - } else { + } + else + { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); } } - private void disableDynamicTexturesButton_Click(object sender, EventArgs e) { + + private void disableDynamicTexturesButton_Click(object sender, EventArgs e) + { DialogResult d; d = MessageBox.Show("Applying this patch will set the Dynamic Textures field of all AreaData files to 0xFFFF.\n\n" + "Are you sure you want to proceed?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.Yes) { + if (d == DialogResult.Yes) + { DSUtils.TryUnpackNarcs(new List { DirNames.areaData }); string[] adFiles = Directory.GetFiles(gameDirs[DirNames.areaData].unpackedDir); - foreach (string s in adFiles) { - AreaData a = new AreaData(new FileStream(s, FileMode.Open)) { + foreach (string s in adFiles) + { + AreaData a = new AreaData(new FileStream(s, FileMode.Open)) + { dynamicTextureType = 0xFFFF }; a.SaveToFile(s, showSuccessMessage: false); @@ -805,12 +967,15 @@ namespace DSPRE { DisableKillTextureAnimationsPatch("Already applied"); disableTextureAnimationsCB.Visible = true; MessageBox.Show("Texture Animations have been disabled in every AreaData.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); - } else { + } + else + { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); } } - private void expandTrainerNamesButton_Click(object sender, EventArgs e) { + private void expandTrainerNamesButton_Click(object sender, EventArgs e) + { // Pearl USA ARM9 at 0x6AC32 // TODO: Verify // Pearl Spain ARM9 at 0x6AC8E // TODO: Verify // Diamond USA ARM9 at 0x6AC32 @@ -822,34 +987,43 @@ namespace DSPRE { // SoulSilver USA ARM9 at 0x7342E // SoulSilver Spain ARM9 at 0x7342E // TODO: Verify - DialogResult d = MessageBox.Show($"Applying this patch will set the Trainer Name max length to {PatchToolboxDialog.expandedTrainerNameLength-1} usable characters.\n" + + DialogResult d = MessageBox.Show($"Applying this patch will set the Trainer Name max length to {PatchToolboxDialog.expandedTrainerNameLength - 1} usable characters.\n" + "Are you sure you want to proceed?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.Yes) { - try { - using (ARM9.Writer wr = new ARM9.Writer(RomInfo.trainerNameLenOffset)) { + if (d == DialogResult.Yes) + { + try + { + using (ARM9.Writer wr = new ARM9.Writer(RomInfo.trainerNameLenOffset)) + { wr.Write((byte)PatchToolboxDialog.expandedTrainerNameLength); } PatchToolboxDialog.flag_TrainerNamesExpanded = true; DisableTrainerNameExpansionPatch("Already applied"); expandTrainerNamesCB.Visible = true; - RomInfo.SetTrainerNameMaxLen(); MessageBox.Show("Trainer Names have been extended.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); - } catch (IOException) { + } + catch (IOException) + { MessageBox.Show("ARM9 could not be written.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Error); } - } else { + } + else + { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); } } #region Mikelan's custom commands - private void applyCustomCommands(object sender, EventArgs e) { + + private void applyCustomCommands(object sender, EventArgs e) + { int expTableOffset = GetCommandTableOffset(); - if (expTableOffset < 0) { + if (expTableOffset < 0) + { DialogResult d; d = MessageBox.Show("Script command table has not been repointed.\n\n" + "Do you wish to repoint it to the expanded ARM9 file?\n\n" + @@ -857,32 +1031,41 @@ namespace DSPRE { "If you already have something there, you must cancel this window and move these things to a new location, or you can manually repoint the script command table to a different free location in the expanded ARM9 file", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.Yes) { + if (d == DialogResult.Yes) + { RepointCommandTable(); - } else { + } + else + { return; } } - if (ImportCustomCommand()) { + if (ImportCustomCommand()) + { MessageBox.Show("Script commands succesfully installed in the ROM", "Done", MessageBoxButtons.OK, MessageBoxIcon.Information); } - } - private int GetCommandTableOffset() { // Checks if command table is repointed IN THE EXPANDED ARM9 FILE, returns pointer inside this file + + private int GetCommandTableOffset() + { // Checks if command table is repointed IN THE EXPANDED ARM9 FILE, returns pointer inside this file ResourceManager customcmdDB = new ResourceManager("DSPRE.Resources.ROMToolboxDB.CustomScrCmdDB", Assembly.GetExecutingAssembly()); int pointerOffset = int.Parse(customcmdDB.GetString("pointerOffset" + "_" + RomInfo.gameVersion + "_" + RomInfo.gameLanguage)); - using (ARM9.Reader r = new ARM9.Reader(pointerOffset)) { + using (ARM9.Reader r = new ARM9.Reader(pointerOffset)) + { uint cmdTable = r.ReadUInt32(); uint offset = cmdTable - synthOverlayLoadAddress; - if ((offset >= 0) && (offset <= 0x12B00)) { + if ((offset >= 0) && (offset <= 0x12B00)) + { return (int)offset; // Table position inside the expanded arm9 file } } return -1; // No table in expanded arm9 file } - private void RepointCommandTable() { + + private void RepointCommandTable() + { string expandedPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + "\\0000"; ResourceManager customcmdDB = new ResourceManager("DSPRE.Resources.ROMToolboxDB.CustomScrCmdDB", Assembly.GetExecutingAssembly()); @@ -891,14 +1074,16 @@ namespace DSPRE { arm9FileStream.CopyTo(arm9Stream); byte[] cmdTbl = arm9Stream.ToArray(); - using (BinaryWriter expArmWriter = new BinaryWriter(new FileStream(expandedPath, FileMode.Open))) { + using (BinaryWriter expArmWriter = new BinaryWriter(new FileStream(expandedPath, FileMode.Open))) + { expArmWriter.BaseStream.Position = 0x200; // Command table default offset expArmWriter.Write(cmdTbl, int.Parse(customcmdDB.GetString("originalTableOffset" + "_" + RomInfo.gameVersion + "_" + RomInfo.gameLanguage)), 4 * 0x355); } arm9FileStream.Close(); - using (ARM9.Writer wr = new ARM9.Writer()) { // Change both the pointer and the limit + using (ARM9.Writer wr = new ARM9.Writer()) + { // Change both the pointer and the limit wr.BaseStream.Position = int.Parse(customcmdDB.GetString("pointerOffset" + "_" + RomInfo.gameVersion + "_" + RomInfo.gameLanguage)); wr.Write((uint)0x023C8200); @@ -906,13 +1091,16 @@ namespace DSPRE { wr.Write((uint)0x053C); } } - private bool ImportCustomCommand() { + + private bool ImportCustomCommand() + { string expandedPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + "\\0000"; int appliedPatches = 0; OpenFileDialog of = new OpenFileDialog(); of.Filter = "Custom Script Command File (*.scrcmd)|*.scrcmd"; - if (of.ShowDialog(this) != DialogResult.OK) { + if (of.ShowDialog(this) != DialogResult.OK) + { return false; } @@ -921,12 +1109,16 @@ namespace DSPRE { expandedFileStream.CopyTo(expandedStream); expandedFileStream.Close(); - using (DSUtils.EasyWriter expandedWriter = new DSUtils.EasyWriter(expandedPath, fmode: FileMode.Open)) { - using (BinaryReader expandedReader = new BinaryReader(expandedStream)) { - try { + using (DSUtils.EasyWriter expandedWriter = new DSUtils.EasyWriter(expandedPath, fmode: FileMode.Open)) + { + using (BinaryReader expandedReader = new BinaryReader(expandedStream)) + { + try + { System.Xml.Linq.XDocument xmldoc = System.Xml.Linq.XDocument.Load(new FileStream(of.FileName, FileMode.Open)); - foreach (var node in xmldoc.Root.Elements("scriptcommand")) { + foreach (var node in xmldoc.Root.Elements("scriptcommand")) + { ushort commandID = ushort.Parse(node.Attribute("ID").Value, System.Globalization.NumberStyles.HexNumber); string targetROM = node.Element("ROM").Value; string targetLang = node.Element("lang").Value; @@ -936,14 +1128,17 @@ namespace DSPRE { int asmOffset = Int32.Parse(node.Element("asmoffset").Value, System.Globalization.NumberStyles.HexNumber); string asmCode = node.Element("asmcode").Value.Replace("\n", "").Replace("\t", "").Replace(" ", ""); - if (RomInfo.gameVersion.ToString().Equals(targetROM) && RomInfo.gameLanguage.Equals(targetLang)) { + if (RomInfo.gameVersion.ToString().Equals(targetROM) && RomInfo.gameLanguage.Equals(targetLang)) + { expandedReader.BaseStream.Position = 0x200 + commandID * 4; - if (expandedReader.ReadUInt32() != 0) { + if (expandedReader.ReadUInt32() != 0) + { DialogResult d; d = MessageBox.Show("Script command " + commandID.ToString("X4") + " is already used.\n\n" + "Do you really want to overwrite it?", "Confirm to proceed", MessageBoxButtons.YesNo, MessageBoxIcon.Warning); - if (d == DialogResult.No) { + if (d == DialogResult.No) + { continue; } } @@ -958,8 +1153,9 @@ namespace DSPRE { appliedPatches++; } } - - } catch { + } + catch + { MessageBox.Show("Selected command installation file is corrupted.\n\n" + "Please, download it again or contact its creator.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); @@ -968,7 +1164,8 @@ namespace DSPRE { } } - if (appliedPatches == 0) { + if (appliedPatches == 0) + { MessageBox.Show("No command could be installed from this file.\n\n" + "Make sure the command installation file supports your current ROM.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); return false; @@ -976,16 +1173,18 @@ namespace DSPRE { return true; } - #endregion - #endregion + #endregion Mikelan's custom commands + + #endregion Button Actions #region Error Messsages - private void AlreadyApplied() { + + private void AlreadyApplied() + { MessageBox.Show("This patch has already been applied.", "Can't reapply patch", MessageBoxButtons.OK, MessageBoxIcon.Information); } - #endregion - + #endregion Error Messsages } } \ No newline at end of file diff --git a/DS_Map/PatchToolboxDialog.resx b/DS_Map/PatchToolboxDialog.resx index f2f9529..c55fda7 100644 --- a/DS_Map/PatchToolboxDialog.resx +++ b/DS_Map/PatchToolboxDialog.resx @@ -127,7 +127,7 @@ This patch is necessary to accomplish most ASM edits. iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vgAADr4B6kKxwAAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT + vQAADr0BR/uQrQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT bPLz+IQY464yh1s0Ne9LXK3rERAGkPt/hLDwPAt0WiTg7MtLYhgL3xaQZzUVsC1AD0Y7baK6AKzBaD8z Ya0APVi4NR/xFCZ481LLhbWHF4ToxecZ2UAmD/Y4kQ+Ag3hrB7VdSjZ6dEJpvENrBrAEguIBIb4J0FIw upmAncykgSX9hgfNYHyTqg2kaiXFN87xo5nSrQ+kXic1kuVygUkD6d58CYZ1nPWgzlMB3EvmcL1i+AEb @@ -137,7 +137,7 @@ This patch is necessary to accomplish most ASM edits. iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vgAADr4B6kKxwAAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT + vQAADr0BR/uQrQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT bPLz+IQY464yh1s0Ne9LXK3rERAGkPt/hLDwPAt0WiTg7MtLYhgL3xaQZzUVsC1AD0Y7baK6AKzBaD8z Ya0APVi4NR/xFCZ481LLhbWHF4ToxecZ2UAmD/Y4kQ+Ag3hrB7VdSjZ6dEJpvENrBrAEguIBIb4J0FIw upmAncykgSX9hgfNYHyTqg2kaiXFN87xo5nSrQ+kXic1kuVygUkD6d58CYZ1nPWgzlMB3EvmcL1i+AEb @@ -147,7 +147,7 @@ This patch is necessary to accomplish most ASM edits. iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vgAADr4B6kKxwAAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT + vQAADr0BR/uQrQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT bPLz+IQY464yh1s0Ne9LXK3rERAGkPt/hLDwPAt0WiTg7MtLYhgL3xaQZzUVsC1AD0Y7baK6AKzBaD8z Ya0APVi4NR/xFCZ481LLhbWHF4ToxecZ2UAmD/Y4kQ+Ag3hrB7VdSjZ6dEJpvENrBrAEguIBIb4J0FIw upmAncykgSX9hgfNYHyTqg2kaiXFN87xo5nSrQ+kXic1kuVygUkD6d58CYZ1nPWgzlMB3EvmcL1i+AEb @@ -157,7 +157,7 @@ This patch is necessary to accomplish most ASM edits. iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vgAADr4B6kKxwAAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT + vQAADr0BR/uQrQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT bPLz+IQY464yh1s0Ne9LXK3rERAGkPt/hLDwPAt0WiTg7MtLYhgL3xaQZzUVsC1AD0Y7baK6AKzBaD8z Ya0APVi4NR/xFCZ481LLhbWHF4ToxecZ2UAmD/Y4kQ+Ag3hrB7VdSjZ6dEJpvENrBrAEguIBIb4J0FIw upmAncykgSX9hgfNYHyTqg2kaiXFN87xo5nSrQ+kXic1kuVygUkD6d58CYZ1nPWgzlMB3EvmcL1i+AEb @@ -167,7 +167,7 @@ This patch is necessary to accomplish most ASM edits. iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vgAADr4B6kKxwAAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT + vQAADr0BR/uQrQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT bPLz+IQY464yh1s0Ne9LXK3rERAGkPt/hLDwPAt0WiTg7MtLYhgL3xaQZzUVsC1AD0Y7baK6AKzBaD8z Ya0APVi4NR/xFCZ481LLhbWHF4ToxecZ2UAmD/Y4kQ+Ag3hrB7VdSjZ6dEJpvENrBrAEguIBIb4J0FIw upmAncykgSX9hgfNYHyTqg2kaiXFN87xo5nSrQ+kXic1kuVygUkD6d58CYZ1nPWgzlMB3EvmcL1i+AEb @@ -177,7 +177,7 @@ This patch is necessary to accomplish most ASM edits. iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vgAADr4B6kKxwAAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT + vQAADr0BR/uQrQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT bPLz+IQY464yh1s0Ne9LXK3rERAGkPt/hLDwPAt0WiTg7MtLYhgL3xaQZzUVsC1AD0Y7baK6AKzBaD8z Ya0APVi4NR/xFCZ481LLhbWHF4ToxecZ2UAmD/Y4kQ+Ag3hrB7VdSjZ6dEJpvENrBrAEguIBIb4J0FIw upmAncykgSX9hgfNYHyTqg2kaiXFN87xo5nSrQ+kXic1kuVygUkD6d58CYZ1nPWgzlMB3EvmcL1i+AEb @@ -187,7 +187,7 @@ This patch is necessary to accomplish most ASM edits. iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vgAADr4B6kKxwAAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT + vQAADr0BR/uQrQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT bPLz+IQY464yh1s0Ne9LXK3rERAGkPt/hLDwPAt0WiTg7MtLYhgL3xaQZzUVsC1AD0Y7baK6AKzBaD8z Ya0APVi4NR/xFCZ481LLhbWHF4ToxecZ2UAmD/Y4kQ+Ag3hrB7VdSjZ6dEJpvENrBrAEguIBIb4J0FIw upmAncykgSX9hgfNYHyTqg2kaiXFN87xo5nSrQ+kXic1kuVygUkD6d58CYZ1nPWgzlMB3EvmcL1i+AEb @@ -197,7 +197,7 @@ This patch is necessary to accomplish most ASM edits. iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vgAADr4B6kKxwAAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT + vQAADr0BR/uQrQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT bPLz+IQY464yh1s0Ne9LXK3rERAGkPt/hLDwPAt0WiTg7MtLYhgL3xaQZzUVsC1AD0Y7baK6AKzBaD8z Ya0APVi4NR/xFCZ481LLhbWHF4ToxecZ2UAmD/Y4kQ+Ag3hrB7VdSjZ6dEJpvENrBrAEguIBIb4J0FIw upmAncykgSX9hgfNYHyTqg2kaiXFN87xo5nSrQ+kXic1kuVygUkD6d58CYZ1nPWgzlMB3EvmcL1i+AEb @@ -207,7 +207,7 @@ This patch is necessary to accomplish most ASM edits. iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vQAADr0BR/uQrQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT + vAAADrwBlbxySQAAAOFJREFUOE+tj8ERgkAMRddx0Js90ItFeJS7B3vxTDO04FiCdaxJ2ISwmywjcPiT bPLz+IQY464yh1s0Ne9LXK3rERAGkPt/hLDwPAt0WiTg7MtLYhgL3xaQZzUVsC1AD0Y7baK6AKzBaD8z Ya0APVi4NR/xFCZ481LLhbWHF4ToxecZ2UAmD/Y4kQ+Ag3hrB7VdSjZ6dEJpvENrBrAEguIBIb4J0FIw upmAncykgSX9hgfNYHyTqg2kaiXFN87xo5nSrQ+kXic1kuVygUkD6d58CYZ1nPWgzlMB3EvmcL1i+AEb diff --git a/DS_Map/ROMFiles/TextArchive.cs b/DS_Map/ROMFiles/TextArchive.cs index 4c150ac..d58b3df 100644 --- a/DS_Map/ROMFiles/TextArchive.cs +++ b/DS_Map/ROMFiles/TextArchive.cs @@ -7,196 +7,96 @@ using System.Reflection; using System.Windows.Forms; using DSPRE.Resources; using static DSPRE.RomInfo; +using DSPRE.MessageEnc; -namespace DSPRE.ROMFiles { +namespace DSPRE.ROMFiles +{ /// /// Class to store message data from DS Pokémon games /// - public class TextArchive : RomFile { + public class TextArchive : RomFile + { #region Fields (2) + public List messages; public int initialKey; - #endregion Fields + + #endregion Fields (2) #region Constructors (1) - public TextArchive(FileStream messageStream, List msg, bool discardLines = false) { - Dictionary GetCharDictionary = TextDatabase.readTextDictionary; - BinaryReader readText = new BinaryReader(messageStream); - int stringCount; - try { - stringCount = readText.ReadUInt16(); - } catch (EndOfStreamException) { - MessageBox.Show("Error loading text file.\n", "Unexpected EOF", MessageBoxButtons.OK, MessageBoxIcon.Error); - readText.Close(); - return; - } - - if (msg == null) { - messages = new List(); - } else { - messages = msg; - } - - initialKey = readText.ReadUInt16(); - - if (!discardLines) { - int key1 = (initialKey * 0x2FD) & 0xFFFF; - bool specialCharON = false; - int[] currentOffset = new int[stringCount]; - int[] currentSize = new int[stringCount]; - bool compressed = new bool(); - - for (int i = 0; i < stringCount; i++) { // Reads and stores string offsets and sizes - int key2 = (key1 * (i + 1) & 0xFFFF); - int realKey = key2 | (key2 << 16); - currentOffset[i] = ((int)readText.ReadUInt32()) ^ realKey; - currentSize[i] = ((int)readText.ReadUInt32()) ^ realKey; - } - - for (int i = 0; i < stringCount; i++) { // Adds new string - key1 = (0x91BD3 * (i + 1)) & 0xFFFF; - readText.BaseStream.Position = currentOffset[i]; - StringBuilder pokemonText = new StringBuilder(""); - - for (int j = 0; j < currentSize[i]; j++) // Adds new characters to string - { - int car = (readText.ReadUInt16()) ^ key1; - - switch (car) { // Special characters - case 0xE000: - pokemonText.Append(@"\n"); - break; - case 0x25BC: - pokemonText.Append(@"\r"); - break; - case 0x25BD: - pokemonText.Append(@"\f"); - break; - case 0xF100: - compressed = true; - break; - case 0xFFFE: - pokemonText.Append(@"\v"); - specialCharON = true; - break; - case 0xFFFF: - pokemonText.Append(""); - break; - default: - if (specialCharON) { - pokemonText.Append(car.ToString("X4")); - specialCharON = false; - } else if (compressed) { - #region Compressed String - int shift = 0; - int trans = 0; - string uncomp = ""; - while (true) { - int tmp = car >> shift; - int tmp1 = tmp; - if (shift >= 0xF) { - shift -= 0xF; - if (shift > 0) { - tmp1 = (trans | ((car << (9 - shift)) & 0x1FF)); - if ((tmp1 & 0xFF) == 0xFF) { - break; - } - if (tmp1 != 0x0 && tmp1 != 0x1) { - string character = ""; - if (!GetCharDictionary.TryGetValue(tmp1, out character)) { - pokemonText.Append(@"\x" + tmp1.ToString("X4")); - } else { - pokemonText.Append(character); - } - } - } - } else { - tmp1 = ((car >> shift) & 0x1FF); - if ((tmp1 & 0xFF) == 0xFF) { - break; - } - if (tmp1 != 0x0 && tmp1 != 0x1) { - string character = ""; - if (!GetCharDictionary.TryGetValue(tmp1, out character)) - pokemonText.Append(@"\x" + tmp1.ToString("X4")); - else { - pokemonText.Append(character); - } - } - shift += 9; - if (shift < 0xF) { - trans = ((car >> shift) & 0x1FF); - shift += 9; - } - key1 += 0x493D; - key1 &= 0xFFFF; - car = Convert.ToUInt16(readText.ReadUInt16() ^ key1); - j++; - } - } - #endregion - pokemonText.Append(uncomp); - } else { - if (GetCharDictionary.TryGetValue(car, out string character)) { - pokemonText.Append(character); - } else { - pokemonText.Append(@"\x" + car.ToString("X4")); - } - } - break; - } - key1 += 0x493D; - key1 &= 0xFFFF; - } - messages.Add(pokemonText.ToString()); - } - } - - readText.Dispose(); + public TextArchive(FileStream messageStream, List msg, bool discardLines = false) + { + messages = msg ?? EncryptText.ReadMessageArchive(messageStream, discardLines); } - public TextArchive(int ID, List msg = null, bool discardLines = false) : this(new FileStream(RomInfo.gameDirs[DirNames.textArchives].unpackedDir + "\\" + ID.ToString("D4"), FileMode.Open), msg, discardLines) { + + public TextArchive(int ID, List msg = null, bool discardLines = false) : this(new FileStream($"{gameDirs[DirNames.textArchives].unpackedDir}\\{ID:D4}", FileMode.Open), msg, discardLines) + { } - #endregion + + #endregion Constructors (1) #region Methods (2) - public int[] EncodeString(string currentMessage, int stringIndex, int stringSize) { // Converts string to hex characters + + public int[] EncodeString(string currentMessage, int stringIndex, int stringSize) + { // Converts string to hex characters ResourceManager GetByte = new ResourceManager("DSPRE.Resources.WriteText", Assembly.GetExecutingAssembly()); int[] pokemonMessage = new int[stringSize - 1]; var charArray = currentMessage.ToCharArray(); int count = 0; - try { - for (int i = 0; i < currentMessage.Length; i++) { - if (charArray[i] == '\\') { - if (charArray[i + 1] == 'r') { + try + { + for (int i = 0; i < currentMessage.Length; i++) + { + if (charArray[i] == '\\') + { + if (charArray[i + 1] == 'r') + { pokemonMessage[count] = 0x25BC; i++; - } else { - if (charArray[i + 1] == 'n') { + } + else + { + if (charArray[i + 1] == 'n') + { pokemonMessage[count] = 0xE000; i++; - } else { - if (charArray[i + 1] == 'f') { + } + else + { + if (charArray[i + 1] == 'f') + { pokemonMessage[count] = 0x25BD; i++; - } else { - if (charArray[i + 1] == 'v') { + } + else + { + if (charArray[i + 1] == 'v') + { pokemonMessage[count] = 0xFFFE; count++; string characterID = ((char)charArray[i + 2]).ToString() + ((char)charArray[i + 3]).ToString() + ((char)charArray[i + 4]).ToString() + ((char)charArray[i + 5]).ToString(); pokemonMessage[count] = (int)Convert.ToUInt32(characterID, 16); i += 5; - } else { + } + else + { //This looks like it can be optimized - if (charArray[i + 1] == 'x' && charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '0') { + if (charArray[i + 1] == 'x' && charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '0') + { pokemonMessage[count] = 0x0000; i += 5; - } else { - if (charArray[i + 1] == 'x' && charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '1') { + } + else + { + if (charArray[i + 1] == 'x' && charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '1') + { pokemonMessage[count] = 0x0001; i += 5; - } else { + } + else + { string characterID = ((char)charArray[i + 2]).ToString() + ((char)charArray[i + 3]).ToString() + ((char)charArray[i + 4]).ToString() + ((char)charArray[i + 5]).ToString(); pokemonMessage[count] = (int)Convert.ToUInt32(characterID, 16); i += 5; @@ -206,56 +106,87 @@ namespace DSPRE.ROMFiles { } } } - } else { - if (charArray[i] == '[') { - if (charArray[i + 1] == 'P') { + } + else + { + if (charArray[i] == '[') + { + if (charArray[i + 1] == 'P') + { pokemonMessage[count] = 0x01E0; i += 3; } - if (charArray[i + 1] == 'M') { + if (charArray[i + 1] == 'M') + { pokemonMessage[count] = 0x01E1; i += 3; } - } else { + } + else + { pokemonMessage[count] = (int)Convert.ToUInt32(GetByte.GetString(((int)charArray[i]).ToString()), 16); } } count++; } - } catch (FormatException) { + } + catch (FormatException) + { MessageBox.Show("Format exception. Assembled so far: " + Environment.NewLine + pokemonMessage); } return pokemonMessage; } - public int GetStringLength(string currentMessage) { // Calculates string length + + public int GetStringLength(string currentMessage) + { // Calculates string length int count = 0; var charArray = currentMessage.ToCharArray(); - for (int i = 0; i < currentMessage.Length; i++) { - if (charArray[i] == '\\') { - if (charArray[i + 1] == 'r') { + for (int i = 0; i < currentMessage.Length; i++) + { + if (charArray[i] == '\\') + { + if (charArray[i + 1] == 'r') + { count++; i++; - } else { - if (charArray[i + 1] == 'n') { + } + else + { + if (charArray[i + 1] == 'n') + { count++; i++; - } else { - if (charArray[i + 1] == 'f') { + } + else + { + if (charArray[i + 1] == 'f') + { count++; i++; - } else { - if (charArray[i + 1] == 'v') { + } + else + { + if (charArray[i + 1] == 'v') + { count += 2; i += 5; - } else { - if (charArray[i + 1] == 'x' && charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '0') { + } + else + { + if (charArray[i + 1] == 'x' && charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '0') + { count++; i += 5; - } else { - if (charArray[i + 1] == 'x' && charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '1') { + } + else + { + if (charArray[i + 1] == 'x' && charArray[i + 2] == '0' && charArray[i + 3] == '0' && charArray[i + 4] == '0' && charArray[i + 5] == '1') + { count++; i += 5; - } else { + } + else + { count++; i += 5; } @@ -264,17 +195,24 @@ namespace DSPRE.ROMFiles { } } } - } else { - if (charArray[i] == '[') { - if (charArray[i + 1] == 'P') { + } + else + { + if (charArray[i] == '[') + { + if (charArray[i + 1] == 'P') + { count++; i += 3; } - if (charArray[i + 1] == 'M') { + if (charArray[i + 1] == 'M') + { count++; i += 3; } - } else { + } + else + { count++; } } @@ -282,9 +220,12 @@ namespace DSPRE.ROMFiles { count++; return count; } - private byte[] ToByteArray(List msgSource) { + + private byte[] ToByteArray(List msgSource) + { MemoryStream newData = new MemoryStream(); - using (BinaryWriter writer = new BinaryWriter(newData)) { + using (BinaryWriter writer = new BinaryWriter(newData)) + { writer.Write((ushort)msgSource.Count); writer.Write((ushort)initialKey); @@ -294,7 +235,8 @@ namespace DSPRE.ROMFiles { int offset = 0x4 + (msgSource.Count * 8); int[] stringSize = new int[msgSource.Count]; - for (int i = 0; i < msgSource.Count; i++) { // Reads and stores string offsets and sizes + for (int i = 0; i < msgSource.Count; i++) + { // Reads and stores string offsets and sizes key2 = (key * (i + 1) & 0xFFFF); realKey = key2 | (key2 << 16); writer.Write(offset ^ realKey); @@ -304,11 +246,13 @@ namespace DSPRE.ROMFiles { offset += length * 2; } - for (int i = 0; i < msgSource.Count; i++) { // Encodes strings and writes them to file + for (int i = 0; i < msgSource.Count; i++) + { // Encodes strings and writes them to file key = (0x91BD3 * (i + 1)) & 0xFFFF; int[] currentString = EncodeString(msgSource[i], i, stringSize[i]); - for (int j = 0; j < stringSize[i] - 1; j++) { + for (int j = 0; j < stringSize[i] - 1; j++) + { writer.Write((ushort)(currentString[j] ^ key)); key += 0x493D; key &= 0xFFFF; @@ -319,19 +263,30 @@ namespace DSPRE.ROMFiles { return newData.ToArray(); } - public override string ToString() { + public override string ToString() + { return string.Join(Environment.NewLine, messages); } - public override byte[] ToByteArray() { + public override byte[] ToByteArray() + { return this.ToByteArray(messages); } - public void SaveToFileDefaultDir(int IDtoReplace, bool showSuccessMessage = true) { - SaveToFileDefaultDir(DirNames.textArchives, IDtoReplace, showSuccessMessage); + + public void SaveToFileDefaultDir(int IDtoReplace, bool showSuccessMessage = true) + { + bool success = EncryptText.WriteMessageArchive(IDtoReplace, messages, IDtoReplace == trainerNamesMessageNumber); + if (showSuccessMessage && success) + { + MessageBox.Show("Saved successfully!", "", MessageBoxButtons.OK, MessageBoxIcon.Information); + } } - public void SaveToFileExplorePath(string suggestedFileName, bool showSuccessMessage = true) { + + public void SaveToFileExplorePath(string suggestedFileName, bool showSuccessMessage = true) + { SaveToFileExplorePath("Gen IV Text Archive", "msg", suggestedFileName, showSuccessMessage); } - #endregion + + #endregion Methods (2) } } \ No newline at end of file diff --git a/DS_Map/ROMFiles/TrainerFile.cs b/DS_Map/ROMFiles/TrainerFile.cs index 1aba11d..ff733cd 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 defaultNameLen = 7; //Does not include special \0 end character! + public const int defaultNameLen = 10; //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/RomInfo.cs b/DS_Map/RomInfo.cs index f508269..612d67d 100644 --- a/DS_Map/RomInfo.cs +++ b/DS_Map/RomInfo.cs @@ -10,15 +10,16 @@ using static DSPRE.RomInfo; using System.Windows.Shapes; using Path = System.IO.Path; -namespace DSPRE { - +namespace DSPRE +{ /// /// Class to store ROM data from GEN IV Pokémon games /// - public class RomInfo { + public class RomInfo + { public static string folderSuffix = "_DSPRE_contents"; - const string dataFolderName = @"data"; + private const string dataFolderName = @"data"; public static string romID { get; private set; } public static string fileName { get; private set; } @@ -37,7 +38,6 @@ namespace DSPRE { public static GameVersions gameVersion { get; private set; } public static GameFamilies gameFamily { get; private set; } - public static uint synthOverlayLoadAddress = 0x023C8000; public static uint arm9spawnOffset { get; private set; } @@ -60,7 +60,6 @@ namespace DSPRE { public static uint vsPokemonEntryTableOffsetToSizeLimiter { get; internal set; } public static uint effectsComboTableOffsetToSizeLimiter { get; internal set; } - public static uint OWTableOffset { get; internal set; } public static string OWtablePath { get; private set; } @@ -78,7 +77,7 @@ namespace DSPRE { public static int moveNamesTextNumbers { 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 int trainerNameMaxLen => SetTrainerNameMaxLen(); public static int trainerFunnyScriptNumber { get; private set; } public static string internalNamesLocation { get; private set; } @@ -92,7 +91,6 @@ namespace DSPRE { public static uint[] overworldTableKeys { get; private set; } public static Dictionary ow3DSpriteDict { get; private set; } - public static Dictionary ScriptCommandNamesDict { get; private set; } public static Dictionary ScriptCommandNamesReverseDict { get; private set; } @@ -104,13 +102,16 @@ namespace DSPRE { public static Dictionary ScriptComparisonOperatorsDict { get; private set; } public static Dictionary ScriptComparisonOperatorsReverseDict { get; private set; } - public enum GameVersions : byte { + public enum GameVersions : byte + { Diamond, Pearl, Platinum, HeartGold, SoulSilver, Black, White, Black2, White2 } - public enum GameFamilies : byte { + + public enum GameFamilies : byte + { NULL, DP, Plat, @@ -118,7 +119,9 @@ namespace DSPRE { BW, BW2 } - public enum GameLanguages : byte { + + public enum GameLanguages : byte + { English, Japanese, @@ -127,7 +130,9 @@ namespace DSPRE { French, German } - public enum DirNames : byte { + + public enum DirNames : byte + { personalPokeData, synthOverlay, @@ -163,12 +168,15 @@ namespace DSPRE { learnsets, evolutions }; + public static Dictionary gameDirs { get; private set; } - #region Constructors (1) - public RomInfo(string id, string romName, bool useSuffix = true) { - if (!useSuffix) { + + public RomInfo(string id, string romName, bool useSuffix = true) + { + if (!useSuffix) + { folderSuffix = ""; } @@ -186,9 +194,12 @@ namespace DSPRE { unpackedPath = Path.Combine(workDir, @"unpacked"); internalNamesPath = Path.Combine(workDir, $@"{dataFolderName}\fielddata\maptable\mapname.bin"); - try { + try + { gameVersion = PokeDatabase.System.versionsDict[id]; - } catch (KeyNotFoundException) { + } + catch (KeyNotFoundException) + { MessageBox.Show("The ROM you attempted to load is not supported.\nYou can only load Gen IV Pokémon ROMS, for now.", "Unsupported ROM", MessageBoxButtons.OK, MessageBoxIcon.Error); return; @@ -227,22 +238,28 @@ namespace DSPRE { ScriptActionNamesReverseDict = ScriptActionNamesDict.Reverse(); ScriptComparisonOperatorsReverseDict = ScriptComparisonOperatorsDict.Reverse(); } - #endregion + + #endregion Constructors (1) #region Methods (22) - public static Dictionary BuildCommandNamesDatabase(GameFamilies gameFam) { + + public static Dictionary BuildCommandNamesDatabase(GameFamilies gameFam) + { Dictionary commonDictionaryNames; Dictionary specificDictionaryNames; - switch (gameFam) { + switch (gameFam) + { case GameFamilies.DP: commonDictionaryNames = ScriptDatabase.DPPtScrCmdNames; specificDictionaryNames = ScriptDatabase.DPScrCmdNames; break; + case GameFamilies.Plat: commonDictionaryNames = ScriptDatabase.DPPtScrCmdNames; specificDictionaryNames = ScriptDatabase.PlatScrCmdNames; break; + default: commonDictionaryNames = ScriptDatabase.HGSSScrCmdNames; #if true @@ -254,19 +271,24 @@ namespace DSPRE { } return commonDictionaryNames.Concat(specificDictionaryNames).ToLookup(x => x.Key, x => x.Value).ToDictionary(x => x.Key, g => g.First()); } - public static Dictionary BuildCommandParametersDatabase(GameFamilies gameFam) { + + public static Dictionary BuildCommandParametersDatabase(GameFamilies gameFam) + { Dictionary commonDictionaryParams; Dictionary specificDictionaryParams; - switch (gameFam) { + switch (gameFam) + { case GameFamilies.DP: commonDictionaryParams = ScriptDatabase.DPPtScrCmdParameters; specificDictionaryParams = ScriptDatabase.DPScrCmdParameters; break; + case GameFamilies.Plat: commonDictionaryParams = ScriptDatabase.DPPtScrCmdParameters; specificDictionaryParams = ScriptDatabase.PlatScrCmdParameters; break; + default: commonDictionaryParams = ScriptDatabase.HGSSScrCmdParameters; #if true @@ -278,11 +300,15 @@ namespace DSPRE { } return commonDictionaryParams.Concat(specificDictionaryParams).ToLookup(x => x.Key, x => x.Value).ToDictionary(x => x.Key, g => g.First()); } - public static Dictionary BuildActionNamesDatabase(GameFamilies gameFam) { - switch (gameFam) { + + public static Dictionary BuildActionNamesDatabase(GameFamilies gameFam) + { + switch (gameFam) + { case GameFamilies.DP: case GameFamilies.Plat: return ScriptDatabase.movementsDictIDName; + default: #if false var commonDictionaryParams = ScriptDatabase.movementsDictIDName; @@ -293,20 +319,27 @@ namespace DSPRE { #endif } } - public static Dictionary BuildComparisonOperatorsDatabase(GameFamilies gameFam) { - switch (gameFam) { + + public static Dictionary BuildComparisonOperatorsDatabase(GameFamilies gameFam) + { + switch (gameFam) + { case GameFamilies.DP: case GameFamilies.Plat: case GameFamilies.HGSS: return ScriptDatabase.comparisonOperatorsDict; + default: var commonDict = ScriptDatabase.comparisonOperatorsDict; var appendixDict = ScriptDatabase.comparisonOperatorsGenVappendix; return commonDict.Concat(appendixDict).ToLookup(x => x.Key, x => x.Value).ToDictionary(x => x.Key, g => g.First()); } } - public static void Set3DOverworldsDict() { - ow3DSpriteDict = new Dictionary() { + + public static void Set3DOverworldsDict() + { + ow3DSpriteDict = new Dictionary() + { [91] = "brown_sign", [92] = "red_sign", [93] = "gray_sign", @@ -317,69 +350,92 @@ namespace DSPRE { //[174] = "dppt_suitcase", }; } - public static void SetHeaderTableOffset() { - switch (gameFamily) { + + public static void SetHeaderTableOffset() + { + switch (gameFamily) + { case GameFamilies.DP: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: headerTableOffset = 0xEEDBC; break; + case GameLanguages.Spanish: headerTableOffset = 0xEEE08; break; + case GameLanguages.Italian: headerTableOffset = 0xEED70; break; + case GameLanguages.French: headerTableOffset = 0xEEDFC; break; + case GameLanguages.German: headerTableOffset = 0xEEDCC; break; + case GameLanguages.Japanese: headerTableOffset = gameVersion == GameVersions.Diamond ? (uint)0xF0D68 : 0xF0D6C; break; } break; + case GameFamilies.Plat: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: headerTableOffset = 0xE601C; break; + case GameLanguages.Spanish: headerTableOffset = 0xE60B0; break; + case GameLanguages.Italian: headerTableOffset = 0xE6038; break; + case GameLanguages.French: headerTableOffset = 0xE60A4; break; + case GameLanguages.German: headerTableOffset = 0xE6074; break; + case GameLanguages.Japanese: headerTableOffset = 0xE56F0; break; } break; + case GameFamilies.HGSS: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: headerTableOffset = 0xF6BE0; break; + case GameLanguages.Spanish: headerTableOffset = gameVersion == GameVersions.HeartGold ? 0xF6BC8 : (uint)0xF6BD0; break; + case GameLanguages.Italian: headerTableOffset = 0xF6B58; break; + case GameLanguages.French: headerTableOffset = 0xF6BC4; break; + case GameLanguages.German: headerTableOffset = 0xF6B94; break; + case GameLanguages.Japanese: headerTableOffset = 0xF6390; break; @@ -387,75 +443,98 @@ namespace DSPRE { break; } } - public static void SetupSpawnSettings() { - switch (gameFamily) { + + public static void SetupSpawnSettings() + { + switch (gameFamily) + { case GameFamilies.DP: initialMoneyOverlayNumber = 52; initialMoneyOverlayOffset = 0x1E4; - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: arm9spawnOffset = 0xF2B9C; break; + case GameLanguages.Spanish: arm9spawnOffset = 0xF2BE8; break; + case GameLanguages.Italian: arm9spawnOffset = 0xF2B50; break; + case GameLanguages.French: arm9spawnOffset = 0xF2BDC; break; + case GameLanguages.German: arm9spawnOffset = 0xF2BAC; break; + case GameLanguages.Japanese: arm9spawnOffset = 0xF4B48; break; } break; + case GameFamilies.Plat: initialMoneyOverlayNumber = 57; initialMoneyOverlayOffset = 0x1EC; - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: arm9spawnOffset = 0xEA12C; break; + case GameLanguages.Spanish: arm9spawnOffset = 0xEA1C0; break; + case GameLanguages.Italian: arm9spawnOffset = 0xEA148; break; + case GameLanguages.French: arm9spawnOffset = 0xEA1B4; break; + case GameLanguages.German: arm9spawnOffset = 0xEA184; break; + case GameLanguages.Japanese: arm9spawnOffset = 0xE9800; break; } break; + case GameFamilies.HGSS: initialMoneyOverlayNumber = 36; initialMoneyOverlayOffset = 0x2FC; - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: arm9spawnOffset = 0xFA17C; break; + case GameLanguages.Spanish: arm9spawnOffset = gameVersion == GameVersions.HeartGold ? 0xFA164 : (uint)0xFA16C; break; + case GameLanguages.Italian: arm9spawnOffset = 0xFA0F4; break; + case GameLanguages.French: arm9spawnOffset = 0xFA160; break; + case GameLanguages.German: arm9spawnOffset = 0xFA130; break; + case GameLanguages.Japanese: arm9spawnOffset = 0xF992C; break; @@ -463,22 +542,28 @@ namespace DSPRE { break; } } - public static void PrepareCameraData() { - switch (gameFamily) { + + public static void PrepareCameraData() + { + switch (gameFamily) + { case GameFamilies.DP: cameraTblOverlayNumber = 5; cameraTblOffsetsToRAMaddress = gameLanguage.Equals(GameLanguages.Japanese) ? (new uint[] { 0x4C50 }) : (new uint[] { 0x4908 }); cameraSize = 24; break; + case GameFamilies.Plat: cameraTblOverlayNumber = 5; cameraTblOffsetsToRAMaddress = new uint[] { 0x4E24 }; cameraSize = 24; break; + case GameFamilies.HGSS: cameraTblOverlayNumber = 1; cameraSize = 36; - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: case GameLanguages.Spanish: case GameLanguages.French: @@ -486,6 +571,7 @@ namespace DSPRE { case GameLanguages.Italian: cameraTblOffsetsToRAMaddress = new uint[] { 0x532C, 0x547C }; break; + case GameLanguages.Japanese: cameraTblOffsetsToRAMaddress = new uint[] { 0x5324, 0x5474 }; break; @@ -493,47 +579,63 @@ namespace DSPRE { break; } } - public static void SetOWtable() { - switch (gameFamily) { + + public static void SetOWtable() + { + switch (gameFamily) + { case GameFamilies.DP: OWtablePath = OverlayUtils.GetPath(5); - switch (gameLanguage) { // Go to the beginning of the overworld table + switch (gameLanguage) + { // Go to the beginning of the overworld table case GameLanguages.English: OWTableOffset = 0x22BCC; break; + case GameLanguages.Japanese: OWTableOffset = 0x23BB8; break; + default: OWTableOffset = 0x22B84; break; } break; + case GameFamilies.Plat: OWtablePath = OverlayUtils.GetPath(5); - switch (gameLanguage) { // Go to the beginning of the overworld table + switch (gameLanguage) + { // Go to the beginning of the overworld table case GameLanguages.Italian: OWTableOffset = 0x2BC44; break; + case GameLanguages.French: case GameLanguages.Spanish: OWTableOffset = 0x2BC3C; break; + case GameLanguages.German: OWTableOffset = 0x2BC50; break; + case GameLanguages.Japanese: OWTableOffset = 0x2BA24; break; + default: OWTableOffset = 0x2BC34; break; } break; + case GameFamilies.HGSS: - if (OverlayUtils.OverlayTable.IsDefaultCompressed(1)) { - if (OverlayUtils.IsCompressed(1)) { - if (OverlayUtils.Decompress(1) < 0) { + if (OverlayUtils.OverlayTable.IsDefaultCompressed(1)) + { + if (OverlayUtils.IsCompressed(1)) + { + if (OverlayUtils.Decompress(1) < 0) + { MessageBox.Show("Overlay 1 couldn't be decompressed.\nOverworld sprites in the Event Editor will be " + "displayed incorrectly or not displayed at all.", "Decompression error", MessageBoxButtons.OK, MessageBoxIcon.Error); } @@ -544,43 +646,55 @@ namespace DSPRE { uint ov1Address = OverlayUtils.OverlayTable.GetRAMAddress(1); int ramAddrOfPointer; - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.Italian: ramAddrOfPointer = 0x021F929C; break; + case GameLanguages.French: case GameLanguages.Spanish: ramAddrOfPointer = 0x021F931C; break; + case GameLanguages.German: ramAddrOfPointer = 0x021F92DC; break; + case GameLanguages.Japanese: ramAddrOfPointer = 0x021F86C4; break; + default: ramAddrOfPointer = 0x021F92FC; break; } - using (DSUtils.EasyReader bReader = new DSUtils.EasyReader(ov1Path, ramAddrOfPointer - ov1Address)) { // read the pointer at the specified ram address and adjust accordingly below + using (DSUtils.EasyReader bReader = new DSUtils.EasyReader(ov1Path, ramAddrOfPointer - ov1Address)) + { // read the pointer at the specified ram address and adjust accordingly below uint ramAddressOfTable = bReader.ReadUInt32(); - if ((ramAddressOfTable >> 0x18) != 0x02) { + if ((ramAddressOfTable >> 0x18) != 0x02) + { MessageBox.Show("Something went wrong reading the Overworld configuration table.\nOverworld sprites in the Event Editor will be " + "displayed incorrectly or not displayed at all.", "Decompression error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } string ov131path = OverlayUtils.GetPath(131); - if (File.Exists(ov131path)) { + if (File.Exists(ov131path)) + { // if HGE field extension overlay exists OWTableOffset = ramAddressOfTable - OverlayUtils.OverlayTable.GetRAMAddress(131); OWtablePath = ov131path; - } else if (ramAddressOfTable >= RomInfo.synthOverlayLoadAddress) { + } + else if (ramAddressOfTable >= RomInfo.synthOverlayLoadAddress) + { // if the pointer shows the table was moved to the synthetic overlay OWTableOffset = ramAddressOfTable - RomInfo.synthOverlayLoadAddress; OWtablePath = gameDirs[DirNames.synthOverlay].unpackedDir + "\\" + PatchToolboxDialog.expandedARMfileID.ToString("D4"); - } else { + } + else + { OWTableOffset = ramAddressOfTable - ov1Address; OWtablePath = ov1Path; } @@ -588,19 +702,25 @@ namespace DSPRE { break; } } - public static void SetConditionalMusicTableOffsetToRAMAddress() { - switch (gameFamily) { + + public static void SetConditionalMusicTableOffsetToRAMAddress() + { + switch (gameFamily) + { case GameFamilies.HGSS: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.Spanish: conditionalMusicTableOffsetToRAMAddress = gameVersion == GameVersions.HeartGold ? (uint)0x667D0 : 0x667D8; break; + case GameLanguages.English: case GameLanguages.Italian: case GameLanguages.French: case GameLanguages.German: conditionalMusicTableOffsetToRAMAddress = 0x667D8; break; + case GameLanguages.Japanese: conditionalMusicTableOffsetToRAMAddress = 0x66238; break; @@ -608,15 +728,20 @@ namespace DSPRE { break; } } - public static void SetBattleEffectsData() { - switch (gameFamily) { + + public static void SetBattleEffectsData() + { + switch (gameFamily) + { case GameFamilies.HGSS: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.Spanish: vsPokemonEntryTableOffsetToRAMAddress = gameVersion == GameVersions.HeartGold ? (uint)0x518CC : 0x518D4; vsTrainerEntryTableOffsetToRAMAddress = gameVersion == GameVersions.HeartGold ? (uint)0x51888 : 0x51890; effectsComboTableOffsetToRAMAddress = gameVersion == GameVersions.HeartGold ? (uint)0x517C0 : 0x517C8; break; + case GameLanguages.English: case GameLanguages.Italian: case GameLanguages.French: @@ -625,6 +750,7 @@ namespace DSPRE { vsTrainerEntryTableOffsetToRAMAddress = 0x51890; effectsComboTableOffsetToRAMAddress = 0x517C8; break; + case GameLanguages.Japanese: vsPokemonEntryTableOffsetToRAMAddress = 0x5136C; vsTrainerEntryTableOffsetToRAMAddress = 0x51328; @@ -637,16 +763,19 @@ namespace DSPRE { break; case GameFamilies.Plat: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: effectsComboTableOffsetToRAMAddress = 0x51BE0; break; + case GameLanguages.Italian: case GameLanguages.French: case GameLanguages.Spanish: case GameLanguages.German: effectsComboTableOffsetToRAMAddress = 0x51C84; break; + case GameLanguages.Japanese: effectsComboTableOffsetToRAMAddress = 0x514C0; break; @@ -654,19 +783,25 @@ namespace DSPRE { break; } } - public static void SetEncounterMusicTableOffsetToRAMAddress() { - switch (gameFamily) { + + public static void SetEncounterMusicTableOffsetToRAMAddress() + { + switch (gameFamily) + { case GameFamilies.HGSS: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.Spanish: encounterMusicTableOffsetToRAMAddress = gameVersion == GameVersions.HeartGold ? (uint)0x550D8 : 0x550E0; break; + case GameLanguages.English: case GameLanguages.Italian: case GameLanguages.French: case GameLanguages.German: encounterMusicTableOffsetToRAMAddress = 0x550E0; break; + case GameLanguages.Japanese: encounterMusicTableOffsetToRAMAddress = 0x54B44; break; @@ -674,16 +809,19 @@ namespace DSPRE { break; case GameFamilies.Plat: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: encounterMusicTableOffsetToRAMAddress = 0x5563C; break; + case GameLanguages.Italian: case GameLanguages.French: case GameLanguages.Spanish: case GameLanguages.German: encounterMusicTableOffsetToRAMAddress = 0x556E0; break; + case GameLanguages.Japanese: encounterMusicTableOffsetToRAMAddress = 0x54F04; break; @@ -691,16 +829,19 @@ namespace DSPRE { break; case GameFamilies.DP: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: encounterMusicTableOffsetToRAMAddress = 0x4AD3C; break; + case GameLanguages.Italian: case GameLanguages.French: case GameLanguages.Spanish: case GameLanguages.German: encounterMusicTableOffsetToRAMAddress = 0x4ADAC; break; + case GameLanguages.Japanese: encounterMusicTableOffsetToRAMAddress = 0x4D9AC; break; @@ -708,64 +849,86 @@ namespace DSPRE { break; } } - public static void SetMonIconsPalTableAddress() { - switch (RomInfo.gameFamily) { + + public static void SetMonIconsPalTableAddress() + { + switch (RomInfo.gameFamily) + { case GameFamilies.DP: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x6B838, 4), 0); break; + case GameLanguages.Italian: monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x6B874, 4), 0); break; + case GameLanguages.German: case GameLanguages.French: case GameLanguages.Spanish: monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x6B894, 4), 0); break; + case GameLanguages.Japanese: monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x6FDEC, 4), 0); break; } break; + case GameFamilies.Plat: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x79F80, 4), 0); break; + case GameLanguages.Italian: case GameLanguages.German: case GameLanguages.French: case GameLanguages.Spanish: monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x7A020, 4), 0); break; + case GameLanguages.Japanese: monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x79858, 4), 0); break; } break; + case GameFamilies.HGSS: default: - switch (gameLanguage) { + switch (gameLanguage) + { case GameLanguages.English: case GameLanguages.Italian: monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74408, 4), 0); break; + case GameLanguages.German: - if (gameVersion == GameVersions.HeartGold) { + if (gameVersion == GameVersions.HeartGold) + { monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74408, 4), 0); - } else { + } + else + { monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74400, 4), 0); } break; + case GameLanguages.French: case GameLanguages.Spanish: - if (gameVersion == GameVersions.HeartGold) { + if (gameVersion == GameVersions.HeartGold) + { monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74400, 4), 0); - } else { + } + else + { monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74408, 4), 0); } break; + case GameLanguages.Japanese: monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x73EA0, 4), 0); break; @@ -774,132 +937,178 @@ namespace DSPRE { } } - private static void SetItemScriptFileNumber() { - switch (gameFamily) { + private static void SetItemScriptFileNumber() + { + switch (gameFamily) + { case GameFamilies.DP: itemScriptFileNumber = 370; break; + case GameFamilies.Plat: itemScriptFileNumber = 404; break; + default: itemScriptFileNumber = 141; break; } } - private static void SetNullEncounterID() { - switch (gameFamily) { + + private static void SetNullEncounterID() + { + switch (gameFamily) + { case GameFamilies.DP: case GameFamilies.Plat: nullEncounterID = ushort.MaxValue; break; + case GameFamilies.HGSS: nullEncounterID = Byte.MaxValue; break; } } - private static void SetAbilityNamesTextNumber() { - switch (gameFamily) { + private static void SetAbilityNamesTextNumber() + { + switch (gameFamily) + { case GameFamilies.DP: abilityNamesTextNumber = 552; break; + case GameFamilies.Plat: abilityNamesTextNumber = 610; break; + case GameFamilies.HGSS: abilityNamesTextNumber = 720; break; + default: break; } } - private static void SetAttackNamesTextNumber() { - switch (gameFamily) { + private static void SetAttackNamesTextNumber() + { + switch (gameFamily) + { case GameFamilies.DP: attackNamesTextNumber = 588; break; + case GameFamilies.Plat: attackNamesTextNumber = 647; break; + default: attackNamesTextNumber = gameLanguage == GameLanguages.Japanese ? 739 : 750; break; } } - private static void SetItemNamesTextNumber() { - switch (gameFamily) { + + private static void SetItemNamesTextNumber() + { + switch (gameFamily) + { case GameFamilies.DP: itemNamesTextNumber = 344; break; + case GameFamilies.Plat: itemNamesTextNumber = 392; break; + default: itemNamesTextNumber = gameLanguage == GameLanguages.Japanese ? 219 : 222; break; } } - private static void SetLocationNamesTextNumber() { - switch (gameFamily) { + + private static void SetLocationNamesTextNumber() + { + switch (gameFamily) + { case GameFamilies.DP: locationNamesTextNumber = 382; break; + case GameFamilies.Plat: locationNamesTextNumber = 433; break; + default: locationNamesTextNumber = gameLanguage == GameLanguages.Japanese ? 272 : 279; break; } } - private static void SetPokemonNamesTextNumber() { - switch (gameFamily) { + + private static void SetPokemonNamesTextNumber() + { + switch (gameFamily) + { case GameFamilies.DP: pokemonNamesTextNumbers = new int[2] { 362, 363 }; break; + case GameFamilies.Plat: pokemonNamesTextNumbers = new int[7] { 412, 413, 712, 713, 714, 715, 716 }; //413? break; + case GameFamilies.HGSS: pokemonNamesTextNumbers = gameLanguage.Equals(GameLanguages.Japanese) ? new int[1] { 232 } : new int[7] { 237, 238, 817, 818, 819, 820, 821 }; //238? break; } } - private static void SetTrainerNamesMessageNumber() { - switch (gameFamily) { + + private static void SetTrainerNamesMessageNumber() + { + switch (gameFamily) + { case GameFamilies.DP: trainerNamesMessageNumber = 559; - if (gameLanguage.Equals(GameLanguages.Japanese)) { + if (gameLanguage.Equals(GameLanguages.Japanese)) + { trainerNamesMessageNumber -= 9; } break; + case GameFamilies.Plat: trainerNamesMessageNumber = 618; break; + default: trainerNamesMessageNumber = 729; - if (gameLanguage == GameLanguages.Japanese) { + if (gameLanguage == GameLanguages.Japanese) + { trainerNamesMessageNumber -= 10; } break; } } - private static void SetTrainerClassMessageNumber() { - switch (gameFamily) { + + private static void SetTrainerClassMessageNumber() + { + switch (gameFamily) + { case GameFamilies.DP: trainerClassMessageNumber = 560; - if (gameLanguage.Equals(GameLanguages.Japanese)) { + if (gameLanguage.Equals(GameLanguages.Japanese)) + { trainerClassMessageNumber -= 9; } break; + case GameFamilies.Plat: trainerClassMessageNumber = 619; break; + default: trainerClassMessageNumber = 730; - if (gameLanguage.Equals(GameLanguages.Japanese)) { + if (gameLanguage.Equals(GameLanguages.Japanese)) + { trainerClassMessageNumber -= 10; } break; @@ -936,16 +1145,21 @@ namespace DSPRE { } } - private static void SetTrainerNameLenOffset() { - switch (RomInfo.gameFamily) { + private static void SetTrainerNameLenOffset() + { + switch (RomInfo.gameFamily) + { case GameFamilies.DP: - switch (RomInfo.gameLanguage) { + switch (RomInfo.gameLanguage) + { case GameLanguages.English: trainerNameLenOffset = 0x6AC32; break; + case GameLanguages.Italian: trainerNameLenOffset = 0x6AC6E; break; + case GameLanguages.Spanish: case GameLanguages.German: case GameLanguages.French: @@ -960,16 +1174,19 @@ namespace DSPRE { break; case GameFamilies.Plat: - switch (RomInfo.gameLanguage) { + switch (RomInfo.gameLanguage) + { case GameLanguages.English: trainerNameLenOffset = 0x791DE; break; + case GameLanguages.Spanish: case GameLanguages.Italian: case GameLanguages.German: case GameLanguages.French: trainerNameLenOffset = 0x7927E; break; + case GameLanguages.Japanese: trainerNameLenOffset = 0x78AB6; break; @@ -981,21 +1198,28 @@ namespace DSPRE { break; case GameFamilies.HGSS: - if (RomInfo.gameLanguage.Equals(GameLanguages.Japanese)) { + if (RomInfo.gameLanguage.Equals(GameLanguages.Japanese)) + { //Jap HGSS trainerNameLenOffset = 0x7342E; - } else if(gameVersion.Equals(GameVersions.SoulSilver)){ + } + else if (gameVersion.Equals(GameVersions.SoulSilver)) + { //All SS languages except Jap trainerNameLenOffset = 0x72EC2; - } else { + } + else + { //All HG languages except Jap - switch (RomInfo.gameLanguage) { + switch (RomInfo.gameLanguage) + { case GameLanguages.English: case GameLanguages.Italian: case GameLanguages.German: case GameLanguages.French: trainerNameLenOffset = 0x7342E; break; + case GameLanguages.Spanish: trainerNameLenOffset = 0x73426; break; @@ -1005,53 +1229,84 @@ namespace DSPRE { } } - public static int SetTrainerNameMaxLen() { - if(trainerNameLenOffset < 0) { - trainerNameMaxLen = TrainerFile.defaultNameLen; - } else { - using (ARM9.Reader ar = new ARM9.Reader(trainerNameLenOffset)) { - trainerNameMaxLen = ar.ReadByte(); + public static int SetTrainerNameMaxLen() + { + int maxLength = TrainerFile.defaultNameLen; + if (trainerNameLenOffset > 0) + { + using (ARM9.Reader ar = new ARM9.Reader(trainerNameLenOffset)) + { + maxLength = ar.ReadByte(); } + maxLength += ((maxLength - 4) / 2); } - return trainerNameMaxLen; + return maxLength; } 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(internalNamesPath).Length / internalNameLength; + public static List GetLocationNames() => new TextArchive(locationNamesTextNumber).messages; + public static string[] GetSimpleTrainerNames() => new TextArchive(trainerNamesMessageNumber).messages.ToArray(); + public static string[] GetTrainerClassNames() => new TextArchive(trainerClassMessageNumber).messages.ToArray(); + public static string[] GetItemNames() => new TextArchive(itemNamesTextNumber).messages.ToArray(); - public static string[] GetItemNames(int startIndex = 0, int? count = null) { + + public static string[] GetItemNames(int startIndex = 0, int? count = null) + { TextArchive itemNames = new TextArchive(itemNamesTextNumber); return itemNames.messages.GetRange(startIndex, count == null ? itemNames.messages.Count - 1 : (int)count).ToArray(); } + public static string[] GetPokemonNames() => new TextArchive(pokemonNamesTextNumbers[0]).messages.ToArray(); + public static string[] GetAbilityNames() => new TextArchive(abilityNamesTextNumber).messages.ToArray(); + public static string[] GetAttackNames() => new TextArchive(attackNamesTextNumber).messages.ToArray(); + public static int GetLearnsetFilesCount() => Directory.GetFiles(gameDirs[DirNames.learnsets].unpackedDir).Length; + public static int GetPersonalFilesCount() => Directory.GetFiles(gameDirs[DirNames.personalPokeData].unpackedDir).Length; + public static string[] GetEvolutionFilesList() => Directory.GetFiles(gameDirs[DirNames.evolutions].unpackedDir); + public static int GetEvolutionFilesCount() => GetEvolutionFilesList().Length; public static string[] GetBattleEffectSequenceFiles() => Directory.GetFiles(gameDirs[DirNames.moveData].unpackedDir); public static int GetBattleEffectSequenceFilesCount() => GetBattleEffectSequenceFiles().Length; public int GetAreaDataCount() => Directory.GetFiles(gameDirs[DirNames.areaData].unpackedDir).Length; + public int GetMapTexturesCount() => Directory.GetFiles(gameDirs[DirNames.mapTextures].unpackedDir).Length; + public int GetBuildingTexturesCount() => Directory.GetFiles(gameDirs[DirNames.buildingTextures].unpackedDir).Length; + public int GetMatrixCount() => Directory.GetFiles(gameDirs[DirNames.matrices].unpackedDir).Length; + public int GetTextArchivesCount() => Directory.GetFiles(gameDirs[DirNames.textArchives].unpackedDir).Length; + public int GetMapCount() => Directory.GetFiles(gameDirs[DirNames.maps].unpackedDir).Length; + public int GetEventCount() => Directory.GetFiles(gameDirs[DirNames.eventFiles].unpackedDir).Length; + public int GetScriptCount() => Directory.GetFiles(gameDirs[DirNames.scripts].unpackedDir).Length; + public int GetBuildingCount(bool interior) => Directory.GetFiles(GetBuildingModelsDirPath(interior)).Length; + public static int GetEventFileCount() => Directory.GetFiles(RomInfo.gameDirs[DirNames.eventFiles].unpackedDir).Length; - #endregion + + #endregion Methods (22) #region System Methods - private void LoadGameLanguage() { - switch (romID) { + + private void LoadGameLanguage() + { + switch (romID) + { case "ADAE": case "APAE": case "CPUE": @@ -1098,31 +1353,41 @@ namespace DSPRE { break; } } - private void LoadGameFamily() { - switch (gameVersion) { + + private void LoadGameFamily() + { + switch (gameVersion) + { case GameVersions.Diamond: case GameVersions.Pearl: gameFamily = GameFamilies.DP; break; + case GameVersions.Platinum: gameFamily = GameFamilies.Plat; break; + case GameVersions.HeartGold: case GameVersions.SoulSilver: gameFamily = GameFamilies.HGSS; break; } } - private void SetNarcDirs() { + + private void SetNarcDirs() + { Dictionary packedDirsDict = null; - switch (gameFamily) { + switch (gameFamily) + { case GameFamilies.DP: string suffix = ""; - if (!gameLanguage.Equals(GameLanguages.Japanese)) { + if (!gameLanguage.Equals(GameLanguages.Japanese)) + { suffix = "_release"; } - packedDirsDict = new Dictionary() { + packedDirsDict = new Dictionary() + { [DirNames.synthOverlay] = @"data\data\weather_sys.narc", [DirNames.textArchives] = @"data\msgdata\msg.narc", @@ -1153,17 +1418,20 @@ namespace DSPRE { //Personal Data archive is different for Pearl string personal = @"data\poketool\personal"; - if (gameVersion == GameVersions.Pearl) { + if (gameVersion == GameVersions.Pearl) + { personal += ("_" + gameVersion.ToString().ToLower()); } personal += @"\personal.narc"; packedDirsDict[DirNames.personalPokeData] = personal; break; + case GameFamilies.Plat: suffix = gameVersion.ToString().Substring(0, 2).ToLower(); - packedDirsDict = new Dictionary() { + packedDirsDict = new Dictionary() + { [DirNames.personalPokeData] = @"data\poketool\personal\pl_personal.narc", [DirNames.synthOverlay] = @"data\data\weather_sys.narc", [DirNames.dynamicHeaders] = @"data\debug\cb_edit\d_test.narc", @@ -1196,8 +1464,10 @@ namespace DSPRE { [DirNames.evolutions] = @"data\poketool\personal\evo.narc", }; break; + case GameFamilies.HGSS: - packedDirsDict = new Dictionary() { + packedDirsDict = new Dictionary() + { [DirNames.personalPokeData] = @"data\a\0\0\2", [DirNames.synthOverlay] = @"data\a\0\2\8", [DirNames.dynamicHeaders] = @"data\a\0\5\0", @@ -1233,51 +1503,64 @@ namespace DSPRE { [DirNames.headbutt] = @"data\a\2\5\2", //both versions use the same folder with different data }; - //Encounter archive is different for SS + //Encounter archive is different for SS packedDirsDict[DirNames.encounters] = gameVersion == GameVersions.HeartGold ? @"data\a\0\3\7" : @"data\a\1\3\6"; break; } gameDirs = new Dictionary(); - foreach (KeyValuePair kvp in packedDirsDict) { + foreach (KeyValuePair kvp in packedDirsDict) + { gameDirs.Add(kvp.Key, (workDir + kvp.Value, workDir + @"unpacked" + '\\' + kvp.Key.ToString())); } } - public void ResetMapCellsColorDictionary() { - switch (gameFamily) { + + public void ResetMapCellsColorDictionary() + { + switch (gameFamily) + { case GameFamilies.DP: case GameFamilies.Plat: MapCellsColorDictionary = PokeDatabase.System.MatrixCellColors.DPPtmatrixColorsDict; break; + case GameFamilies.HGSS: MapCellsColorDictionary = PokeDatabase.System.MatrixCellColors.HGSSmatrixColorsDict; break; } } - public static void ReadOWTable() { + + public static void ReadOWTable() + { OverworldTable = new SortedDictionary(); - switch (gameFamily) { + switch (gameFamily) + { case GameFamilies.DP: case GameFamilies.Plat: - using (BinaryReader idReader = new BinaryReader(new FileStream(OWtablePath, FileMode.Open))) { + using (BinaryReader idReader = new BinaryReader(new FileStream(OWtablePath, FileMode.Open))) + { idReader.BaseStream.Position = OWTableOffset; uint entryID = idReader.ReadUInt32(); idReader.BaseStream.Position -= 4; - while ((entryID = idReader.ReadUInt32()) != 0xFFFF) { + while ((entryID = idReader.ReadUInt32()) != 0xFFFF) + { uint spriteID = idReader.ReadUInt32(); (uint spriteID, ushort properties) tup = (spriteID, 0x0000); OverworldTable.Add(entryID, tup); } } break; + case GameFamilies.HGSS: - using (BinaryReader idReader = new BinaryReader(new FileStream(OWtablePath, FileMode.Open))) { + using (BinaryReader idReader = new BinaryReader(new FileStream(OWtablePath, FileMode.Open))) + { idReader.BaseStream.Position = OWTableOffset; ushort entryID = idReader.ReadUInt16(); idReader.BaseStream.Position -= 2; - while ((entryID = idReader.ReadUInt16()) != 0xFFFF) { + while ((entryID = idReader.ReadUInt16()) != 0xFFFF) + { uint spriteID = idReader.ReadUInt16(); ushort properties = idReader.ReadUInt16(); (uint spriteID, ushort properties) tup = (spriteID, properties); @@ -1286,11 +1569,13 @@ namespace DSPRE { } break; } - foreach (uint k in ow3DSpriteDict.Keys) { + foreach (uint k in ow3DSpriteDict.Keys) + { OverworldTable.Add(k, (0x3D3D, 0x3D3D)); //ADD 3D overworld data (spriteID and properties are dummy values) } overworldTableKeys = OverworldTable.Keys.ToArray(); } - #endregion + + #endregion System Methods } } \ No newline at end of file From ef25d51dd67a2cc7a96f9d49f91d6072e376717d Mon Sep 17 00:00:00 2001 From: AdAstra-LD <76622070+AdAstra-LD@users.noreply.github.com> Date: Wed, 26 Jun 2024 01:04:27 +0200 Subject: [PATCH 2/4] Fixed EncryptText.cs --- DS_Map/MessageEnc/EncryptText.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/DS_Map/MessageEnc/EncryptText.cs b/DS_Map/MessageEnc/EncryptText.cs index 54db1c1..07887cc 100644 --- a/DS_Map/MessageEnc/EncryptText.cs +++ b/DS_Map/MessageEnc/EncryptText.cs @@ -65,13 +65,10 @@ namespace DSPRE.MessageEnc { decode.Append(textChar.ToString("X4")); hasSpecialCharacter = false; - } - if (isCompressed) - { + } else if (isCompressed) { int shift = 0; int trans = 0; - while (true) - { + while (true){ int compChar = textChar >> shift; if (shift >= 0xF) { From 7816e973276dd50d4ac647b57a6efb312bddc1de Mon Sep 17 00:00:00 2001 From: AdAstra-LD <76622070+AdAstra-LD@users.noreply.github.com> Date: Wed, 26 Jun 2024 01:21:19 +0200 Subject: [PATCH 3/4] Fixed some Plat param numbers --- DS_Map/Resources/ScriptDatabase.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DS_Map/Resources/ScriptDatabase.cs b/DS_Map/Resources/ScriptDatabase.cs index 8ec2719..4a53f46 100644 --- a/DS_Map/Resources/ScriptDatabase.cs +++ b/DS_Map/Resources/ScriptDatabase.cs @@ -1024,14 +1024,14 @@ namespace DSPRE.Resources { [0x0154] = new byte[1] { 0 }, [0x0155] = new byte[] { 2, 2 }, [0x0156] = new byte[] { 2 }, - [0x0157] = new byte[1] { 0 }, + [0x0157] = new byte[] { 2 }, [0x0158] = new byte[1] { 0 }, - [0x0159] = new byte[1] { 0 }, + [0x0159] = new byte[] { 2 }, [0x015A] = new byte[1] { 0 }, [0x015B] = new byte[] { 2, 2 }, [0x015C] = new byte[] { 2 }, [0x015D] = new byte[] { 2 }, - [0x015E] = new byte[1] { 0 }, + [0x015E] = new byte[] { 2 }, [0x015F] = new byte[1] { 0 }, [0x0160] = new byte[] { 2 }, [0x0161] = new byte[1] { 0 }, @@ -1060,12 +1060,12 @@ namespace DSPRE.Resources { [0x0178] = new byte[] { 1 }, [0x0179] = new byte[] { 2 }, [0x017A] = new byte[] { 2, 2 }, - [0x017B] = new byte[] { 2 }, + [0x017B] = new byte[] { 1, 2, 2 }, [0x017C] = new byte[] { 1, 2 }, [0x017D] = new byte[] { 2 }, [0x017E] = new byte[] { 2 }, [0x017F] = new byte[] { 2 }, - [0x0180] = new byte[] { 1 }, + [0x0180] = new byte[] { 2 }, [0x0181] = new byte[] { 2 }, [0x0182] = new byte[] { 2 }, [0x0183] = new byte[] { 2 }, From 003ead7bdd1fbf0513d32bbc5d26bc92dbe27036 Mon Sep 17 00:00:00 2001 From: AdAstra-LD <76622070+AdAstra-LD@users.noreply.github.com> Date: Mon, 1 Jul 2024 23:54:39 +0200 Subject: [PATCH 4/4] Update ScriptDatabase.cs --- DS_Map/Resources/ScriptDatabase.cs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/DS_Map/Resources/ScriptDatabase.cs b/DS_Map/Resources/ScriptDatabase.cs index 4a53f46..3ecd165 100644 --- a/DS_Map/Resources/ScriptDatabase.cs +++ b/DS_Map/Resources/ScriptDatabase.cs @@ -678,7 +678,9 @@ namespace DSPRE.Resources { [0x02C1] = "ShowSaveBox", [0x02C2] = "HideSaveBox", - [0x02C3] = "ScopeMode" + [0x02C3] = "ScopeMode", + + [0x0333] = "SetFieldVolume", }; public static Dictionary DPPtScrCmdParameters = new Dictionary() { [0x0000] = new byte[1] { 0 }, @@ -1494,8 +1496,11 @@ namespace DSPRE.Resources { [0x0302] = "CheckUsedRotomAppliances", + [0x0314] = "GetBattleOutcome", [0x0315] = "GetCurrentWeather", + [0x0317] = "GetPlayerPositionFull", + [0x0318] = "WildBattleFateful", [0x0319] = "GiratinaBattle", [0x031A] = "RegisterSeenPokemon", @@ -1635,7 +1640,7 @@ namespace DSPRE.Resources { [0x0331] = new byte[1] { 0 }, [0x0332] = new byte[1] { 0 }, [0x0333] = new byte[] { 2 }, - [0x0334] = new byte[1] { 0 }, + [0x0334] = new byte[] { 2, 2 }, [0x0335] = new byte[] { 2, 4 }, [0x0336] = new byte[] { 2 }, @@ -2088,7 +2093,14 @@ namespace DSPRE.Resources { [0x0290] = "CheckHeadbuttCompatibility", + [0x02AB] = "GetBattleOutcome", [0x02AC] = "GetCurrentWeather", + [0x02AD] = "GetPlayerPositionFull", + [0x02AE] = "WildBattleFateful", + [0x02AF] = "RegisterSeenPokemon", + + [0x02BF] = "SetFieldVolume", + [0x02C4] = "FloorTrapAnimation", @@ -2850,8 +2862,8 @@ namespace DSPRE.Resources { [0x02AA] = new byte[] { 2 }, [0x02AB] = new byte[] { 2 }, [0x02AC] = new byte[] { 2 }, - [0x02AD] = new byte[] { 2, 2 }, - [0x02AE] = new byte[1] { 0 }, + [0x02AD] = new byte[] { 2, 2, 2 }, + [0x02AE] = new byte[] { 2, 2 }, [0x02AF] = new byte[] { 2 }, [0x02B0] = new byte[] { 2 }, [0x02B1] = new byte[] { 2 }, @@ -2868,7 +2880,7 @@ namespace DSPRE.Resources { [0x02BC] = new byte[] { 2 }, [0x02BD] = new byte[] { 2, 2, 2, 2 }, [0x02BE] = new byte[1] { 0 }, - [0x02BF] = new byte[1] { 0 }, + [0x02BF] = new byte[] { 2 }, [0x02C0] = new byte[] { 2 }, [0x02C1] = new byte[1] { 0 }, [0x02C2] = new byte[] { 2 },