diff --git a/DS_Map/DSUtils.cs b/DS_Map/DSUtils.cs index f0add7f..05caa95 100644 --- a/DS_Map/DSUtils.cs +++ b/DS_Map/DSUtils.cs @@ -232,6 +232,35 @@ namespace DSPRE { WriteToFile(RomInfo.arm9Path, bytesToWrite, writeAt, readFrom); } + public static byte[] StringToByteArray(String hex) { + //Ummm what? + int NumberChars = hex.Length; + byte[] bytes = new byte[NumberChars / 2]; + for (int i = 0; i < NumberChars; i += 2) + bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); + return bytes; + } + public static byte[] HexStringToByteArray(string hexString) { + //FC B5 05 48 C0 46 41 21 + //09 22 02 4D A8 47 00 20 + //03 21 FC BD F1 64 00 02 + //00 80 3C 02 + if (hexString is null) + return null; + + hexString = hexString.Trim(); + + byte[] b = new byte[hexString.Length / 3 + 1]; + for (int i = 0; i < hexString.Length; i += 2) { + if (hexString[i] == ' ') { + hexString = hexString.Substring(1, hexString.Length - 1); + } + + b[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16); + } + return b; + } + public static void TryUnpackNarcs(List IDs, ToolStripProgressBar progress = null) { foreach (DirNames id in IDs) { @@ -304,21 +333,7 @@ namespace DSPRE { } return output.ToArray(); } - public static byte[] BuildNSBTXHeader(uint texturesSize) { - MemoryStream ms = new MemoryStream(); - - using (BinaryWriter bw = new BinaryWriter(ms)) { - bw.Write(Encoding.UTF8.GetBytes("BTX0")); // Write magic code BTX0 - bw.Write((ushort)0xFEFF); // Byte order - bw.Write((ushort)0x0001); // ??? - bw.Write(texturesSize); // Write size of textures block - bw.Write((short)0x10); //Header size - bw.Write((short)0x01); //Number of sub-files??? - bw.Write((uint)0x14); // Offset to sub-file - } - return ms.ToArray(); - } - + public static byte[] GetTexturesFromTexturedNSBMD(byte[] modelFile) { using (BinaryReader byteArrReader = new BinaryReader(new MemoryStream(modelFile))) { byteArrReader.BaseStream.Position = 14; @@ -340,7 +355,6 @@ namespace DSPRE { return output; } } - public static int CheckNSBMDHeader(byte[] modelFile) { using (BinaryReader byteArrReader = new BinaryReader(new MemoryStream(modelFile))) { if (byteArrReader.ReadUInt32() != NSBMD.NDS_TYPE_BMD0) { @@ -352,7 +366,20 @@ namespace DSPRE { return byteArrReader.ReadInt16() >= 2 ? NSBMD_HAS_TEXTURE : NSBMD_DOESNTHAVE_TEXTURE; } } + public static byte[] BuildNSBTXHeader(uint texturesSize) { + MemoryStream ms = new MemoryStream(); + using (BinaryWriter bw = new BinaryWriter(ms)) { + bw.Write(Encoding.UTF8.GetBytes("BTX0")); // Write magic code BTX0 + bw.Write((ushort)0xFEFF); // Byte order + bw.Write((ushort)0x0001); // ??? + bw.Write(texturesSize); // Write size of textures block + bw.Write((short)0x10); //Header size + bw.Write((short)0x01); //Number of sub-files??? + bw.Write((uint)0x14); // Offset to sub-file + } + return ms.ToArray(); + } public static byte[] BuildNSBMDwithTextures(byte[] nsbmd, byte[] nsbtx) { byte[] wholeMDL0 = GetFirstBlock(nsbmd); byte[] wholeTEX0 = GetFirstBlock(nsbtx); @@ -378,7 +405,6 @@ namespace DSPRE { } return ms.ToArray(); } - private static byte[] GetFirstBlock(byte[] NSBFile) { int blockSize; uint offsetToMainBlock; diff --git a/DS_Map/Main Window.cs b/DS_Map/Main Window.cs index 69482f8..eec2613 100644 --- a/DS_Map/Main Window.cs +++ b/DS_Map/Main Window.cs @@ -283,7 +283,9 @@ namespace DSPRE { isItemRadioButton.Enabled = true; OWTypeChanged(null, null); } - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied) addHeaderBTN.Enabled = true; + if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied) { + addHeaderBTN.Enabled = true; + } } } private void scriptCommandsDatabaseToolStripButton_Click(object sender, EventArgs e) { @@ -877,18 +879,18 @@ namespace DSPRE { if (headerListBox.Items.Count > 0) headerListBox.SelectedIndex = 0; - ROMToolboxDialog dialog = new ROMToolboxDialog(); - if (dialog.CheckDynamicHeaders()) addHeaderBTN.Enabled = true; + if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) + addHeaderBTN.Enabled = true; } private void addHeaderBTN_Click(object sender, EventArgs e) { // Add new file in the dynamic headers directory - string sourcePath = RomInfo.GetDynamicHeadersDirPath() + "\\" + "0000"; - string destPath = RomInfo.GetDynamicHeadersDirPath() + "\\" + RomInfo.GetHeaderCount().ToString("D4"); + string sourcePath = RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + "0000"; + string destPath = RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + RomInfo.GetHeaderCount().ToString("D4"); File.Copy(sourcePath, destPath); // Add row to internal names table string nameString = "4E 45 57 4D 41 50 00 00 00 00 00 00 00 00 00 00"; - DSUtils.WriteToFile(RomInfo.internalNamesLocation, ROMToolboxDialog.HexStringToByteArray(nameString), (uint)RomInfo.GetHeaderCount() * 0x10); + DSUtils.WriteToFile(RomInfo.internalNamesLocation, DSUtils.HexStringToByteArray(nameString), (uint)RomInfo.GetHeaderCount() * 0x10); // Update headers ListBox and internal names list headerListBox.Items.Add(headerListBox.Items.Count + " - NEWMAP"); @@ -1003,10 +1005,11 @@ namespace DSPRE { ushort headerNumber = ushort.Parse(headerListBox.SelectedItem.ToString().Substring(0, internalNames.Count.ToString().Length)); /* Check if dynamic headers patch has been applied, and load header from arm9 or a/0/5/0 accordingly */ - ROMToolboxDialog dialog = new ROMToolboxDialog(); - if (dialog.CheckDynamicHeaders()) { - currentHeader = MapHeader.BuildFromFile(RomInfo.GetDynamicHeadersDirPath() + "\\" + headerNumber.ToString("D4"), headerNumber, 0); - } else currentHeader = MapHeader.LoadFromARM9(headerNumber); + if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + currentHeader = MapHeader.BuildFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + headerNumber.ToString("D4"), headerNumber, 0); + } else { + currentHeader = MapHeader.LoadFromARM9(headerNumber); + } refreshHeaderEditorFields(); } @@ -1338,9 +1341,8 @@ namespace DSPRE { private void saveHeaderButton_Click(object sender, EventArgs e) { /* Check if dynamic headers patch has been applied, and save header to arm9 or a/0/5/0 accordingly */ - ROMToolboxDialog dialog = new ROMToolboxDialog(); - if (dialog.CheckDynamicHeaders()) { - DSUtils.WriteToFile(RomInfo.GetDynamicHeadersDirPath() + "\\" + currentHeader.ID.ToString("D4"), currentHeader.ToByteArray(), 0, 0, true); + if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + DSUtils.WriteToFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + currentHeader.ID.ToString("D4"), currentHeader.ToByteArray(), 0, 0, true); } else { uint headerOffset = (uint)(PokeDatabase.System.headerOffsetsDict[RomInfo.romID] + MapHeader.length * currentHeader.ID); DSUtils.WriteToArm9(currentHeader.ToByteArray(), headerOffset); @@ -1820,14 +1822,17 @@ namespace DSPRE { headersGridView.Columns.Add("Column" + i, i.ToString("D")); headersGridView.Columns[i].Width = 32; // Set column size headersGridView.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable; + headersGridView.Columns[i].Frozen = (i == 0); heightsGridView.Columns.Add("Column" + i, i.ToString("D")); heightsGridView.Columns[i].Width = 21; // Set column size heightsGridView.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable; + headersGridView.Columns[i].Frozen = (i == 0); mapFilesGridView.Columns.Add("Column" + i, i.ToString("D")); mapFilesGridView.Columns[i].Width = 32; // Set column size mapFilesGridView.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable; + headersGridView.Columns[i].Frozen = (i == 0); } @@ -4378,7 +4383,7 @@ namespace DSPRE { spawnableDirComboBox.Items.AddRange(PokeDatabase.EventEditor.Spawnables.orientationsArray); spawnableTypeComboBox.Items.AddRange(PokeDatabase.EventEditor.Spawnables.typesArray); - if (ScanScriptsCheckStandardizedItemNumbers()) + if (ROMToolboxDialog.CheckScriptsStandardizedItemNumbers()) isItemRadioButton.Enabled = true; disableHandlers = false; @@ -4755,18 +4760,6 @@ namespace DSPRE { overworldsListBox.Items.Add("Overworld " + (currentEvFile.overworlds.Count - 1).ToString()); overworldsListBox.SelectedIndex = currentEvFile.overworlds.Count - 1; } - public static bool ScanScriptsCheckStandardizedItemNumbers() { - ScriptFile itemScript = new ScriptFile(RomInfo.itemScriptFileNumber); - 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) { - return false; - } - } - return true; - } private void OWTypeChanged(object sender, EventArgs e) { if (overworldsListBox.SelectedIndex < 0) return; diff --git a/DS_Map/Main Window.resx b/DS_Map/Main Window.resx index 189648b..8b9c2d9 100644 --- a/DS_Map/Main Window.resx +++ b/DS_Map/Main Window.resx @@ -865,7 +865,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABk - EAAAAk1TRnQBSQFMAgEBCAEAAaQBEgGkARIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo + EAAAAk1TRnQBSQFMAgEBCAEAAawBEgGsARIBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo AwABQAMAATADAAEBAQABCAYAAQwYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5 AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA diff --git a/DS_Map/ROMToolboxDialog.cs b/DS_Map/ROMToolboxDialog.cs index 2b4f451..8e8b603 100644 --- a/DS_Map/ROMToolboxDialog.cs +++ b/DS_Map/ROMToolboxDialog.cs @@ -87,7 +87,8 @@ namespace DSPRE { } } } - public uint expandedARMfileID = ToolboxDB.syntheticOverlayFileNumbersDB[RomInfo.gameFamily]; + + public static uint expandedARMfileID = ToolboxDB.syntheticOverlayFileNumbersDB[RomInfo.gameFamily]; public static bool flag_standardizedItems { get; private set; } = false; public static bool flag_arm9Expanded { get; private set; } = false; public static bool flag_BDHCamPatchApplied { get; private set; } = false; @@ -102,7 +103,7 @@ namespace DSPRE { CheckStandardizedItems(); if (RomInfo.gameLanguage == "ENG" || RomInfo.gameLanguage == "ESP") { - CheckARM9Expansion(); + CheckARM9ExpansionApplied(); } else { DisableARM9patch("Unsupported\nlanguage"); DisableBDHCamPatch("Unsupported\nlanguage"); @@ -120,7 +121,7 @@ namespace DSPRE { DisableOverlay1patch("Unsupported"); DisableMatrixExpansionPatch("Unsupported"); DisableScrcmdRepointPatch("Unsupported"); - CheckFilesBDHCamPatchApplied(); + CheckBDHCamPatchApplied(); CheckDynamicHeadersPatchApplied(); break; case "HGSS": @@ -129,10 +130,10 @@ namespace DSPRE { overlay1CB.Visible = true; } - CheckFilesBDHCamPatchApplied(); + CheckBDHCamPatchApplied(); if (RomInfo.gameLanguage == "ENG" || RomInfo.gameLanguage == "ESP") { - CheckMatrixPatchApplied(); + CheckMatrixExpansionApplied(); CheckScrcmdRepointPatchApplied(); } else { DisableMatrixExpansionPatch("Unsupported\nlanguage"); @@ -192,31 +193,114 @@ namespace DSPRE { #endregion #endregion - #region Patch Checkers - private int CheckARM9Expansion() { - if (!flag_arm9Expanded) { - ARM9PatchData data = new ARM9PatchData(); + #region Patch + private static bool CheckFilesArm9ExpansionApplied() { + ARM9PatchData data = new ARM9PatchData(); - try { - byte[] branchCode = HexStringToByteArray(data.branchString); - byte[] branchCodeRead = DSUtils.ReadFromArm9(data.branchOffset, data.branchString.Length / 3 + 1); //Read branchCode - if (branchCodeRead.Length != branchCode.Length) - return 0; //0 means ARM9 Expansion has never been applied - if (!branchCodeRead.SequenceEqual(branchCode)) - return 0; + byte[] branchCode = DSUtils.HexStringToByteArray(data.branchString); + byte[] branchCodeRead = DSUtils.ReadFromArm9(data.branchOffset, data.branchString.Length / 3 + 1); //Read branchCode + if (branchCodeRead.Length != branchCode.Length || !branchCodeRead.SequenceEqual(branchCode)) + return false; - byte[] initCode = HexStringToByteArray(data.initString); - byte[] initCodeRead = DSUtils.ReadFromArm9(data.initOffset, data.initString.Length / 3 + 1); //Read initCode - if (initCodeRead.Length != initCode.Length) - return 0; - if (!initCodeRead.SequenceEqual(initCode)) - return 0; - } catch { - return -1; //-1 means Check failure + byte[] initCode = DSUtils.HexStringToByteArray(data.initString); + byte[] initCodeRead = DSUtils.ReadFromArm9(data.initOffset, data.initString.Length / 3 + 1); //Read initCode + if (initCodeRead.Length != initCode.Length || !initCodeRead.SequenceEqual(initCode)) + return false; + + return true; + } + public static bool CheckFilesBDHCamPatchApplied() { + BDHCAMPatchData data = new BDHCAMPatchData(); + + byte[] branchCode = DSUtils.HexStringToByteArray(data.branchString); + byte[] branchCodeRead = DSUtils.ReadFromArm9(data.branchOffset, branchCode.Length); + + if (branchCode.Length != branchCodeRead.Length || !branchCode.SequenceEqual(branchCodeRead)) + return false; + + + string overlayFilePath = RomInfo.workDir + "overlay" + "\\" + "overlay_" + data.overlayNumber.ToString("D4") + ".bin"; + DSUtils.DecompressOverlay(data.overlayNumber); + + byte[] overlayCode1 = DSUtils.HexStringToByteArray(data.overlayString1); + byte[] overlayCode1Read = DSUtils.ReadFromFile(overlayFilePath, data.overlayOffset1, overlayCode1.Length); + 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)) + return false; //0 means BDHCAM patch has not been applied + + String fullFilePath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + ROMToolboxDialog.expandedARMfileID.ToString("D4"); + byte[] subroutineRead = DSUtils.ReadFromFile(fullFilePath, ToolboxDB.BDHCamSubroutineOffset, data.subroutine.Length); //Write new overlayCode1 + if (data.subroutine.Length != subroutineRead.Length || !data.subroutine.SequenceEqual(subroutineRead)) + return false; //0 means BDHCAM patch has not been applied + + return true; + } + 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") + languageOffset = +8; + + byte[] read = DSUtils.ReadFromArm9((uint)(offset - 0x02000000 + languageOffset), kv.Value.Length / 3 + 1); + byte[] code = DSUtils.HexStringToByteArray(kv.Value); + if (read.Length != code.Length || !read.SequenceEqual(code)) + return false; + } + } + return true; + } + public static bool CheckScriptsStandardizedItemNumbers() { + ScriptFile itemScript = new ScriptFile(RomInfo.itemScriptFileNumber); + 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) { + return false; + } + } + return true; + } + public bool CheckStandardizedItems() { + DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.scripts }); + + if (!ROMToolboxDialog.flag_standardizedItems) { + if (!ROMToolboxDialog.CheckScriptsStandardizedItemNumbers()) { + return false; } } - flag_arm9Expanded = true; + itemNumbersCB.Visible = true; + ROMToolboxDialog.flag_standardizedItems = true; + + DisableStandardizeItemsPatch("Already applied"); + return true; + } + public bool CheckMatrixExpansionApplied() { + if (!ROMToolboxDialog.flag_MatrixExpansionApplied) { + if (!ROMToolboxDialog.CheckFilesMatrixExpansionApplied()) { + return false; + } + } + + DisableMatrixExpansionPatch("Already applied"); + ROMToolboxDialog.flag_MatrixExpansionApplied = true; + expandedMatrixCB.Visible = true; + return true; + } + private bool CheckARM9ExpansionApplied() { + if (!ROMToolboxDialog.flag_arm9Expanded) { + if (!ROMToolboxDialog.CheckFilesArm9ExpansionApplied()) + return false; + } + + ROMToolboxDialog.flag_arm9Expanded = true; arm9patchCB.Visible = true; DisableARM9patch("Already applied"); @@ -229,120 +313,47 @@ namespace DSPRE { BDHCamPatchTextLBL.Enabled = true; break; } - return 1; //arm9 Expansion has already been applied + + return true; } - private int CheckDynamicHeadersPatchApplied() { - if (!flag_DynamicHeadersPatchApplied) { - if (!CheckDynamicHeaders()) return 0; + public bool CheckDynamicHeadersPatchApplied() { + if (!ROMToolboxDialog.flag_DynamicHeadersPatchApplied) { + if (!ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) + return false; } - flag_DynamicHeadersPatchApplied = true; + ROMToolboxDialog.flag_DynamicHeadersPatchApplied = true; dynamicHeadersPatchCB.Visible = true; DisableDynamicHeadersPatch("Already applied"); - return 1; + return true; } - public bool CheckDynamicHeaders() { + + public static bool CheckFilesDynamicHeadersPatchApplied() { DynamicHeadersPatchData data = new DynamicHeadersPatchData(); ushort initValue = BitConverter.ToUInt16(DSUtils.ReadFromArm9(data.initOffset, 0x2), 0); - - if (initValue == 0xB500) return true; - else return false; + return initValue == 0xB500; } - private int CheckFilesBDHCamPatchApplied() { - if (!flag_arm9Expanded) { + + public bool CheckBDHCamPatchApplied() { + if (!CheckARM9ExpansionApplied()) { BDHCamARM9requiredLBL.Visible = true; - DisableBDHCamPatch("!"); - return 0; + DisableBDHCamPatch("ARM9 not expanded!"); + return false; } - if (!flag_BDHCamPatchApplied) { - BDHCAMPatchData data = new BDHCAMPatchData(); - try { - byte[] branchCode = HexStringToByteArray(data.branchString); - byte[] branchCodeRead = DSUtils.ReadFromArm9(data.branchOffset, branchCode.Length); - - if (branchCode.Length != branchCodeRead.Length) - return 0; //0 means BDHCAM patch has not been applied - if (!branchCode.SequenceEqual(branchCodeRead)) - return 0; - - - string overlayFilePath = RomInfo.workDir + "overlay" + "\\" + "overlay_" + data.overlayNumber.ToString("D4") + ".bin"; - DSUtils.DecompressOverlay(data.overlayNumber); - - byte[] overlayCode1 = HexStringToByteArray(data.overlayString1); - byte[] overlayCode1Read = DSUtils.ReadFromFile(overlayFilePath, data.overlayOffset1, overlayCode1.Length); - if (overlayCode1.Length != overlayCode1Read.Length) - return 0; //0 means BDHCAM patch has not been applied - if (!overlayCode1.SequenceEqual(overlayCode1Read)) - return 0; - - - byte[] overlayCode2 = HexStringToByteArray(data.overlayString2); - byte[] overlayCode2Read = DSUtils.ReadFromFile(overlayFilePath, data.overlayOffset2, overlayCode2.Length); //Write new overlayCode1 - if (overlayCode2.Length != overlayCode2Read.Length) - return 0; //0 means BDHCAM patch has not been applied - if (!overlayCode2.SequenceEqual(overlayCode2Read)) - return 0; - - String fullFilePath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + expandedARMfileID.ToString("D4"); - byte[] subroutineRead = DSUtils.ReadFromFile(fullFilePath, ToolboxDB.BDHCamSubroutineOffset, data.subroutine.Length); //Write new overlayCode1 - if (data.subroutine.Length != subroutineRead.Length) - return 0; //0 means BDHCAM patch has not been applied - if (!data.subroutine.SequenceEqual(subroutineRead)) - return 0; - } catch { - return -1; + if (!ROMToolboxDialog.flag_BDHCamPatchApplied) { + if (!ROMToolboxDialog.CheckFilesBDHCamPatchApplied()) { + return false; } } - flag_BDHCamPatchApplied = true; + ROMToolboxDialog.flag_BDHCamPatchApplied = true; BDHCamCB.Visible = true; DisableBDHCamPatch("Already applied"); - return 0; + return true; } - public bool CheckStandardizedItems() { - DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.scripts }); - - if (flag_standardizedItems || MainProgram.ScanScriptsCheckStandardizedItemNumbers()) { - itemNumbersCB.Visible = true; - flag_standardizedItems = true; - - DisableStandardizeItemsPatch("Already applied"); - return true; - } - return false; - } - private int CheckMatrixPatchApplied() { - if (!flag_MatrixExpansionApplied) { - try { - 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") - languageOffset = +8; - - byte[] read = DSUtils.ReadFromArm9((uint)(offset - 0x02000000 + languageOffset), kv.Value.Length / 3 + 1); - byte[] code = HexStringToByteArray(kv.Value); - if (read.Length != code.Length) - return 0; - if (!read.SequenceEqual(code)) - return 0; - } - } - } catch { - return -1; //-1 means Check failure - } - } - - DisableMatrixExpansionPatch("Already applied"); - flag_MatrixExpansionApplied = true; - expandedMatrixCB.Visible = true; - return 1; //arm9 Expansion has already been applied - } - - private void CheckScrcmdRepointPatchApplied() { + public void CheckScrcmdRepointPatchApplied() { //throw new NotImplementedException(); } #endregion @@ -403,7 +414,7 @@ namespace DSPRE { File.Copy(RomInfo.arm9Path, RomInfo.arm9Path + ".backup", overwrite: true); try { - DSUtils.WriteToArm9(HexStringToByteArray(data.branchString), data.branchOffset); //Write new branchOffset + DSUtils.WriteToArm9(DSUtils.HexStringToByteArray(data.branchString), data.branchOffset); //Write new branchOffset /* Write to overlayfile */ string overlayFilePath = RomInfo.workDir + "overlay" + "\\" + "overlay_" + data.overlayNumber.ToString("D4") + ".bin"; @@ -411,8 +422,8 @@ namespace DSPRE { DSUtils.DecompressOverlay(data.overlayNumber); } - DSUtils.WriteToFile(overlayFilePath, HexStringToByteArray(data.overlayString1), data.overlayOffset1); //Write new overlayCode1 - DSUtils.WriteToFile(overlayFilePath, HexStringToByteArray(data.overlayString2), data.overlayOffset2); //Write new overlayCode2 + DSUtils.WriteToFile(overlayFilePath, DSUtils.HexStringToByteArray(data.overlayString1), data.overlayOffset1); //Write new overlayCode1 + DSUtils.WriteToFile(overlayFilePath, DSUtils.HexStringToByteArray(data.overlayString2), data.overlayOffset2); //Write new overlayCode2 overlay1MustBeRestoredFromBackup = false; String fullFilePath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + expandedARMfileID.ToString("D4"); @@ -427,7 +438,7 @@ namespace DSPRE { overlay1MustBeRestoredFromBackup = false; DisableBDHCamPatch("Already applied"); - flag_BDHCamPatchApplied = true; + ROMToolboxDialog.flag_BDHCamPatchApplied = true; BDHCamCB.Visible = true; MessageBox.Show("The BDHCAM patch has been applied.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -465,7 +476,7 @@ namespace DSPRE { DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.scripts }); - if (flag_standardizedItems) { + if (ROMToolboxDialog.flag_standardizedItems) { AlreadyApplied(); } else { ScriptFile itemScript = new ScriptFile(RomInfo.itemScriptFileNumber); @@ -490,7 +501,7 @@ namespace DSPRE { DisableStandardizeItemsPatch("Already applied"); itemNumbersCB.Visible = true; - flag_standardizedItems = true; + ROMToolboxDialog.flag_standardizedItems = true; } } else { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -512,8 +523,8 @@ namespace DSPRE { File.Copy(RomInfo.arm9Path, RomInfo.arm9Path + ".backup", overwrite: true); try { - DSUtils.WriteToArm9(HexStringToByteArray(data.branchString), data.branchOffset); //Write new branchOffset - DSUtils.WriteToArm9(HexStringToByteArray(data.initString), data.initOffset); //Write new initOffset + DSUtils.WriteToArm9(DSUtils.HexStringToByteArray(data.branchString), data.branchOffset); //Write new branchOffset + DSUtils.WriteToArm9(DSUtils.HexStringToByteArray(data.initString), data.initOffset); //Write new initOffset string fullFilePath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + expandedARMfileID.ToString("D4"); File.Delete(fullFilePath); @@ -524,7 +535,7 @@ namespace DSPRE { DisableARM9patch("Already applied"); arm9patchCB.Visible = true; - flag_arm9Expanded = true; + ROMToolboxDialog.flag_arm9Expanded = true; switch (RomInfo.gameFamily) { case "Plat": @@ -577,7 +588,7 @@ namespace DSPRE { try { foreach (KeyValuePair kv in ToolboxDB.matrixExpansionDB) { foreach (uint offset in kv.Key) { - DSUtils.WriteToArm9(HexStringToByteArray(kv.Value), (uint)(offset - 0x02000000 + languageOffset)); + DSUtils.WriteToArm9(DSUtils.HexStringToByteArray(kv.Value), (uint)(offset - 0x02000000 + languageOffset)); } } } catch { @@ -586,7 +597,7 @@ namespace DSPRE { } DisableMatrixExpansionPatch("Already applied"); expandedMatrixCB.Visible = true; - flag_MatrixExpansionApplied = true; + ROMToolboxDialog.flag_MatrixExpansionApplied = true; MessageBox.Show("Matrix 0 can now be freely expanded up to twice its size.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); } else { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -643,7 +654,7 @@ namespace DSPRE { DE F7 3D F9 bl 0x02017E6C @Free_Memory */ - DSUtils.WriteToArm9(HexStringToByteArray(data.initString), data.initOffset); + DSUtils.WriteToArm9(DSUtils.HexStringToByteArray(data.initString), data.initOffset); /* - Neutralize instances of HeaderID * 0x18 so the base offset the data is read from is always 0x0: @@ -665,7 +676,7 @@ namespace DSPRE { */ foreach (Tuple reference in ToolboxDB.dynamicHeadersPointersDB[RomInfo.gameFamily]) { - DSUtils.WriteToArm9(HexStringToByteArray(data.REFERENCE_STRING), (uint)(reference.Item1 + data.pointerDiff)); + DSUtils.WriteToArm9(DSUtils.HexStringToByteArray(data.REFERENCE_STRING), (uint)(reference.Item1 + data.pointerDiff)); uint pointerValue = BitConverter.ToUInt32(DSUtils.ReadFromArm9((uint)(reference.Item2 + data.pointerDiff), 4), 0) - PokeDatabase.System.headerOffsetsDict[RomInfo.romID] - 0x02000000; DSUtils.WriteToArm9(BitConverter.GetBytes(pointerValue), (uint)(reference.Item2 + data.pointerDiff)); @@ -675,13 +686,13 @@ namespace DSPRE { /* 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 */ - DSUtils.WriteToArm9(HexStringToByteArray("19 00"), (uint)(0x3B522 + data.pointerDiff)); - DSUtils.WriteToArm9(HexStringToByteArray("C0 46"), (uint)(0x3B526 + data.pointerDiff)); - DSUtils.WriteToArm9(HexStringToByteArray("00 00 00 00"), (uint)(0x3B53C + data.pointerDiff)); + DSUtils.WriteToArm9(DSUtils.HexStringToByteArray("19 00"), (uint)(0x3B522 + data.pointerDiff)); + DSUtils.WriteToArm9(DSUtils.HexStringToByteArray("C0 46"), (uint)(0x3B526 + data.pointerDiff)); + DSUtils.WriteToArm9(DSUtils.HexStringToByteArray("00 00 00 00"), (uint)(0x3B53C + data.pointerDiff)); } // Clear the dynamic headers directory in 'unpacked' - string headersDir = RomInfo.GetDynamicHeadersDirPath(); + string headersDir = RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir; Directory.Delete(headersDir, true); Directory.CreateDirectory(headersDir); @@ -696,7 +707,7 @@ namespace DSPRE { DisableDynamicHeadersPatch("Already applied"); dynamicHeadersPatchCB.Visible = true; - flag_DynamicHeadersPatchApplied = true; + ROMToolboxDialog.flag_DynamicHeadersPatchApplied = true; MessageBox.Show("The headers are now dynamically allocated in memory.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch { @@ -815,7 +826,7 @@ namespace DSPRE { expandedWriter.BaseStream.Position = 0x200 + commandID * 4; expandedWriter.Write((UInt32)(0x023C8000 + asmOffset + 1)); - byte[] asmCodeBytes = StringToByteArray(asmCode); + byte[] asmCodeBytes = DSUtils.StringToByteArray(asmCode); expandedWriter.BaseStream.Position = asmOffset; expandedWriter.Write(asmCodeBytes); @@ -841,48 +852,9 @@ namespace DSPRE { } #endregion - #endregion - #region Utilities - //Ummm what? - private byte[] StringToByteArray(String hex) { - int NumberChars = hex.Length; - byte[] bytes = new byte[NumberChars / 2]; - for (int i = 0; i < NumberChars; i += 2) - bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16); - return bytes; - } - - public static byte[] HexStringToByteArray(string hexString) { - //FC B5 05 48 C0 46 41 21 - //09 22 02 4D A8 47 00 20 - //03 21 FC BD F1 64 00 02 - //00 80 3C 02 - if (hexString is null) - return null; - - hexString = hexString.Trim(); - - byte[] b = new byte[hexString.Length / 3 + 1]; - for (int i = 0; i < hexString.Length; i += 2) { - if (hexString[i] == ' ') { - hexString = hexString.Substring(1, hexString.Length - 1); - } - - b[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16); - } - return b; - } #endregion #region Error Messsages - private void UnsupportedROM() { - MessageBox.Show("This operation is currently impossible to carry out on any Pokémon " + RomInfo.gameName + " rom.", - "Unsupported ROM", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - private void UnsupportedROMLanguage() { - MessageBox.Show("This operation is currently impossible to carry out on the " + RomInfo.gameLanguage + - " version of this rom.", "Unsupported Language", MessageBoxButtons.OK, MessageBoxIcon.Information); - } private void AlreadyApplied() { MessageBox.Show("This patch has already been applied.", "Can't reapply patch", MessageBoxButtons.OK, MessageBoxIcon.Information); } diff --git a/DS_Map/RomInfo.cs b/DS_Map/RomInfo.cs index edc921a..b073986 100644 --- a/DS_Map/RomInfo.cs +++ b/DS_Map/RomInfo.cs @@ -39,7 +39,7 @@ namespace DSPRE { public static int attackNamesTextNumber { get; private set; } public static int[] pokemonNamesTextNumbers { get; private set; } public static int itemNamesTextNumber { get; private set; } - public static int itemScriptFileNumber { get; internal set; } + public static int itemScriptFileNumber { get; internal set; } public static int trainerClassMessageNumber { get; private set; } public static int trainerNamesMessageNumber { get; private set; } public static int locationNamesTextNumber { get; private set; } @@ -57,11 +57,10 @@ namespace DSPRE { public static Dictionary ow3DSpriteDict { get; private set; } public enum DirNames : byte { - synthOverlay, - textArchives, - + synthOverlay, dynamicHeaders, - + + textArchives, matrices, maps, @@ -79,15 +78,15 @@ namespace DSPRE { encounters, interiorBuildingModels - }; + }; public static Dictionary gameDirs { get; private set; } - + #region Constructors (1) public RomInfo(string id, string romName) { romID = id; fileName = romName; - workDir = Path.GetDirectoryName(romName) + "\\" + Path.GetFileNameWithoutExtension(romName) + folderSuffix + "\\";; + workDir = Path.GetDirectoryName(romName) + "\\" + Path.GetFileNameWithoutExtension(romName) + folderSuffix + "\\"; LoadGameVersion(); if (gameVersion is null) return; @@ -103,7 +102,7 @@ namespace DSPRE { internalNamesLocation = workDir + @"data\fielddata\maptable\mapname.bin"; SetNarcDirs(); - SetNullEncounterID(); + SetNullEncounterID(); SetAttackNamesTextNumber(); SetPokémonNamesTextNumber(); @@ -118,7 +117,7 @@ namespace DSPRE { CommandParametersDict = BuildCommandParametersDatabase(gameVersion); } - public static string GetRomNameFromWorkdir () { + public static string GetRomNameFromWorkdir() { return workDir.Substring(0, workDir.Length - folderSuffix.Length - 1); } public static void Set3DOverworldsDict() { @@ -243,7 +242,7 @@ namespace DSPRE { case "JAP": cameraTblOffsetsToRAMaddress = new uint[] { 0x5324, 0x5474 }; break; - } + } break; } } @@ -274,7 +273,7 @@ namespace DSPRE { break; } } - public void SetNarcDirs () { + public void SetNarcDirs() { Dictionary packedDirsDict = null; switch (gameFamily) { case "DP": @@ -282,7 +281,7 @@ namespace DSPRE { if (!gameLanguage.Equals("JAP")) suffix = "_release"; - packedDirsDict = new Dictionary() { + packedDirsDict = new Dictionary() { [DirNames.synthOverlay] = @"data\data\weather_sys.narc", [DirNames.textArchives] = @"data\msgdata\msg.narc", @@ -306,10 +305,10 @@ namespace DSPRE { case "Plat": packedDirsDict = new Dictionary() { [DirNames.synthOverlay] = @"data\data\weather_sys.narc", - [DirNames.textArchives] = @"data\msgdata\" + gameVersion.Substring(0,2).ToLower() + '_' + "msg.narc", - [DirNames.dynamicHeaders] = @"data\debug\cb_edit\d_test.narc", + [DirNames.textArchives] = @"data\msgdata\" + gameVersion.Substring(0, 2).ToLower() + '_' + "msg.narc", + [DirNames.matrices] = @"data\fielddata\mapmatrix\map_matrix.narc", [DirNames.maps] = @"data\fielddata\land_data\land_data.narc", @@ -324,16 +323,16 @@ namespace DSPRE { [DirNames.OWSprites] = @"data\data\mmodel\mmodel.narc", [DirNames.scripts] = @"data\fielddata\script\scr_seq.narc", - [DirNames.encounters] = @"data\fielddata\encountdata\" + gameVersion.Substring(0,2).ToLower() + '_' + "enc_data.narc" + [DirNames.encounters] = @"data\fielddata\encountdata\" + gameVersion.Substring(0, 2).ToLower() + '_' + "enc_data.narc" }; break; case "HGSS": packedDirsDict = new Dictionary() { [DirNames.synthOverlay] = @"data\a\0\2\8", - [DirNames.textArchives] = @"data\a\0\2\7", - [DirNames.dynamicHeaders] = @"data\a\0\5\0", + [DirNames.textArchives] = @"data\a\0\2\7", + [DirNames.matrices] = @"data\a\0\4\1", [DirNames.maps] = @"data\a\0\6\5", @@ -363,7 +362,7 @@ namespace DSPRE { gameDirs = new Dictionary(); foreach (KeyValuePair kvp in packedDirsDict) { - gameDirs.Add(kvp.Key, (workDir + kvp.Value, workDir + @"unpacked" + '\\' + kvp.Key.ToString()) ); + gameDirs.Add(kvp.Key, (workDir + kvp.Value, workDir + @"unpacked" + '\\' + kvp.Key.ToString())); } } public string GetBuildingModelsDirPath(bool interior) { @@ -373,11 +372,7 @@ namespace DSPRE { return gameDirs[DirNames.exteriorBuildingModels].unpackedDir; } } - public static string GetDynamicHeadersDirPath() - { - return workDir + "\\" + "unpacked" + "\\" + "dynamicHeaders"; - } - public static void SetOWtable () { + public static void SetOWtable() { switch (gameFamily) { case "DP": OWtablePath = workDir + "overlay" + "\\" + "overlay_0005.bin"; @@ -435,7 +430,7 @@ namespace DSPRE { var customDictionaryNames = PokeDatabase.ScriptEditor.CustomScrCmdNames; return commonDictionaryNames.Concat(customDictionaryNames).ToLookup(x => x.Key, x => x.Value).ToDictionary(x => x.Key, g => g.First()); } - } + } public static Dictionary BuildCommandParametersDatabase(string gameVer) { switch (gameFamily) { case "DP": @@ -445,7 +440,7 @@ namespace DSPRE { case "Plat": commonDictionaryParams = PokeDatabase.ScriptEditor.DPPtScrCmdParameters; specificDictionaryParams = PokeDatabase.ScriptEditor.PlatScrCmdParameters; - return commonDictionaryParams.Concat(specificDictionaryParams).ToLookup(x => x.Key, x => x.Value).ToDictionary(x => x.Key, g => g.First()); + return commonDictionaryParams.Concat(specificDictionaryParams).ToLookup(x => x.Key, x => x.Value).ToDictionary(x => x.Key, g => g.First()); default: commonDictionaryParams = PokeDatabase.ScriptEditor.HGSSScrCmdParameters; var customDictionaryParams = PokeDatabase.ScriptEditor.CustomScrCmdParameters; @@ -591,7 +586,8 @@ namespace DSPRE { break; } } - public void SetLocationNamesTextNumber() {; + public void SetLocationNamesTextNumber() { + ; switch (gameFamily) { case "DP": locationNamesTextNumber = 382; @@ -666,7 +662,7 @@ namespace DSPRE { 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 GetScriptCount() => Directory.GetFiles(gameDirs[DirNames.scripts].unpackedDir).Length; public int GetBuildingCount(bool interior) { return Directory.GetFiles(GetBuildingModelsDirPath(interior)).Length; } @@ -687,14 +683,14 @@ namespace DSPRE { public void SetMapCellsColorDictionary(Dictionary, (Color background, Color foreground)> dict) { MapCellsColorDictionary = dict; } - public static void ReadOWTable () { + public static void ReadOWTable() { OverworldTable = new SortedDictionary(); switch (gameFamily) { case "DP": case "Plat": 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) { @@ -719,7 +715,7 @@ 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(); diff --git a/DS_Map/SpawnEditor.cs b/DS_Map/SpawnEditor.cs index 9f2e78e..8b8a298 100644 --- a/DS_Map/SpawnEditor.cs +++ b/DS_Map/SpawnEditor.cs @@ -74,11 +74,23 @@ namespace DSPRE { ushort globalY = BitConverter.ToUInt16(DSUtils.ReadFromArm9(RomInfo.arm9spawnOffset + 12, 2), 0); spawnHeaderComboBox.SelectedIndex = headerNumber; + localmapxUpDown.Value = (short)(globalX % 32); localmapyUpDown.Value = (short)(globalY % 32); - matrixxUpDown.Value = (ushort)(globalX / 32); - matrixyUpDown.Value = (ushort)(globalY / 32); + + try { + matrixxUpDown.Value = (ushort)Math.Min(globalX / 32, matrixxUpDown.Maximum); + } catch (ArgumentOutOfRangeException) { + matrixxUpDown.Value = matrixxUpDown.Maximum; + } + + try { + matrixyUpDown.Value = (ushort)Math.Min(globalY / 32, matrixyUpDown.Maximum); + } catch (ArgumentOutOfRangeException) { + matrixyUpDown.Value = matrixyUpDown.Maximum; + } + ReadDefaultMoney(); playerDirCombobox.SelectedIndex = BitConverter.ToUInt16(DSUtils.ReadFromArm9(RomInfo.arm9spawnOffset + 16, 2), 0); }