diff --git a/DS_Map/BuildingEditor.cs b/DS_Map/BuildingEditor.cs index 0587fe8..6444e42 100644 --- a/DS_Map/BuildingEditor.cs +++ b/DS_Map/BuildingEditor.cs @@ -62,7 +62,7 @@ namespace DSPRE { string readingPath = folder + rom.GetBuildingModelsDirPath(interior) + "\\" + modelID.ToString("D4"); byte[] txFile = File.ReadAllBytes(readingPath); - byte[] texData = DSUtils.GetTexturesFromTexturedNSBMD(txFile); + byte[] texData = NSBUtils.GetTexturesFromTexturedNSBMD(txFile); if (texData.Length <= 4) { Console.WriteLine("No textures found"); @@ -76,7 +76,7 @@ namespace DSPRE { string filePath = folder + rom.GetBuildingModelsDirPath(interior) + "\\" + currentIndex.ToString("D4"); using (DSUtils.EasyReader reader = new DSUtils.EasyReader(filePath, 0x14)) { - string nsbmdName = DSUtils.ReadNSBMDname(reader); + string nsbmdName = NSBUtils.ReadNSBMDname(reader); buildingEditorBldListBox.Items.Add("[" + currentIndex.ToString("D3") + "] " + nsbmdName); } } @@ -207,7 +207,7 @@ namespace DSPRE { int currentIndex = buildingEditorBldListBox.SelectedIndex; File.Copy(im.FileName, folder + rom.GetBuildingModelsDirPath(interiorCheckBox.Checked) + "\\" + currentIndex.ToString("D4"), true); - buildingEditorBldListBox.Items[currentIndex] = "[" + currentIndex.ToString("D3") + "] " + DSUtils.ReadNSBMDname(reader, 0x14); + buildingEditorBldListBox.Items[currentIndex] = "[" + currentIndex.ToString("D3") + "] " + NSBUtils.ReadNSBMDname(reader, 0x14); buildingEditorListBox_SelectedIndexChanged(null, null); } } @@ -275,7 +275,7 @@ namespace DSPRE { } private void bldExportDAEbutton_Click(object sender, EventArgs e) { - DSUtils.ModelToDAE( + ModelUtils.ModelToDAE( modelName: buildingEditorBldListBox.SelectedItem.ToString().TrimEnd('\0'), modelData: currentModelData, textureData: textureComboBox.SelectedIndex < 1 ? null : File.ReadAllBytes(RomInfo.gameDirs[DirNames.buildingTextures].unpackedDir + "\\" + (textureComboBox.SelectedIndex - 1).ToString("D4")) diff --git a/DS_Map/DSPRE.csproj b/DS_Map/DSPRE.csproj index 8452f29..394e6e8 100644 --- a/DS_Map/DSPRE.csproj +++ b/DS_Map/DSPRE.csproj @@ -95,6 +95,11 @@ + + + + + Form @@ -205,7 +210,6 @@ - Form @@ -252,11 +256,11 @@ - + Form - - ROMToolboxDialog.cs + + PatchToolboxDialog.cs Form @@ -417,8 +421,8 @@ CommandsDatabase.cs Designer - - ROMToolboxDialog.cs + + PatchToolboxDialog.cs BuildingEditor.cs diff --git a/DS_Map/DSUtils.cs b/DS_Map/DSUtils.cs deleted file mode 100644 index b001237..0000000 --- a/DS_Map/DSUtils.cs +++ /dev/null @@ -1,652 +0,0 @@ -using Ekona.Images; -using Images; -using LibNDSFormats.NSBMD; -using Microsoft.WindowsAPICodePack.Dialogs; -using NarcAPI; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using static DSPRE.RomInfo; - -namespace DSPRE { - public static class DSUtils { - public static readonly string NDSRomFilter = "NDS File (*.nds)|*.nds"; - public class EasyReader : BinaryReader { - public EasyReader(string path, long pos = 0) : base(File.OpenRead(path)) { - this.BaseStream.Position = pos; - } - } - public class EasyWriter : BinaryWriter { - public EasyWriter(string path, long pos = 0, FileMode fmode = FileMode.OpenOrCreate) : base(new FileStream(path, fmode, FileAccess.Write, FileShare.None)) { - this.BaseStream.Position = pos; - } - public void EditSize(int increment) { - this.BaseStream.SetLength(this.BaseStream.Length + increment); - } - } - public static class ARM9 { - public static readonly uint address = 0x02000000; - public class Reader : EasyReader { - public Reader(long pos = 0) : base(arm9Path, pos) { - this.BaseStream.Position = pos; - } - } - public class Writer : EasyWriter { - public Writer(long pos = 0) : base(arm9Path, pos) { - this.BaseStream.Position = pos; - } - } - public static void EditSize(int increment) { - using (Writer w = new Writer()) { - w.EditSize(increment); - } - } - public static bool Decompress(string path) { - Process decompress = new Process(); - decompress.StartInfo.FileName = @"Tools\blz.exe"; - decompress.StartInfo.Arguments = @" -d " + '"' + path + '"'; - decompress.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - decompress.StartInfo.CreateNoWindow = true; - decompress.Start(); - decompress.WaitForExit(); - - return new FileInfo(RomInfo.arm9Path).Length > 0xBC000; - } - public static bool Compress(string path) { - Process compress = new Process(); - compress.StartInfo.FileName = @"Tools\blz.exe"; - compress.StartInfo.Arguments = @" -en9 " + '"' + path + '"'; - compress.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - compress.StartInfo.CreateNoWindow = true; - compress.Start(); - compress.WaitForExit(); - - return new FileInfo(RomInfo.arm9Path).Length <= 0xBC000; - } - public static bool CheckCompressionMark() { - return BitConverter.ToInt32(DSUtils.ARM9.ReadBytes((uint)(RomInfo.gameFamily == GameFamilies.DP ? 0xB7C : 0xBB4), 4), 0) != 0; - } - public static byte[] ReadBytes(uint startOffset, long numberOfBytes = 0) { - return ReadFromFile(RomInfo.arm9Path, startOffset, numberOfBytes); - } - public static void WriteBytes(byte[] bytesToWrite, uint destOffset, int indexFirstByteToWrite = 0, int? indexLastByteToWrite = null) { - WriteToFile(RomInfo.arm9Path, bytesToWrite, destOffset, indexFirstByteToWrite, indexLastByteToWrite); - } - public static byte ReadByte(uint startOffset) { - return ReadFromFile(RomInfo.arm9Path, startOffset, 1)[0]; - } - public static void WriteByte(byte value, uint destOffset) { - WriteToFile(RomInfo.arm9Path, BitConverter.GetBytes(value), destOffset, 0); - } - } - - public const int NSBMD_DOESNTHAVE_TEXTURE = 0; - public const int NSBMD_HAS_TEXTURE = 1; - - public const int ERR_OVERLAY_NOTFOUND = -1; - public const int ERR_OVERLAY_ALREADY_UNCOMPRESSED = -2; - - public const string backupSuffix = ".backup"; - - public static string ReadNSBMDname(BinaryReader reader, long? startPos = null) { - if (startPos != null) { - reader.BaseStream.Position = (long)startPos; - } - - if (reader.ReadUInt32() == NSBMD.NDS_TYPE_MDL0) { //MDL0 - reader.BaseStream.Position += 0x1c; - } else { - reader.BaseStream.Position += 0x1c + 4; - } - - return Encoding.UTF8.GetString(reader.ReadBytes(16)); - } - - public static void ModelToDAE(string modelName, byte[] modelData, byte[] textureData) { - MessageBox.Show("Choose output folder.\nDSPRE will automatically create a sub-folder in it.", "Awaiting user input", MessageBoxButtons.OK, MessageBoxIcon.Information); - - CommonOpenFileDialog cofd = new CommonOpenFileDialog { - IsFolderPicker = true, - Multiselect = false - }; - if (cofd.ShowDialog() != CommonFileDialogResult.Ok) { - return; - } - - string outDir = Path.Combine(cofd.FileName, modelName); - - if (Directory.Exists(outDir)) { - if (Directory.GetFiles(outDir).Length > 0) { - DialogResult d = MessageBox.Show($"Directory \"{outDir}\" already exists and is not empty.\nIts contents will be lost.\n\nDo you want to proceed?", "Directory not empty", MessageBoxButtons.YesNo, MessageBoxIcon.Question); - - if (d.Equals(DialogResult.No)) { - return; - } else { - Directory.Delete(outDir, recursive: true); - } - } else { - Directory.Delete(outDir, recursive: true); - } - } - string tempNSBMDPath = outDir + "_temp.nsbmd"; - - if (textureData != null && textureData.Length > 0) { - modelData = DSUtils.BuildNSBMDwithTextures(modelData, textureData); - } - - File.WriteAllBytes(tempNSBMDPath, modelData); - - /* Check correct creation of temp NSBMD file*/ - if (!File.Exists(tempNSBMDPath)) { - MessageBox.Show("NSBMD file corresponding to this map could not be found.\nAborting", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - } - - Process apicula = new Process(); - apicula.StartInfo.FileName = @"Tools\apicula.exe"; - apicula.StartInfo.Arguments = $" convert \"{tempNSBMDPath}\" --output \"{outDir}\""; - apicula.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - apicula.StartInfo.CreateNoWindow = true; - apicula.Start(); - apicula.WaitForExit(); - - if (File.Exists(tempNSBMDPath)) { - File.Delete(tempNSBMDPath); - - if (File.Exists(tempNSBMDPath)) { - MessageBox.Show("Temporary NSBMD file deletion failed.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - } else { - MessageBox.Show("Temporary NSBMD file corresponding to this map disappeared.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - - if (apicula.ExitCode == 0) { - MessageBox.Show("NSBMD was exported and converted successfully!", "Operation successful", MessageBoxButtons.OK, MessageBoxIcon.Information); - } else { - MessageBox.Show("NSBMD to DAE conversion failed.", "Apicula error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - public static void ModelToGLB(string modelName, byte[] modelData, byte[] textureData) { - MessageBox.Show("Choose output folder.\nDSPRE will automatically create a sub-folder in it.", "Awaiting user input", MessageBoxButtons.OK, MessageBoxIcon.Information); - - CommonOpenFileDialog cofd = new CommonOpenFileDialog { - IsFolderPicker = true, - Multiselect = false - }; - if (cofd.ShowDialog() != CommonFileDialogResult.Ok) { - return; - } - - string outDir = Path.Combine(cofd.FileName, modelName); - - if (Directory.Exists(outDir)) { - if (Directory.GetFiles(outDir).Length > 0) { - DialogResult d = MessageBox.Show($"Directory \"{outDir}\" already exists and is not empty.\nIts contents will be lost.\n\nDo you want to proceed?", "Directory not empty", MessageBoxButtons.YesNo, MessageBoxIcon.Question); - - if (d.Equals(DialogResult.No)) { - return; - } else { - Directory.Delete(outDir, recursive: true); - } - } else { - Directory.Delete(outDir, recursive: true); - } - } - string tempNSBMDPath = outDir + "_temp.nsbmd"; - - if (textureData != null && textureData.Length > 0) { - modelData = DSUtils.BuildNSBMDwithTextures(modelData, textureData); - } - - File.WriteAllBytes(tempNSBMDPath, modelData); - - /* Check correct creation of temp NSBMD file*/ - if (!File.Exists(tempNSBMDPath)) { - MessageBox.Show("NSBMD file corresponding to this map could not be found.\nAborting", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information); - return; - } - - Process apicula = new Process(); - apicula.StartInfo.FileName = @"Tools\apicula.exe"; - apicula.StartInfo.Arguments = $" convert \"{tempNSBMDPath}\" -f glb --output \"{outDir}\""; - apicula.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - apicula.StartInfo.CreateNoWindow = true; - apicula.Start(); - apicula.WaitForExit(); - - if (File.Exists(tempNSBMDPath)) { - File.Delete(tempNSBMDPath); - - if (File.Exists(tempNSBMDPath)) { - MessageBox.Show("Temporary NSBMD file deletion failed.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - } else { - MessageBox.Show("Temporary NSBMD file corresponding to this map disappeared.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); - } - - if (apicula.ExitCode == 0) { - MessageBox.Show("NSBMD was exported and converted successfully!", "Operation successful", MessageBoxButtons.OK, MessageBoxIcon.Information); - } else { - MessageBox.Show("NSBMD to GLB conversion failed.", "Apicula error", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - - public static void WriteToFile(string filepath, byte[] toOutput, uint writeAt = 0, int indexFirstByteToWrite = 0, int? indexLastByteToWrite = null, FileMode fmode = FileMode.OpenOrCreate) { - using (EasyWriter writer = new EasyWriter(filepath, writeAt, fmode)) { - writer.Write(toOutput, indexFirstByteToWrite, indexLastByteToWrite is null ? toOutput.Length - indexFirstByteToWrite : (int)indexLastByteToWrite); - } - } - public static byte[] ReadFromFile(string filepath, long startOffset = 0, long numberOfBytes = 0) { - byte[] buffer = null; - - using (EasyReader reader = new EasyReader(filepath, startOffset)) { - try { - buffer = reader.ReadBytes(numberOfBytes == 0 ? (int)(reader.BaseStream.Length - reader.BaseStream.Position) : (int)numberOfBytes); - } catch (EndOfStreamException) { - Console.WriteLine("Stream ended"); - } - } - - return buffer; - } - public static byte[] ReadFromByteArray(byte[] input, long readFrom = 0, long numberOfBytes = 0) { - byte[] buffer = null; - - using (BinaryReader reader = new BinaryReader(new MemoryStream(input))) { - reader.BaseStream.Position = readFrom; - - try { - if (numberOfBytes == 0) { - buffer = reader.ReadBytes((int)(input.Length - reader.BaseStream.Position)); - } else { - buffer = reader.ReadBytes((int)numberOfBytes); - } - } catch (EndOfStreamException) { - Console.WriteLine("Stream ended"); - } - } - return buffer; - } - public static int DecompressOverlay(int overlayNumber, bool makeBackup = true) { - string overlayFilePath = GetOverlayPath(overlayNumber); - - if (!File.Exists(overlayFilePath)) { - MessageBox.Show("Overlay to decompress #" + overlayNumber + " doesn't exist", - "Overlay not found", MessageBoxButtons.OK, MessageBoxIcon.Error); - return ERR_OVERLAY_NOTFOUND; - } - - if (makeBackup) { - if (File.Exists(overlayFilePath + backupSuffix)) { - File.Delete(overlayFilePath + backupSuffix); - } - File.Copy(overlayFilePath, overlayFilePath + backupSuffix); - } - - Process unpack = new Process(); - unpack.StartInfo.FileName = @"Tools\blz.exe"; - String arguments = "-d " + '"' + overlayFilePath + '"'; - unpack.StartInfo.Arguments = arguments; - Application.DoEvents(); - unpack.StartInfo.WindowStyle = ProcessWindowStyle.Normal; - unpack.StartInfo.CreateNoWindow = false; - unpack.Start(); - unpack.WaitForExit(); - return unpack.ExitCode; - } - public static int CompressOverlay(int overlayNumber) { - string overlayFilePath = GetOverlayPath(overlayNumber); - - if (!File.Exists(overlayFilePath)) { - MessageBox.Show("Overlay to decompress #" + overlayNumber + " doesn't exist", - "Overlay not found", MessageBoxButtons.OK, MessageBoxIcon.Error); - return ERR_OVERLAY_NOTFOUND; - } - - Process compress = new Process(); - compress.StartInfo.FileName = @"Tools\blz.exe"; - compress.StartInfo.Arguments = "-en " + '"' + overlayFilePath + '"'; - Application.DoEvents(); - compress.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - compress.StartInfo.CreateNoWindow = true; - compress.Start(); - compress.WaitForExit(); - return compress.ExitCode; - } - public static string GetOverlayPath(int overlayNumber) { - return RomInfo.workDir + "overlay" + "\\" + "overlay_" + overlayNumber.ToString("D4") + ".bin"; - } - public static void RestoreOverlayFromCompressedBackup(int overlayNumber, bool eventEditorIsReady) { - String overlayFilePath = GetOverlayPath(overlayNumber); - - if (File.Exists(overlayFilePath + backupSuffix)) { - if (new FileInfo(overlayFilePath).Length <= new FileInfo(overlayFilePath + backupSuffix).Length) { //if overlay is bigger than its backup - Console.WriteLine("Overlay " + overlayNumber + " is already compressed."); - return; - } else { - File.Delete(overlayFilePath); - File.Move(overlayFilePath + backupSuffix, overlayFilePath); - } - } else { - string msg = "Overlay File " + '"' + overlayFilePath + backupSuffix + '"' + " couldn't be found and restored."; - Console.WriteLine(msg); - - if (eventEditorIsReady) { - MessageBox.Show(msg, "Can't restore overlay from backup", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - } - } - - /** - * Only checks if the overlay is CONFIGURED as compressed - **/ - public static bool CheckOverlayHasCompressionFlag(int ovNumber) { - using (BinaryReader f = new BinaryReader(File.OpenRead(RomInfo.overlayTablePath))) { - f.BaseStream.Position = ovNumber * 32 + 31; //overlayNumber * size of entry + offset - return f.ReadByte() % 2 != 0; - } - } - - /** - * Checks the actual size of the overlay file - **/ - public static bool OverlayIsCompressed(int ovNumber) { - return (new FileInfo(GetOverlayPath(ovNumber)).Length < GetOverlayUncompressedSize(ovNumber)); - } - public static uint GetOverlayUncompressedSize(int ovNumber) { - using (BinaryReader f = new BinaryReader(File.OpenRead(RomInfo.overlayTablePath))) { - f.BaseStream.Position = ovNumber * 32 + 8; //overlayNumber * size of entry + offset - return f.ReadUInt32(); - } - } - public static uint GetOverlayRAMAddress(int ovNumber) { - using (BinaryReader f = new BinaryReader(File.OpenRead(RomInfo.overlayTablePath))) { - f.BaseStream.Position = ovNumber * 32 + 4; //overlayNumber * size of entry + offset - return f.ReadUInt32(); - } - } - public static void SetOverlayCompressionInTable(int ovNumber, byte compressStatus) { - if (compressStatus < 0 || compressStatus > 3) { - Console.WriteLine("Compression status " + compressStatus + " is invalid. No operation performed."); - return; - } - using (BinaryWriter f = new BinaryWriter(File.OpenWrite(RomInfo.overlayTablePath))) { - f.BaseStream.Position = ovNumber * 32 + 31; //overlayNumber * size of entry + offset - f.Write(compressStatus); - } - } - public static void RepackROM(string ndsFileName) { - Process repack = new Process(); - repack.StartInfo.FileName = @"Tools\ndstool.exe"; - repack.StartInfo.Arguments = "-c " + '"' + ndsFileName + '"' - + " -9 " + '"' + RomInfo.arm9Path + '"' - + " -7 " + '"' + RomInfo.workDir + "arm7.bin" + '"' - + " -y9 " + '"' + RomInfo.workDir + "y9.bin" + '"' - + " -y7 " + '"' + RomInfo.workDir + "y7.bin" + '"' - + " -d " + '"' + RomInfo.workDir + "data" + '"' - + " -y " + '"' + RomInfo.workDir + "overlay" + '"' - + " -t " + '"' + RomInfo.workDir + "banner.bin" + '"' - + " -h " + '"' + RomInfo.workDir + "header.bin" + '"'; - - Application.DoEvents(); - repack.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; - repack.StartInfo.CreateNoWindow = true; - repack.Start(); - repack.WaitForExit(); - } - - 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) { - Parallel.ForEach(IDs, id => { - if (!RomInfo.gameDirs.TryGetValue(id, out (string packedPath, string unpackedPath) paths)) { - return; - } - - DirectoryInfo di = new DirectoryInfo(paths.unpackedPath); - - if (di.Exists && di.GetFiles().Length != 0) { - return; - } - - Narc opened = Narc.Open(paths.packedPath); - - if (opened is null) { - throw new NullReferenceException(); - } - - opened.ExtractToFolder(paths.unpackedPath); - }); - } - - public static void ForceUnpackNarcs(List IDs) { - Parallel.ForEach(IDs, id => { - if (gameDirs.TryGetValue(id, out (string packedPath, string unpackedPath) paths)) { - Narc opened = Narc.Open(paths.packedPath); - - if (opened is null) { - throw new NullReferenceException(); - } - - opened.ExtractToFolder(paths.unpackedPath); - } - }); - } - - public static byte[] GetModelWithoutTextures(byte[] modelFile) { - byte[] nsbmdHeaderData; - uint mdl0Size; - byte[] mdl0Data; - - using (BinaryReader modelReader = new BinaryReader(new MemoryStream(modelFile))) { - modelReader.BaseStream.Position = 0x0; - nsbmdHeaderData = modelReader.ReadBytes(0x8); - - modelReader.BaseStream.Position = 0x1C; - mdl0Size = modelReader.ReadUInt32(); // Read mdl0 file size - - modelReader.BaseStream.Position = 0x18; - mdl0Data = modelReader.ReadBytes((int)mdl0Size); - } - - MemoryStream output = new MemoryStream(); - using (BinaryWriter writer = new BinaryWriter(output)) { - - writer.Write(nsbmdHeaderData); // Write first header bytes, same for all NSBMD. - writer.Write(mdl0Size + 0x14); - writer.Write((short)0x10); // Writes BMD0 header size (always 16) - writer.Write((short)0x1); // Write new number of sub-files, since embedded textures are removed - writer.Write((uint)0x14); // Writes new start offset of MDL0 - - writer.Write(mdl0Data); // Writes MDL0; - } - return output.ToArray(); - } - - public static byte[] GetTexturesFromTexturedNSBMD(byte[] modelFile) { - using (BinaryReader byteArrReader = new BinaryReader(new MemoryStream(modelFile))) { - byteArrReader.BaseStream.Position = 14; - if (byteArrReader.ReadUInt16() < 2) //No textures - return new byte[0]; - - byteArrReader.BaseStream.Position = 20; - int texAbsoluteOffset = byteArrReader.ReadInt32(); - - byteArrReader.BaseStream.Position = texAbsoluteOffset + 4; - uint textureSize = byteArrReader.ReadUInt32(); - - byte[] nsbtxHeader = DSUtils.BuildNSBTXHeader(20 + textureSize); - byte[] texData = DSUtils.ReadFromByteArray(modelFile, readFrom: texAbsoluteOffset); - - byte[] output = new byte[nsbtxHeader.Length + texData.Length]; - Buffer.BlockCopy(nsbtxHeader, 0, output, 0, nsbtxHeader.Length); - Buffer.BlockCopy(texData, 0, output, nsbtxHeader.Length, texData.Length); - return output; - } - } - public static int CheckNSBMDHeader(byte[] modelFile) { - using (BinaryReader byteArrReader = new BinaryReader(new MemoryStream(modelFile))) { - if (byteArrReader.ReadUInt32() != NSBMD.NDS_TYPE_BMD0) { - MessageBox.Show("Please select an NSBMD file.", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error); - return -1; - } - - byteArrReader.BaseStream.Position = 0xE; - 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); - - MemoryStream ms = new MemoryStream(); - using (BinaryWriter msWriter = new BinaryWriter(ms)) { - msWriter.Write(NSBMD.NDS_TYPE_BMD0); - msWriter.Write(NSBMD.NDS_TYPE_BYTEORDER); - msWriter.Write(NSBMD.NDS_TYPE_UNK2); - - ushort nBlocks = 2; - uint modelLength = (uint)(wholeMDL0.Length + NSBMD.HEADERSIZE + 4 * nBlocks); - msWriter.Write((uint)(modelLength + wholeTEX0.Length)); - msWriter.Write(NSBMD.HEADERSIZE); //Header size, always 16 - msWriter.Write(nBlocks); //Number of blocks, now it's 2 because we are inserting textures - - msWriter.Write((uint)(msWriter.BaseStream.Position + 4 * nBlocks)); //Absolute offset to model data. We are gonna have to write two offsets - - msWriter.Write(modelLength); //Copy offset to TEX0 - msWriter.Write(wholeMDL0); - msWriter.Write(wholeTEX0); - } - return ms.ToArray(); - } - private static byte[] GetFirstBlock(byte[] NSBFile) { - int blockSize; - uint offsetToMainBlock; - using (BinaryReader reader = new BinaryReader(new MemoryStream(NSBFile))) { - reader.BaseStream.Position = 16; - offsetToMainBlock = reader.ReadUInt32(); - - reader.BaseStream.Position = offsetToMainBlock + 4; - blockSize = reader.ReadInt32(); - } - byte[] blockData = new byte[blockSize]; - Buffer.BlockCopy(NSBFile, (int)offsetToMainBlock, blockData, 0, blockSize); - - return blockData; - } - - public static Image GetPokePic(int species, int w, int h) { - PaletteBase paletteBase; - bool fiveDigits = false; // some extreme future proofing - string filename = "0000"; - - try { - paletteBase = new NCLR(gameDirs[DirNames.monIcons].unpackedDir + "\\" + filename, 0, filename); - } catch (FileNotFoundException) { - filename += '0'; - paletteBase = new NCLR(gameDirs[DirNames.monIcons].unpackedDir + "\\" + filename, 0, filename); - fiveDigits = true; - } - - // read arm9 table to grab pal ID - int paletteId = 0; - string iconTablePath; - - int iconPalTableOffsetFromFileStart; - string ov129path = DSUtils.GetOverlayPath(129); - if (File.Exists(ov129path)) { - // if overlay 129 exists, read it from there - iconPalTableOffsetFromFileStart = (int)(RomInfo.monIconPalTableAddress - DSUtils.GetOverlayRAMAddress(129)); - iconTablePath = ov129path; - } else if ((int)(RomInfo.monIconPalTableAddress - RomInfo.synthOverlayLoadAddress) >= 0) { - // if there is a synthetic overlay, read it from there - iconPalTableOffsetFromFileStart = (int)(RomInfo.monIconPalTableAddress - RomInfo.synthOverlayLoadAddress); - iconTablePath = gameDirs[DirNames.synthOverlay].unpackedDir + "\\" + ROMToolboxDialog.expandedARMfileID.ToString("D4"); - } else { - // default handling - iconPalTableOffsetFromFileStart = (int)(RomInfo.monIconPalTableAddress - DSUtils.ARM9.address); - iconTablePath = RomInfo.arm9Path; - } - - using (DSUtils.EasyReader idReader = new DSUtils.EasyReader(iconTablePath, iconPalTableOffsetFromFileStart + species)) { - paletteId = idReader.ReadByte(); - } - - if (paletteId != 0) { - paletteBase.Palette[0] = paletteBase.Palette[paletteId]; // update pal 0 to be the new pal - } - - // grab tiles - int spriteFileID = species + 7; - string spriteFilename = spriteFileID.ToString("D" + (fiveDigits ? "5" : "4")); - ImageBase imageBase = new NCGR(gameDirs[DirNames.monIcons].unpackedDir + "\\" + spriteFilename, spriteFileID, spriteFilename); - - // grab sprite - int ncerFileId = 2; - string ncerFileName = ncerFileId.ToString("D" + (fiveDigits ? "5" : "4")); - SpriteBase spriteBase = new NCER(gameDirs[DirNames.monIcons].unpackedDir + "\\" + ncerFileName, 2, ncerFileName); - - // copy this from the trainer - int bank0OAMcount = spriteBase.Banks[0].oams.Length; - int[] OAMenabled = new int[bank0OAMcount]; - for (int i = 0; i < OAMenabled.Length; i++) { - OAMenabled[i] = i; - } - - // finally compose image - try { - return spriteBase.Get_Image(imageBase, paletteBase, 0, w, h, false, false, false, true, true, -1, OAMenabled); - } catch (FormatException) { - return Properties.Resources.IconPokeball; - } - } - } -} diff --git a/DS_Map/DSUtils/ARM9.cs b/DS_Map/DSUtils/ARM9.cs new file mode 100644 index 0000000..7590d2d --- /dev/null +++ b/DS_Map/DSUtils/ARM9.cs @@ -0,0 +1,62 @@ +using System; +using System.Diagnostics; +using System.IO; +using static DSPRE.RomInfo; + +namespace DSPRE { + public static class ARM9 { + private const int MAX_SIZE = 0xBC000; + public static readonly uint address = 0x02000000; + public class Reader : DSUtils.EasyReader { + public Reader(long pos = 0) : base(arm9Path, pos) { + this.BaseStream.Position = pos; + } + } + public class Writer : DSUtils.EasyWriter { + public Writer(long pos = 0) : base(arm9Path, pos) { + this.BaseStream.Position = pos; + } + } + public static void EditSize(int increment) { + using (Writer w = new Writer()) { + w.EditSize(increment); + } + } + public static bool Decompress(string path) { + Process decompress = DSUtils.CreateDecompressProcess(path); + decompress.Start(); + decompress.WaitForExit(); + + return new FileInfo(path).Length > MAX_SIZE; + } + + public static bool Compress(string path) { + Process compress = new Process(); + compress.StartInfo.FileName = @"Tools\blz.exe"; + compress.StartInfo.Arguments = @" -en9 " + '"' + path + '"'; + compress.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + compress.StartInfo.CreateNoWindow = true; + compress.Start(); + compress.WaitForExit(); + + return new FileInfo(path).Length <= MAX_SIZE; + } + public static bool CheckCompressionMark() { + return BitConverter.ToInt32(ReadBytes((uint)(RomInfo.gameFamily == gFamEnum.DP ? 0xB7C : 0xBB4), 4), 0) != 0; + } + + public static byte[] ReadBytes(uint startOffset, long numberOfBytes = 0) { + return DSUtils.ReadFromFile(RomInfo.arm9Path, startOffset, numberOfBytes); + } + public static void WriteBytes(byte[] bytesToWrite, uint destOffset, int indexFirstByteToWrite = 0, int? indexLastByteToWrite = null) { + DSUtils.WriteToFile(RomInfo.arm9Path, bytesToWrite, destOffset, indexFirstByteToWrite, indexLastByteToWrite); + } + + public static byte ReadByte(uint startOffset) { + return DSUtils.ReadFromFile(RomInfo.arm9Path, startOffset, 1)[0]; + } + public static void WriteByte(byte value, uint destOffset) { + DSUtils.WriteToFile(RomInfo.arm9Path, BitConverter.GetBytes(value), destOffset, 0); + } + } +} \ No newline at end of file diff --git a/DS_Map/DSUtils/DSUtils.cs b/DS_Map/DSUtils/DSUtils.cs new file mode 100644 index 0000000..7322932 --- /dev/null +++ b/DS_Map/DSUtils/DSUtils.cs @@ -0,0 +1,232 @@ +using Ekona.Images; +using Images; +using LibNDSFormats.NSBMD; +using Microsoft.WindowsAPICodePack.Dialogs; +using NarcAPI; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using static DSPRE.RomInfo; + +namespace DSPRE { + public static class DSUtils { + + public const int ERR_OVERLAY_NOTFOUND = -1; + public const int ERR_OVERLAY_ALREADY_UNCOMPRESSED = -2; + + public const string backupSuffix = ".backup"; + + public static readonly string NDSRomFilter = "NDS File (*.nds)|*.nds"; + public class EasyReader : BinaryReader { + public EasyReader(string path, long pos = 0) : base(File.OpenRead(path)) { + this.BaseStream.Position = pos; + } + } + public class EasyWriter : BinaryWriter { + public EasyWriter(string path, long pos = 0, FileMode fmode = FileMode.OpenOrCreate) : base(new FileStream(path, fmode, FileAccess.Write, FileShare.None)) { + this.BaseStream.Position = pos; + } + public void EditSize(int increment) { + this.BaseStream.SetLength(this.BaseStream.Length + increment); + } + } + + public static void WriteToFile(string filepath, byte[] toOutput, uint writeAt = 0, int indexFirstByteToWrite = 0, int? indexLastByteToWrite = null, FileMode fmode = FileMode.OpenOrCreate) { + using (EasyWriter writer = new EasyWriter(filepath, writeAt, fmode)) { + writer.Write(toOutput, indexFirstByteToWrite, indexLastByteToWrite is null ? toOutput.Length - indexFirstByteToWrite : (int)indexLastByteToWrite); + } + } + public static byte[] ReadFromFile(string filepath, long startOffset = 0, long numberOfBytes = 0) { + byte[] buffer = null; + + using (EasyReader reader = new EasyReader(filepath, startOffset)) { + try { + buffer = reader.ReadBytes(numberOfBytes == 0 ? (int)(reader.BaseStream.Length - reader.BaseStream.Position) : (int)numberOfBytes); + } catch (EndOfStreamException) { + Console.WriteLine("Stream ended"); + } + } + + return buffer; + } + public static byte[] ReadFromByteArray(byte[] input, long readFrom = 0, long numberOfBytes = 0) { + byte[] buffer = null; + + using (BinaryReader reader = new BinaryReader(new MemoryStream(input))) { + reader.BaseStream.Position = readFrom; + + try { + if (numberOfBytes == 0) { + buffer = reader.ReadBytes((int)(input.Length - reader.BaseStream.Position)); + } else { + buffer = reader.ReadBytes((int)numberOfBytes); + } + } catch (EndOfStreamException) { + Console.WriteLine("Stream ended"); + } + } + return buffer; + } + public static Process CreateDecompressProcess(string path) { + Process decompress = new Process(); + decompress.StartInfo.FileName = @"Tools\blz.exe"; + decompress.StartInfo.Arguments = @" -d " + '"' + path + '"'; + decompress.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + decompress.StartInfo.CreateNoWindow = true; + return decompress; + + } + + public static void RepackROM(string ndsFileName) { + Process repack = new Process(); + repack.StartInfo.FileName = @"Tools\ndstool.exe"; + repack.StartInfo.Arguments = "-c " + '"' + ndsFileName + '"' + + " -9 " + '"' + RomInfo.arm9Path + '"' + + " -7 " + '"' + RomInfo.workDir + "arm7.bin" + '"' + + " -y9 " + '"' + RomInfo.workDir + "y9.bin" + '"' + + " -y7 " + '"' + RomInfo.workDir + "y7.bin" + '"' + + " -d " + '"' + RomInfo.workDir + "data" + '"' + + " -y " + '"' + RomInfo.workDir + "overlay" + '"' + + " -t " + '"' + RomInfo.workDir + "banner.bin" + '"' + + " -h " + '"' + RomInfo.workDir + "header.bin" + '"'; + + Application.DoEvents(); + repack.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + repack.StartInfo.CreateNoWindow = true; + repack.Start(); + repack.WaitForExit(); + } + + 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) { + Parallel.ForEach(IDs, id => { + if (gameDirs.TryGetValue(id, out (string packedPath, string unpackedPath) paths)) { + DirectoryInfo di = new DirectoryInfo(paths.unpackedPath); + + if (!di.Exists || di.GetFiles().Length == 0) { + Narc opened = Narc.Open(paths.packedPath); + + if (opened is null) { + throw new NullReferenceException(); + } + + opened.ExtractToFolder(paths.unpackedPath); + } + } + }); + } + public static void ForceUnpackNarcs(List IDs) { + Parallel.ForEach(IDs, id => { + if (gameDirs.TryGetValue(id, out (string packedPath, string unpackedPath) paths)) { + Narc opened = Narc.Open(paths.packedPath); + + if (opened is null) { + throw new NullReferenceException(); + } + + opened.ExtractToFolder(paths.unpackedPath); + } + }); + } + + public static Image GetPokePic(int species, int w, int h) { + PaletteBase paletteBase; + bool fiveDigits = false; // some extreme future proofing + string filename = "0000"; + + try { + paletteBase = new NCLR(gameDirs[DirNames.monIcons].unpackedDir + "\\" + filename, 0, filename); + } catch (FileNotFoundException) { + filename += '0'; + paletteBase = new NCLR(gameDirs[DirNames.monIcons].unpackedDir + "\\" + filename, 0, filename); + fiveDigits = true; + } + + // read arm9 table to grab pal ID + int paletteId = 0; + string iconTablePath; + + int iconPalTableOffsetFromFileStart; + string ov129path = OverlayUtils.GetPath(129); + if (File.Exists(ov129path)) { + // if overlay 129 exists, read it from there + iconPalTableOffsetFromFileStart = (int)(RomInfo.monIconPalTableAddress - OverlayUtils.OverlayTable.GetRAMAddress(129)); + iconTablePath = ov129path; + } else if ((int)(RomInfo.monIconPalTableAddress - RomInfo.synthOverlayLoadAddress) >= 0) { + // if there is a synthetic overlay, read it from there + iconPalTableOffsetFromFileStart = (int)(RomInfo.monIconPalTableAddress - RomInfo.synthOverlayLoadAddress); + iconTablePath = gameDirs[DirNames.synthOverlay].unpackedDir + "\\" + PatchToolboxDialog.expandedARMfileID.ToString("D4"); + } else { + // default handling + iconPalTableOffsetFromFileStart = (int)(RomInfo.monIconPalTableAddress - ARM9.address); + iconTablePath = RomInfo.arm9Path; + } + + using (DSUtils.EasyReader idReader = new DSUtils.EasyReader(iconTablePath, iconPalTableOffsetFromFileStart + species)) { + paletteId = idReader.ReadByte(); + } + + if (paletteId != 0) { + paletteBase.Palette[0] = paletteBase.Palette[paletteId]; // update pal 0 to be the new pal + } + + // grab tiles + int spriteFileID = species + 7; + string spriteFilename = spriteFileID.ToString("D" + (fiveDigits ? "5" : "4")); + ImageBase imageBase = new NCGR(gameDirs[DirNames.monIcons].unpackedDir + "\\" + spriteFilename, spriteFileID, spriteFilename); + + // grab sprite + int ncerFileId = 2; + string ncerFileName = ncerFileId.ToString("D" + (fiveDigits ? "5" : "4")); + SpriteBase spriteBase = new NCER(gameDirs[DirNames.monIcons].unpackedDir + "\\" + ncerFileName, 2, ncerFileName); + + // copy this from the trainer + int bank0OAMcount = spriteBase.Banks[0].oams.Length; + int[] OAMenabled = new int[bank0OAMcount]; + for (int i = 0; i < OAMenabled.Length; i++) { + OAMenabled[i] = i; + } + + // finally compose image + try { + return spriteBase.Get_Image(imageBase, paletteBase, 0, w, h, false, false, false, true, true, -1, OAMenabled); + } catch (FormatException) { + return Properties.Resources.IconPokeball; + } + } + } +} \ No newline at end of file diff --git a/DS_Map/DSUtils/ModelUtils.cs b/DS_Map/DSUtils/ModelUtils.cs new file mode 100644 index 0000000..b9232bc --- /dev/null +++ b/DS_Map/DSUtils/ModelUtils.cs @@ -0,0 +1,139 @@ +using Microsoft.WindowsAPICodePack.Dialogs; +using System.Diagnostics; +using System.IO; +using System.Windows.Forms; + +namespace DSPRE { + public static class ModelUtils { + + public static void ModelToDAE(string modelName, byte[] modelData, byte[] textureData) { + MessageBox.Show("Choose output folder.\nDSPRE will automatically create a sub-folder in it.", "Awaiting user input", MessageBoxButtons.OK, MessageBoxIcon.Information); + + CommonOpenFileDialog cofd = new CommonOpenFileDialog { + IsFolderPicker = true, + Multiselect = false + }; + if (cofd.ShowDialog() != CommonFileDialogResult.Ok) { + return; + } + + string outDir = Path.Combine(cofd.FileName, modelName); + + if (Directory.Exists(outDir)) { + if (Directory.GetFiles(outDir).Length > 0) { + DialogResult d = MessageBox.Show($"Directory \"{outDir}\" already exists and is not empty.\nIts contents will be lost.\n\nDo you want to proceed?", "Directory not empty", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + + if (d.Equals(DialogResult.No)) { + return; + } else { + Directory.Delete(outDir, recursive: true); + } + } else { + Directory.Delete(outDir, recursive: true); + } + } + string tempNSBMDPath = outDir + "_temp.nsbmd"; + + if (textureData != null && textureData.Length > 0) { + modelData = NSBUtils.BuildNSBMDwithTextures(modelData, textureData); + } + + File.WriteAllBytes(tempNSBMDPath, modelData); + + /* Check correct creation of temp NSBMD file*/ + if (!File.Exists(tempNSBMDPath)) { + MessageBox.Show("Expected NSBMD file could not be found.\nAborting", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + Process apicula = new Process(); + apicula.StartInfo.FileName = @"Tools\apicula.exe"; + apicula.StartInfo.Arguments = $" convert \"{tempNSBMDPath}\" --output \"{outDir}\""; + apicula.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + apicula.StartInfo.CreateNoWindow = true; + apicula.Start(); + apicula.WaitForExit(); + + if (File.Exists(tempNSBMDPath)) { + File.Delete(tempNSBMDPath); + + if (File.Exists(tempNSBMDPath)) { + MessageBox.Show("Temporary NSBMD file deletion failed.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } else { + MessageBox.Show("Temporary NSBMD file corresponding to this map disappeared.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + + if (apicula.ExitCode == 0) { + MessageBox.Show("NSBMD was exported and converted successfully!", "Operation successful", MessageBoxButtons.OK, MessageBoxIcon.Information); + } else { + MessageBox.Show("NSBMD to DAE conversion failed.", "Apicula error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + public static void ModelToGLB(string modelName, byte[] modelData, byte[] textureData) { + MessageBox.Show("Choose output folder.\nDSPRE will automatically create a sub-folder in it.", "Awaiting user input", MessageBoxButtons.OK, MessageBoxIcon.Information); + + CommonOpenFileDialog cofd = new CommonOpenFileDialog { + IsFolderPicker = true, + Multiselect = false + }; + if (cofd.ShowDialog() != CommonFileDialogResult.Ok) { + return; + } + + string outDir = Path.Combine(cofd.FileName, modelName); + + if (Directory.Exists(outDir)) { + if (Directory.GetFiles(outDir).Length > 0) { + DialogResult d = MessageBox.Show($"Directory \"{outDir}\" already exists and is not empty.\nIts contents will be lost.\n\nDo you want to proceed?", "Directory not empty", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + + if (d.Equals(DialogResult.No)) { + return; + } else { + Directory.Delete(outDir, recursive: true); + } + } else { + Directory.Delete(outDir, recursive: true); + } + } + string tempNSBMDPath = outDir + "_temp.nsbmd"; + + if (textureData != null && textureData.Length > 0) { + modelData = NSBUtils.BuildNSBMDwithTextures(modelData, textureData); + } + + File.WriteAllBytes(tempNSBMDPath, modelData); + + /* Check correct creation of temp NSBMD file*/ + if (!File.Exists(tempNSBMDPath)) { + MessageBox.Show("NSBMD file corresponding to this map could not be found.\nAborting", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information); + return; + } + + Process apicula = new Process(); + apicula.StartInfo.FileName = @"Tools\apicula.exe"; + apicula.StartInfo.Arguments = $" convert \"{tempNSBMDPath}\" -f glb --output \"{outDir}\""; + apicula.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + apicula.StartInfo.CreateNoWindow = true; + apicula.Start(); + apicula.WaitForExit(); + + if (File.Exists(tempNSBMDPath)) { + File.Delete(tempNSBMDPath); + + if (File.Exists(tempNSBMDPath)) { + MessageBox.Show("Temporary NSBMD file deletion failed.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + } else { + MessageBox.Show("Temporary NSBMD file corresponding to this map disappeared.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + } + + if (apicula.ExitCode == 0) { + MessageBox.Show("NSBMD was exported and converted successfully!", "Operation successful", MessageBoxButtons.OK, MessageBoxIcon.Information); + } else { + MessageBox.Show("NSBMD to GLB conversion failed.", "Apicula error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } +} \ No newline at end of file diff --git a/DS_Map/DSUtils/NSBUtils.cs b/DS_Map/DSUtils/NSBUtils.cs new file mode 100644 index 0000000..3026d8e --- /dev/null +++ b/DS_Map/DSUtils/NSBUtils.cs @@ -0,0 +1,142 @@ +using LibNDSFormats.NSBMD; +using System; +using System.IO; +using System.Text; +using System.Windows.Forms; + +namespace DSPRE { + public static class NSBUtils { + public const int NSBMD_DOESNTHAVE_TEXTURE = 0; + public const int NSBMD_HAS_TEXTURE = 1; + + public static string ReadNSBMDname(BinaryReader reader, long? startPos = null) { + if (startPos != null) { + reader.BaseStream.Position = (long)startPos; + } + + if (reader.ReadUInt32() == NSBMD.NDS_TYPE_MDL0) { //MDL0 + reader.BaseStream.Position += 0x1c; + } else { + reader.BaseStream.Position += 0x1c + 4; + } + + return Encoding.UTF8.GetString(reader.ReadBytes(16)); + } + public static byte[] BuildNSBMDwithTextures(byte[] nsbmd, byte[] nsbtx) { + byte[] wholeMDL0 = GetFirstBlock(nsbmd); + byte[] wholeTEX0 = GetFirstBlock(nsbtx); + + MemoryStream ms = new MemoryStream(); + using (BinaryWriter msWriter = new BinaryWriter(ms)) { + msWriter.Write(NSBMD.NDS_TYPE_BMD0); + msWriter.Write(NSBMD.NDS_TYPE_BYTEORDER); + msWriter.Write(NSBMD.NDS_TYPE_UNK2); + + ushort nBlocks = 2; + uint modelLength = (uint)(wholeMDL0.Length + NSBMD.HEADERSIZE + 4 * nBlocks); + msWriter.Write((uint)(modelLength + wholeTEX0.Length)); + msWriter.Write(NSBMD.HEADERSIZE); //Header size, always 16 + msWriter.Write(nBlocks); //Number of blocks, now it's 2 because we are inserting textures + + msWriter.Write((uint)(msWriter.BaseStream.Position + 4 * nBlocks)); //Absolute offset to model data. We are gonna have to write two offsets + + msWriter.Write(modelLength); //Copy offset to TEX0 + msWriter.Write(wholeMDL0); + msWriter.Write(wholeTEX0); + } + return ms.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 int CheckNSBMDHeader(byte[] modelFile) { + using (BinaryReader byteArrReader = new BinaryReader(new MemoryStream(modelFile))) { + if (byteArrReader.ReadUInt32() != NSBMD.NDS_TYPE_BMD0) { + MessageBox.Show("Please select an NSBMD file.", "Invalid File", MessageBoxButtons.OK, MessageBoxIcon.Error); + return -1; + } + + byteArrReader.BaseStream.Position = 0xE; + return byteArrReader.ReadInt16() >= 2 ? NSBMD_HAS_TEXTURE : NSBMD_DOESNTHAVE_TEXTURE; + } + } + + public static byte[] GetModelWithoutTextures(byte[] modelFile) { + byte[] nsbmdHeaderData; + uint mdl0Size; + byte[] mdl0Data; + + using (BinaryReader modelReader = new BinaryReader(new MemoryStream(modelFile))) { + modelReader.BaseStream.Position = 0x0; + nsbmdHeaderData = modelReader.ReadBytes(0x8); + + modelReader.BaseStream.Position = 0x1C; + mdl0Size = modelReader.ReadUInt32(); // Read mdl0 file size + + modelReader.BaseStream.Position = 0x18; + mdl0Data = modelReader.ReadBytes((int)mdl0Size); + } + + MemoryStream output = new MemoryStream(); + using (BinaryWriter writer = new BinaryWriter(output)) { + + writer.Write(nsbmdHeaderData); // Write first header bytes, same for all NSBMD. + writer.Write(mdl0Size + 0x14); + writer.Write((short)0x10); // Writes BMD0 header size (always 16) + writer.Write((short)0x1); // Write new number of sub-files, since embedded textures are removed + writer.Write((uint)0x14); // Writes new start offset of MDL0 + + writer.Write(mdl0Data); // Writes MDL0; + } + return output.ToArray(); + } + + public static byte[] GetTexturesFromTexturedNSBMD(byte[] modelFile) { + using (BinaryReader byteArrReader = new BinaryReader(new MemoryStream(modelFile))) { + byteArrReader.BaseStream.Position = 14; + if (byteArrReader.ReadUInt16() < 2) //No textures + return new byte[0]; + + byteArrReader.BaseStream.Position = 20; + int texAbsoluteOffset = byteArrReader.ReadInt32(); + + byteArrReader.BaseStream.Position = texAbsoluteOffset + 4; + uint textureSize = byteArrReader.ReadUInt32(); + + byte[] nsbtxHeader = NSBUtils.BuildNSBTXHeader(20 + textureSize); + byte[] texData = DSUtils.ReadFromByteArray(modelFile, readFrom: texAbsoluteOffset); + + byte[] output = new byte[nsbtxHeader.Length + texData.Length]; + Buffer.BlockCopy(nsbtxHeader, 0, output, 0, nsbtxHeader.Length); + Buffer.BlockCopy(texData, 0, output, nsbtxHeader.Length, texData.Length); + return output; + } + } + private static byte[] GetFirstBlock(byte[] NSBFile) { + int blockSize; + uint offsetToMainBlock; + using (BinaryReader reader = new BinaryReader(new MemoryStream(NSBFile))) { + reader.BaseStream.Position = 16; + offsetToMainBlock = reader.ReadUInt32(); + + reader.BaseStream.Position = offsetToMainBlock + 4; + blockSize = reader.ReadInt32(); + } + byte[] blockData = new byte[blockSize]; + Buffer.BlockCopy(NSBFile, (int)offsetToMainBlock, blockData, 0, blockSize); + + return blockData; + } + } +} \ No newline at end of file diff --git a/DS_Map/DSUtils/OverlayUtils.cs b/DS_Map/DSUtils/OverlayUtils.cs new file mode 100644 index 0000000..0ad2b11 --- /dev/null +++ b/DS_Map/DSUtils/OverlayUtils.cs @@ -0,0 +1,123 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Windows.Forms; +using static DSPRE.DSUtils; +using static DSPRE.RomInfo; + +namespace DSPRE { + public static class OverlayUtils { + public static class OverlayTable { + private const int ENTRY_LEN = 32; + + /** + * Only checks if the overlay is CONFIGURED as compressed + **/ + public static bool IsDefaultCompressed(int ovNumber) { + using (DSUtils.EasyReader f = new EasyReader(RomInfo.overlayTablePath, ovNumber * ENTRY_LEN + 31)) { + return (f.ReadByte() & 1) == 1; + } + } + public static void SetDefaultCompressed(int ovNumber, bool compressStatus) { + DSUtils.WriteToFile(RomInfo.overlayTablePath, new byte[] { compressStatus ? (byte)1 : (byte)0 }, (uint)(ovNumber * ENTRY_LEN + 31)); //overlayNumber * size of entry + offset + } + + public static uint GetRAMAddress(int ovNumber) { + using (DSUtils.EasyReader f = new EasyReader(RomInfo.overlayTablePath, ovNumber * ENTRY_LEN + 4)) { + return f.ReadUInt32(); + } + } + public static uint GetUncompressedSize(int ovNumber) { + using (DSUtils.EasyReader f = new EasyReader(RomInfo.overlayTablePath, ovNumber * ENTRY_LEN + 8)) { + return f.ReadUInt32(); + } + } + } + + + public static string GetPath(int overlayNumber) { + return $"{workDir}overlay\\overlay_{overlayNumber:D4}.bin"; + } + + /** + * Checks the actual size of the overlay file + **/ + public static bool IsCompressed(int ovNumber) { + return (new FileInfo(GetPath(ovNumber)).Length < OverlayTable.GetUncompressedSize(ovNumber)); + } + + /** + * Gets number of overlays + **/ + public static long GetNumberOfOverlays() { + using (FileStream fileStream = File.OpenRead(RomInfo.overlayTablePath)) { + // Get the length of the file in bytes + return fileStream.Length / 32; + } + } + + public static void RestoreFromCompressedBackup(int overlayNumber, bool eventEditorIsReady) { + String overlayFilePath = GetPath(overlayNumber); + + if (File.Exists(overlayFilePath + DSUtils.backupSuffix)) { + if (new FileInfo(overlayFilePath).Length <= new FileInfo(overlayFilePath + DSUtils.backupSuffix).Length) { //if overlay is bigger than its backup + Console.WriteLine($"Overlay {overlayNumber} is already compressed."); + return; + } else { + File.Delete(overlayFilePath); + File.Move(overlayFilePath + DSUtils.backupSuffix, overlayFilePath); + } + } else { + string msg = $"Overlay File {overlayFilePath}{DSUtils.backupSuffix} couldn't be found and restored."; + Console.WriteLine(msg); + + if (eventEditorIsReady) { + MessageBox.Show(msg, "Can't restore overlay from backup", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } + public static int Compress(int overlayNumber) { + string overlayFilePath = GetPath(overlayNumber); + + if (!File.Exists(overlayFilePath)) { + MessageBox.Show("Overlay to decompress #" + overlayNumber + " doesn't exist", + "Overlay not found", MessageBoxButtons.OK, MessageBoxIcon.Error); + return ERR_OVERLAY_NOTFOUND; + } + + Process compress = new Process(); + compress.StartInfo.FileName = @"Tools\blz.exe"; + compress.StartInfo.Arguments = "-en " + '"' + overlayFilePath + '"'; + Application.DoEvents(); + compress.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + compress.StartInfo.CreateNoWindow = true; + compress.Start(); + compress.WaitForExit(); + return compress.ExitCode; + } + + public static int Decompress(string overlayFilePath, bool makeBackup = true) { + if (!File.Exists(overlayFilePath)) { + MessageBox.Show($"File to decompress \"{overlayFilePath}\" doesn't exist", + "Overlay not found", MessageBoxButtons.OK, MessageBoxIcon.Error); + return ERR_OVERLAY_NOTFOUND; + } + + if (makeBackup) { + if (File.Exists(overlayFilePath + backupSuffix)) { + File.Delete(overlayFilePath + backupSuffix); + } + File.Copy(overlayFilePath, overlayFilePath + backupSuffix); + } + + Process decompress = DSUtils.CreateDecompressProcess(overlayFilePath); + decompress.Start(); + decompress.WaitForExit(); + return decompress.ExitCode; + } + public static int Decompress(int overlayNumber, bool makeBackup = true) { + return Decompress(GetPath(overlayNumber), makeBackup); + } + + } +} \ No newline at end of file diff --git a/DS_Map/Filesystem.cs b/DS_Map/Filesystem.cs index 3d503ab..53db149 100644 --- a/DS_Map/Filesystem.cs +++ b/DS_Map/Filesystem.cs @@ -33,7 +33,7 @@ namespace DSPRE { } } - public static string expArmPath { get { return Path.Combine(synthOverlay, ROMToolboxDialog.expandedARMfileID.ToString("D4")); } } + public static string expArmPath { get { return Path.Combine(synthOverlay, PatchToolboxDialog.expandedARMfileID.ToString("D4")); } } public static string GetPath(string path, int id, string format = "D4") { return Path.Combine(path, id.ToString(format)); diff --git a/DS_Map/HeaderSearch.cs b/DS_Map/HeaderSearch.cs index ae4d32a..e913965 100644 --- a/DS_Map/HeaderSearch.cs +++ b/DS_Map/HeaderSearch.cs @@ -180,7 +180,7 @@ namespace DSPRE { for (ushort i = startID; i < finalID; i++) { MapHeader h; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { h = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + i.ToString("D4"), i, 0); } else { h = MapHeader.LoadFromARM9(i); diff --git a/DS_Map/Helpers.cs b/DS_Map/Helpers.cs index 13fa6d0..911cdf9 100644 --- a/DS_Map/Helpers.cs +++ b/DS_Map/Helpers.cs @@ -256,14 +256,14 @@ namespace DSPRE { switch (RomInfo.gameFamily) { case RomInfo.GameFamilies.DP: - iconPalTableBuf = DSUtils.ARM9.ReadBytes(0x6B838, 4); + iconPalTableBuf = ARM9.ReadBytes(0x6B838, 4); break; case RomInfo.GameFamilies.Plat: - iconPalTableBuf = DSUtils.ARM9.ReadBytes(0x79F80, 4); + iconPalTableBuf = ARM9.ReadBytes(0x79F80, 4); break; case RomInfo.GameFamilies.HGSS: default: - iconPalTableBuf = DSUtils.ARM9.ReadBytes(0x74408, 4); + iconPalTableBuf = ARM9.ReadBytes(0x74408, 4); break; } diff --git a/DS_Map/Main Window.cs b/DS_Map/Main Window.cs index 1fc2c45..ee02185 100644 --- a/DS_Map/Main Window.cs +++ b/DS_Map/Main Window.cs @@ -315,13 +315,13 @@ namespace DSPRE { } private void romToolBoxToolStripMenuItem_Click(object sender, EventArgs e) { - using (ROMToolboxDialog window = new ROMToolboxDialog()) { + using (PatchToolboxDialog window = new PatchToolboxDialog()) { window.ShowDialog(); - if (ROMToolboxDialog.flag_standardizedItems && eventEditorIsReady) { + if (PatchToolboxDialog.flag_standardizedItems && eventEditorIsReady) { selectEventComboBox_SelectedIndexChanged(null, null); UpdateItemComboBox(RomInfo.GetItemNames()); } - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied) { addHeaderBTN.Enabled = true; removeLastHeaderBTN.Enabled = true; } @@ -576,7 +576,7 @@ namespace DSPRE { versionLabel.Text = "Error"; return; } - DSUtils.ARM9.EditSize(-12); + ARM9.EditSize(-12); } catch (IOException) { MessageBox.Show("Can't access temp directory: \n" + RomInfo.workDir + "\nThis might be a temporary issue.\nMake sure no other process is using it and try again.", "Open Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Helpers.statusLabelError("ERROR: Concurrent access to " + RomInfo.workDir); @@ -591,8 +591,8 @@ namespace DSPRE { Helpers.statusLabelMessage("Attempting to unpack NARCs from folder..."); Update(); //for (int i = 0; i < 128; i++) { - // if (DSUtils.OverlayIsCompressed(i)) { - // DSUtils.DecompressOverlay(i); + // if (OverlayUtils.IsCompressed(i)) { + // OverlayUtils.Decompress(i); // } //} ReadROMInitData(); @@ -653,11 +653,11 @@ namespace DSPRE { } private void ReadROMInitData() { - if (DSUtils.ARM9.CheckCompressionMark()) { + if (ARM9.CheckCompressionMark()) { if (!RomInfo.gameFamily.Equals(GameFamilies.HGSS)) { MessageBox.Show("Unexpected compressed ARM9. It is advised that you double check the ARM9."); } - if (!DSUtils.ARM9.Decompress(RomInfo.arm9Path)) { + if (!ARM9.Decompress(RomInfo.arm9Path)) { MessageBox.Show("ARM9 decompression failed. The program can't proceed.\nAborting.", "Error with ARM9 decompression", MessageBoxButtons.OK, MessageBoxIcon.Error); return; @@ -719,7 +719,7 @@ namespace DSPRE { } - if (DSUtils.ARM9.CheckCompressionMark()) { + if (ARM9.CheckCompressionMark()) { Helpers.statusLabelMessage("Awaiting user response..."); DialogResult d = MessageBox.Show("The ARM9 file of this ROM is currently uncompressed, but marked as compressed.\n" + "This will prevent your ROM from working on native hardware.\n\n" + @@ -727,26 +727,26 @@ namespace DSPRE { MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (d == DialogResult.Yes) { - DSUtils.ARM9.WriteBytes(new byte[4] { 0, 0, 0, 0 }, (uint)(RomInfo.gameFamily == GameFamilies.DP ? 0xB7C : 0xBB4)); + ARM9.WriteBytes(new byte[4] { 0, 0, 0, 0 }, (uint)(RomInfo.gameFamily == GameFamilies.DP ? 0xB7C : 0xBB4)); } } - DSUtils.ARM9.WriteBytes(new byte[4] { 0, 0, 0, 0 }, (uint)(RomInfo.gameFamily == GameFamilies.DP ? 0xB7C : 0xBB4)); + ARM9.WriteBytes(new byte[4] { 0, 0, 0, 0 }, (uint)(RomInfo.gameFamily == GameFamilies.DP ? 0xB7C : 0xBB4)); Helpers.statusLabelMessage("Repacking ROM..."); - if (DSUtils.CheckOverlayHasCompressionFlag(1)) { - if (ROMToolboxDialog.overlay1MustBeRestoredFromBackup) { + if (OverlayUtils.OverlayTable.IsDefaultCompressed(1)) { + if (PatchToolboxDialog.overlay1MustBeRestoredFromBackup) { DSUtils.RestoreOverlayFromCompressedBackup(1, eventEditorIsReady); } else { - if (!DSUtils.OverlayIsCompressed(1)) { + if (!OverlayUtils.IsCompressed(1)) { DSUtils.CompressOverlay(1); } } } - if (DSUtils.CheckOverlayHasCompressionFlag(RomInfo.initialMoneyOverlayNumber)) { - if (!DSUtils.OverlayIsCompressed(RomInfo.initialMoneyOverlayNumber)) { + if (OverlayUtils.OverlayTable.IsDefaultCompressed(RomInfo.initialMoneyOverlayNumber)) { + if (!OverlayUtils.IsCompressed(RomInfo.initialMoneyOverlayNumber)) { DSUtils.CompressOverlay(RomInfo.initialMoneyOverlayNumber); } } @@ -755,7 +755,7 @@ namespace DSPRE { Update(); //for (int i = 0; i < 128; i++) { - // if (!DSUtils.OverlayIsCompressed(i)) { + // if (!OverlayUtils.IsCompressed(i)) { // DSUtils.CompressOverlay(i); // } //} @@ -764,8 +764,8 @@ namespace DSPRE { if (RomInfo.gameFamily != GameFamilies.DP && RomInfo.gameFamily != GameFamilies.Plat) { if (eventEditorIsReady) { - if (DSUtils.OverlayIsCompressed(1)) { - DSUtils.DecompressOverlay(1); + if (OverlayUtils.IsCompressed(1)) { + OverlayUtils.Decompress(1); } } } @@ -972,7 +972,7 @@ namespace DSPRE { internalNames = new List(); headerListBoxNames = new List(); int headerCount; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { addHeaderBTN.Enabled = true; removeLastHeaderBTN.Enabled = true; headerCount = Directory.GetFiles(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir).Length; @@ -993,7 +993,7 @@ namespace DSPRE { } // Creating a dictionary linking events to headers to fetch header data for Event Editor - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { for (ushort i = 0; i < internalNames.Count; i++) { MapHeader h = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + i.ToString("D4"), i, 0); eventToHeader[h.eventFileID] = i; @@ -1232,7 +1232,7 @@ namespace DSPRE { } /* Check if dynamic headers patch has been applied, and load header from arm9 or a/0/5/0 accordingly */ - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { currentHeader = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + headerNumber.ToString("D4"), headerNumber, 0); } else { currentHeader = MapHeader.LoadFromARM9(headerNumber); @@ -1698,11 +1698,11 @@ 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 */ - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { DSUtils.WriteToFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + currentHeader.ID.ToString("D4"), currentHeader.ToByteArray(), 0, 0, fmode: FileMode.Create); } else { uint headerOffset = (uint)(RomInfo.headerTableOffset + MapHeader.length * currentHeader.ID); - DSUtils.ARM9.WriteBytes(currentHeader.ToByteArray(), headerOffset); + ARM9.WriteBytes(currentHeader.ToByteArray(), headerOffset); } Helpers.DisableHandlers(); @@ -1767,7 +1767,7 @@ namespace DSPRE { /* Check if dynamic headers patch has been applied, and load header from arm9 or a/0/5/0 accordingly */ for (ushort i = 0; i < internalNames.Count; i++) { MapHeader h; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { h = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + i.ToString("D4"), i, 0); } else { h = MapHeader.LoadFromARM9(i); @@ -1937,11 +1937,11 @@ namespace DSPRE { currentHeader = h; /* Check if dynamic headers patch has been applied, and save header to arm9 or a/0/5/0 accordingly */ - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { DSUtils.WriteToFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + currentHeader.ID.ToString("D4"), currentHeader.ToByteArray(), 0, 0, fmode: FileMode.Create); } else { uint headerOffset = (uint)(RomInfo.headerTableOffset + MapHeader.length * currentHeader.ID); - DSUtils.ARM9.WriteBytes(currentHeader.ToByteArray(), headerOffset); + ARM9.WriteBytes(currentHeader.ToByteArray(), headerOffset); } try { @@ -2651,7 +2651,7 @@ namespace DSPRE { } else if (gameFamily.Equals(GameFamilies.Plat)) { foreach (ushort r in result) { HeaderPt hpt; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { hpt = (HeaderPt)MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + r.ToString("D4"), r, 0); } else { hpt = (HeaderPt)MapHeader.LoadFromARM9(r); @@ -2665,7 +2665,7 @@ namespace DSPRE { } else { foreach (ushort r in result) { HeaderHGSS hgss; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { hgss = (HeaderHGSS)MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + r.ToString("D4"), r, 0); } else { hgss = (HeaderHGSS)MapHeader.LoadFromARM9(r); @@ -2696,7 +2696,7 @@ namespace DSPRE { /* get texture file numbers from area data */ MapHeader h; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { h = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + headerID.ToString("D4"), headerID, 0); } else { h = MapHeader.LoadFromARM9(headerID); @@ -4905,7 +4905,7 @@ namespace DSPRE { foreach (ushort headerID in result) { HeaderPt hpt; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { hpt = (HeaderPt)MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + headerID.ToString("D4"), headerID, 0); } else { hpt = (HeaderPt)MapHeader.LoadFromARM9(headerID); @@ -5099,7 +5099,7 @@ namespace DSPRE { if (eventMatrix.hasHeadersSection && readGraphicsFromHeader) { ushort headerID = (ushort)eventMatrix.headers[(short)eventMatrixYUpDown.Value, (short)eventMatrixXUpDown.Value]; MapHeader h; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { h = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + headerID.ToString("D4"), headerID, 0); } else { h = MapHeader.LoadFromARM9(headerID); @@ -5356,9 +5356,9 @@ namespace DSPRE { break; default: // HGSS Overlay 1 must be decompressed in order to read the overworld table - if (DSUtils.CheckOverlayHasCompressionFlag(1)) { - if (DSUtils.OverlayIsCompressed(1)) { - if (DSUtils.DecompressOverlay(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.", "Unexpected EOF", MessageBoxButtons.OK, MessageBoxIcon.Error); } @@ -5405,7 +5405,7 @@ namespace DSPRE { /* Add item list to ow item box */ string[] itemNames = RomInfo.GetItemNames(); - if (ROMToolboxDialog.CheckScriptsStandardizedItemNumbers()) { + if (PatchToolboxDialog.CheckScriptsStandardizedItemNumbers()) { UpdateItemComboBox(itemNames); } else { ScriptFile itemScript = new ScriptFile(RomInfo.itemScriptFileNumber); @@ -5668,7 +5668,7 @@ namespace DSPRE { if (eventToHeader.TryGetValue((ushort)selectEventComboBox.SelectedIndex, out ushort mapHeader)) { MapHeader h; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { h = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + mapHeader.ToString("D4"), mapHeader, 0); } else { h = MapHeader.LoadFromARM9(mapHeader); @@ -6414,7 +6414,7 @@ namespace DSPRE { ushort destHeaderID = (ushort)eventEditorWarpHeaderListBox.SelectedIndex; MapHeader destHeader; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { destHeader = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + destHeaderID.ToString("D4"), destHeaderID, 0); } else { destHeader = MapHeader.LoadFromARM9(destHeaderID); @@ -6558,7 +6558,7 @@ namespace DSPRE { ushort destHeaderID = (ushort)eventEditorWarpHeaderListBox.SelectedIndex; MapHeader destHeader; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { destHeader = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + destHeaderID.ToString("D4"), destHeaderID, 0); } else { destHeader = MapHeader.LoadFromARM9(destHeaderID); @@ -7580,12 +7580,12 @@ namespace DSPRE { RomInfo.PrepareCameraData(); cameraEditorDataGridView.Rows.Clear(); - if (DSUtils.CheckOverlayHasCompressionFlag(RomInfo.cameraTblOverlayNumber)) { + if (OverlayUtils.OverlayTable.IsDefaultCompressed(RomInfo.cameraTblOverlayNumber)) { 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); - bool userConfirmed = (d1 == DialogResult.Yes && ROMToolboxDialog.ConfigureOverlay1Uncompressed()); + bool userConfirmed = (d1 == DialogResult.Yes && PatchToolboxDialog.ConfigureOverlay1Uncompressed()); if (!userConfirmed) { @@ -7593,15 +7593,15 @@ namespace DSPRE { "If you change your mind, you can apply it later by accessing the ROM Toolbox.", "Caution", MessageBoxButtons.OK, MessageBoxIcon.Information); - if (DSUtils.OverlayIsCompressed(RomInfo.cameraTblOverlayNumber)) { - DSUtils.DecompressOverlay(RomInfo.cameraTblOverlayNumber); + if (OverlayUtils.IsCompressed(RomInfo.cameraTblOverlayNumber)) { + OverlayUtils.Decompress(RomInfo.cameraTblOverlayNumber); } } } uint[] RAMaddresses = new uint[RomInfo.cameraTblOffsetsToRAMaddress.Length]; - string camOverlayPath = DSUtils.GetOverlayPath(RomInfo.cameraTblOverlayNumber); + string camOverlayPath = OverlayUtils.GetPath(RomInfo.cameraTblOverlayNumber); using (DSUtils.EasyReader br = new DSUtils.EasyReader(camOverlayPath)) { for (int i = 0; i < RomInfo.cameraTblOffsetsToRAMaddress.Length; i++) { br.BaseStream.Position = RomInfo.cameraTblOffsetsToRAMaddress[i]; @@ -7648,7 +7648,7 @@ namespace DSPRE { } } private void saveCameraTableButton_Click(object sender, EventArgs e) { - SaveCameraTable(DSUtils.GetOverlayPath(RomInfo.cameraTblOverlayNumber), overlayCameraTblOffset); + SaveCameraTable(OverlayUtils.GetPath(RomInfo.cameraTblOverlayNumber), overlayCameraTblOffset); } private void cameraEditorDataGridView_CellValidated(object sender, DataGridViewCellEventArgs e) { currentCameraTable[e.RowIndex][e.ColumnIndex] = cameraEditorDataGridView.Rows[e.RowIndex].Cells[e.ColumnIndex].Value; @@ -7766,7 +7766,7 @@ namespace DSPRE { RomInfo.SetEncounterMusicTableOffsetToRAMAddress(); trainerClassEncounterMusicDict = new Dictionary(); - uint encounterMusicTableTableStartAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(RomInfo.encounterMusicTableOffsetToRAMAddress, 4), 0) - DSUtils.ARM9.address; + uint encounterMusicTableTableStartAddress = BitConverter.ToUInt32(ARM9.ReadBytes(RomInfo.encounterMusicTableOffsetToRAMAddress, 4), 0) - ARM9.address; uint entrySize = 4; uint tableSizeOffset = 10; @@ -7776,8 +7776,8 @@ namespace DSPRE { encounterSSEQAltUpDown.Enabled = true; } - byte tableEntriesCount = DSUtils.ARM9.ReadByte(RomInfo.encounterMusicTableOffsetToRAMAddress - tableSizeOffset); - using (DSUtils.ARM9.Reader ar = new DSUtils.ARM9.Reader(encounterMusicTableTableStartAddress)) { + byte tableEntriesCount = ARM9.ReadByte(RomInfo.encounterMusicTableOffsetToRAMAddress - tableSizeOffset); + using (ARM9.Reader ar = new ARM9.Reader(encounterMusicTableTableStartAddress)) { for (int i = 0; i < tableEntriesCount; i++) { uint entryOffset = (uint)ar.BaseStream.Position; byte tclass = (byte)ar.ReadUInt16(); @@ -8311,7 +8311,7 @@ namespace DSPRE { //Expose a smaller limit to the user if (RomInfo.trainerNameLenOffset >= 0) { MessageBox.Show($"Trainer File saved successfully. However:\nYou attempted to save a Trainer whose name exceeds {RomInfo.trainerNameMaxLen-1} characters.\nThis may lead to issues in game." + - (ROMToolboxDialog.flag_TrainerNamesExpanded ? "\n\nIt's recommended that you use a shorter name." : "\n\nRefer to the ROM Toolbox to extend Trainer names."), + (PatchToolboxDialog.flag_TrainerNamesExpanded ? "\n\nIt's recommended that you use a shorter name." : "\n\nRefer to the ROM Toolbox to extend Trainer names."), "Saved successfully, but...", MessageBoxButtons.OK, MessageBoxIcon.Warning); } else { MessageBox.Show($"Trainer File saved successfully. However:\nThe Trainer name length could not be safely determined for this ROM.\n" + @@ -8538,7 +8538,7 @@ namespace DSPRE { ushort eyeMusicID = (ushort)encounterSSEQMainUpDown.Value; if (trainerClassEncounterMusicDict.TryGetValue(b_selectedTrClass, out var dictEntry)) { - DSUtils.ARM9.WriteBytes(BitConverter.GetBytes(eyeMusicID), dictEntry.entryOffset); + ARM9.WriteBytes(BitConverter.GetBytes(eyeMusicID), dictEntry.entryOffset); trainerClassEncounterMusicDict[b_selectedTrClass] = (dictEntry.entryOffset, eyeMusicID, dictEntry.musicN); } @@ -8735,11 +8735,11 @@ namespace DSPRE { RomInfo.SetConditionalMusicTableOffsetToRAMAddress(); conditionalMusicTable = new List<(ushort, ushort, ushort)>(); - conditionalMusicTableStartAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(RomInfo.conditionalMusicTableOffsetToRAMAddress, 4), 0) - DSUtils.ARM9.address; - byte tableEntriesCount = DSUtils.ARM9.ReadByte(RomInfo.conditionalMusicTableOffsetToRAMAddress - 8); + conditionalMusicTableStartAddress = BitConverter.ToUInt32(ARM9.ReadBytes(RomInfo.conditionalMusicTableOffsetToRAMAddress, 4), 0) - ARM9.address; + byte tableEntriesCount = ARM9.ReadByte(RomInfo.conditionalMusicTableOffsetToRAMAddress - 8); conditionalMusicTableListBox.Items.Clear(); - using (DSUtils.ARM9.Reader ar = new DSUtils.ARM9.Reader(conditionalMusicTableStartAddress)) { + using (ARM9.Reader ar = new ARM9.Reader(conditionalMusicTableStartAddress)) { for (int i = 0; i < tableEntriesCount; i++) { ushort header = ar.ReadUInt16(); ushort flag = ar.ReadUInt16(); @@ -8786,25 +8786,25 @@ namespace DSPRE { effectsComboTable = new List<(ushort vsGraph, ushort battleSSEQ)>(); - effectsComboMainTableStartAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(RomInfo.effectsComboTableOffsetToRAMAddress, 4), 0); - ROMToolboxDialog.flag_MainComboTableRepointed = (effectsComboMainTableStartAddress >= RomInfo.synthOverlayLoadAddress); - effectsComboMainTableStartAddress -= ROMToolboxDialog.flag_MainComboTableRepointed ? RomInfo.synthOverlayLoadAddress : DSUtils.ARM9.address; + effectsComboMainTableStartAddress = BitConverter.ToUInt32(ARM9.ReadBytes(RomInfo.effectsComboTableOffsetToRAMAddress, 4), 0); + PatchToolboxDialog.flag_MainComboTableRepointed = (effectsComboMainTableStartAddress >= RomInfo.synthOverlayLoadAddress); + effectsComboMainTableStartAddress -= PatchToolboxDialog.flag_MainComboTableRepointed ? RomInfo.synthOverlayLoadAddress : ARM9.address; byte comboTableEntriesCount; if (RomInfo.gameFamily == GameFamilies.HGSS) { - comboTableEntriesCount = DSUtils.ARM9.ReadByte(RomInfo.effectsComboTableOffsetToSizeLimiter); + comboTableEntriesCount = ARM9.ReadByte(RomInfo.effectsComboTableOffsetToSizeLimiter); vsPokemonEffectsList = new List<(int pokemonID, int comboID)>(); vsTrainerEffectsList = new List<(int trainerClass, int comboID)>(); - vsPokemonTableStartAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(RomInfo.vsPokemonEntryTableOffsetToRAMAddress, 4), 0); - ROMToolboxDialog.flag_PokemonBattleTableRepointed = (vsPokemonTableStartAddress >= RomInfo.synthOverlayLoadAddress); - vsPokemonTableStartAddress -= ROMToolboxDialog.flag_PokemonBattleTableRepointed ? RomInfo.synthOverlayLoadAddress : DSUtils.ARM9.address; + vsPokemonTableStartAddress = BitConverter.ToUInt32(ARM9.ReadBytes(RomInfo.vsPokemonEntryTableOffsetToRAMAddress, 4), 0); + PatchToolboxDialog.flag_PokemonBattleTableRepointed = (vsPokemonTableStartAddress >= RomInfo.synthOverlayLoadAddress); + vsPokemonTableStartAddress -= PatchToolboxDialog.flag_PokemonBattleTableRepointed ? RomInfo.synthOverlayLoadAddress : ARM9.address; - vsTrainerTableStartAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(RomInfo.vsTrainerEntryTableOffsetToRAMAddress, 4), 0); - ROMToolboxDialog.flag_TrainerClassBattleTableRepointed = (vsTrainerTableStartAddress >= RomInfo.synthOverlayLoadAddress); - vsTrainerTableStartAddress -= ROMToolboxDialog.flag_TrainerClassBattleTableRepointed ? RomInfo.synthOverlayLoadAddress : DSUtils.ARM9.address; + vsTrainerTableStartAddress = BitConverter.ToUInt32(ARM9.ReadBytes(RomInfo.vsTrainerEntryTableOffsetToRAMAddress, 4), 0); + PatchToolboxDialog.flag_TrainerClassBattleTableRepointed = (vsTrainerTableStartAddress >= RomInfo.synthOverlayLoadAddress); + vsTrainerTableStartAddress -= PatchToolboxDialog.flag_TrainerClassBattleTableRepointed ? RomInfo.synthOverlayLoadAddress : ARM9.address; pbEffectsPokemonCombobox.Items.Clear(); @@ -8823,11 +8823,11 @@ namespace DSPRE { pbEffectsCombosListbox.Items.Clear(); - String expArmPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + ROMToolboxDialog.expandedARMfileID.ToString("D4"); + String expArmPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + PatchToolboxDialog.expandedARMfileID.ToString("D4"); if (RomInfo.gameFamily == GameFamilies.HGSS) { - using (DSUtils.EasyReader ar = new DSUtils.EasyReader(ROMToolboxDialog.flag_TrainerClassBattleTableRepointed ? expArmPath : RomInfo.arm9Path, vsTrainerTableStartAddress)) { - byte trainerTableEntriesCount = DSUtils.ARM9.ReadByte(RomInfo.vsTrainerEntryTableOffsetToSizeLimiter); + using (DSUtils.EasyReader ar = new DSUtils.EasyReader(PatchToolboxDialog.flag_TrainerClassBattleTableRepointed ? expArmPath : RomInfo.arm9Path, vsTrainerTableStartAddress)) { + byte trainerTableEntriesCount = ARM9.ReadByte(RomInfo.vsTrainerEntryTableOffsetToSizeLimiter); for (int i = 0; i < trainerTableEntriesCount; i++) { ushort entry = ar.ReadUInt16(); @@ -8838,8 +8838,8 @@ namespace DSPRE { } } - using (DSUtils.EasyReader ar = new DSUtils.EasyReader(ROMToolboxDialog.flag_PokemonBattleTableRepointed ? expArmPath : RomInfo.arm9Path, vsPokemonTableStartAddress)) { - byte pokemonTableEntriesCount = DSUtils.ARM9.ReadByte(RomInfo.vsPokemonEntryTableOffsetToSizeLimiter); + using (DSUtils.EasyReader ar = new DSUtils.EasyReader(PatchToolboxDialog.flag_PokemonBattleTableRepointed ? expArmPath : RomInfo.arm9Path, vsPokemonTableStartAddress)) { + byte pokemonTableEntriesCount = ARM9.ReadByte(RomInfo.vsPokemonEntryTableOffsetToSizeLimiter); for (int i = 0; i < pokemonTableEntriesCount; i++) { ushort entry = ar.ReadUInt16(); @@ -8858,7 +8858,7 @@ namespace DSPRE { } } - using (DSUtils.EasyReader ar = new DSUtils.EasyReader(ROMToolboxDialog.flag_MainComboTableRepointed ? expArmPath : RomInfo.arm9Path, effectsComboMainTableStartAddress)) { + using (DSUtils.EasyReader ar = new DSUtils.EasyReader(PatchToolboxDialog.flag_MainComboTableRepointed ? expArmPath : RomInfo.arm9Path, effectsComboMainTableStartAddress)) { for (int i = 0; i < comboTableEntriesCount; i++) { ushort battleIntroEffect = ar.ReadUInt16(); ushort battleMusic = ar.ReadUInt16(); @@ -8956,9 +8956,9 @@ namespace DSPRE { private void saveConditionalMusicTableBTN_Click(object sender, EventArgs e) { for (int i = 0; i < conditionalMusicTable.Count; i++) { - DSUtils.ARM9.WriteBytes(BitConverter.GetBytes(conditionalMusicTable[i].header), (uint)(conditionalMusicTableStartAddress + 6 * i)); - DSUtils.ARM9.WriteBytes(BitConverter.GetBytes(conditionalMusicTable[i].flag), (uint)(conditionalMusicTableStartAddress + 6 * i + 2)); - DSUtils.ARM9.WriteBytes(BitConverter.GetBytes(conditionalMusicTable[i].music), (uint)(conditionalMusicTableStartAddress + 6 * i + 4)); + ARM9.WriteBytes(BitConverter.GetBytes(conditionalMusicTable[i].header), (uint)(conditionalMusicTableStartAddress + 6 * i)); + ARM9.WriteBytes(BitConverter.GetBytes(conditionalMusicTable[i].flag), (uint)(conditionalMusicTableStartAddress + 6 * i + 2)); + ARM9.WriteBytes(BitConverter.GetBytes(conditionalMusicTable[i].music), (uint)(conditionalMusicTableStartAddress + 6 * i + 4)); } } @@ -8973,8 +8973,8 @@ namespace DSPRE { effectsComboTable[index] = (battleIntroEffect, battleMusic); - String expArmPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + ROMToolboxDialog.expandedARMfileID.ToString("D4"); - using (DSUtils.EasyWriter wr = new DSUtils.EasyWriter(ROMToolboxDialog.flag_MainComboTableRepointed ? expArmPath : RomInfo.arm9Path, effectsComboMainTableStartAddress + 4 * index)) { + String expArmPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + PatchToolboxDialog.expandedARMfileID.ToString("D4"); + using (DSUtils.EasyWriter wr = new DSUtils.EasyWriter(PatchToolboxDialog.flag_MainComboTableRepointed ? expArmPath : RomInfo.arm9Path, effectsComboMainTableStartAddress + 4 * index)) { wr.Write(battleIntroEffect); wr.Write(battleMusic); }; @@ -8997,8 +8997,8 @@ namespace DSPRE { vsPokemonEffectsList[index] = (pokemonID, comboID); - String expArmPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + ROMToolboxDialog.expandedARMfileID.ToString("D4"); - using (DSUtils.EasyWriter wr = new DSUtils.EasyWriter(ROMToolboxDialog.flag_PokemonBattleTableRepointed ? expArmPath : RomInfo.arm9Path, vsPokemonTableStartAddress + 2 * index)) { + String expArmPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + PatchToolboxDialog.expandedARMfileID.ToString("D4"); + using (DSUtils.EasyWriter wr = new DSUtils.EasyWriter(PatchToolboxDialog.flag_PokemonBattleTableRepointed ? expArmPath : RomInfo.arm9Path, vsPokemonTableStartAddress + 2 * index)) { wr.Write((ushort)((pokemonID & 1023) + (comboID << 10))); //PokemonID }; @@ -9013,8 +9013,8 @@ namespace DSPRE { ushort comboID = (ushort)pbEffectsTrainerChooseMainCombobox.SelectedIndex; vsTrainerEffectsList[index] = (trainerClass, comboID); - String expArmPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + ROMToolboxDialog.expandedARMfileID.ToString("D4"); - using (DSUtils.EasyWriter wr = new DSUtils.EasyWriter(ROMToolboxDialog.flag_TrainerClassBattleTableRepointed ? expArmPath : RomInfo.arm9Path, vsTrainerTableStartAddress + 2 * index)) { + String expArmPath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + PatchToolboxDialog.expandedARMfileID.ToString("D4"); + using (DSUtils.EasyWriter wr = new DSUtils.EasyWriter(PatchToolboxDialog.flag_TrainerClassBattleTableRepointed ? expArmPath : RomInfo.arm9Path, vsTrainerTableStartAddress + 2 * index)) { wr.Write((ushort)((trainerClass & 1023) + (comboID << 10))); }; diff --git a/DS_Map/ROMToolboxDialog.Designer.cs b/DS_Map/PatchToolboxDialog.Designer.cs similarity index 99% rename from DS_Map/ROMToolboxDialog.Designer.cs rename to DS_Map/PatchToolboxDialog.Designer.cs index 3d5abf9..a4a1d06 100644 --- a/DS_Map/ROMToolboxDialog.Designer.cs +++ b/DS_Map/PatchToolboxDialog.Designer.cs @@ -1,6 +1,6 @@ namespace DSPRE { - partial class ROMToolboxDialog + partial class PatchToolboxDialog { /// /// Required designer variable. @@ -27,7 +27,7 @@ /// the contents of this method with the code editor. /// private void InitializeComponent() { - System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ROMToolboxDialog)); + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(PatchToolboxDialog)); this.applyItemStandardizeButton = new System.Windows.Forms.Button(); this.arm9expansionTextLBL = new System.Windows.Forms.Label(); this.arm9expansionLBL = new System.Windows.Forms.Label(); diff --git a/DS_Map/ROMToolboxDialog.cs b/DS_Map/PatchToolboxDialog.cs similarity index 90% rename from DS_Map/ROMToolboxDialog.cs rename to DS_Map/PatchToolboxDialog.cs index 98f86ba..7a9bb83 100644 --- a/DS_Map/ROMToolboxDialog.cs +++ b/DS_Map/PatchToolboxDialog.cs @@ -14,7 +14,7 @@ using static DSPRE.Resources.ROMToolboxDB.ToolboxDB; using static NSMBe4.ROM; namespace DSPRE { - public partial class ROMToolboxDialog : Form { + public partial class PatchToolboxDialog : Form { public static uint expandedARMfileID = ToolboxDB.syntheticOverlayFileNumbersDB[RomInfo.gameFamily]; public static bool flag_standardizedItems { get; private set; } = false; @@ -33,7 +33,7 @@ namespace DSPRE { public static readonly int expandedTrainerNameLength = 12; #region Constructor - public ROMToolboxDialog() { + public PatchToolboxDialog() { InitializeComponent(); CheckStandardizedItems(); @@ -69,7 +69,7 @@ namespace DSPRE { CheckDynamicHeadersPatchApplied(); break; case GameFamilies.HGSS: - if (!DSUtils.CheckOverlayHasCompressionFlag(1)) { + if (!OverlayUtils.OverlayTable.IsDefaultCompressed(1)) { DisableOverlay1patch("Already applied"); overlay1CB.Visible = true; } @@ -153,12 +153,12 @@ namespace DSPRE { ARM9PatchData data = new ARM9PatchData(); byte[] branchCode = DSUtils.HexStringToByteArray(data.branchString); - byte[] branchCodeRead = DSUtils.ARM9.ReadBytes(data.branchOffset, data.branchString.Length / 3 + 1); //Read branchCode + byte[] branchCodeRead = ARM9.ReadBytes(data.branchOffset, data.branchString.Length / 3 + 1); //Read branchCode if (branchCodeRead.Length != branchCode.Length || !branchCodeRead.SequenceEqual(branchCode)) return false; byte[] initCode = DSUtils.HexStringToByteArray(data.initString); - byte[] initCodeRead = DSUtils.ARM9.ReadBytes(data.initOffset, data.initString.Length / 3 + 1); //Read initCode + byte[] initCodeRead = ARM9.ReadBytes(data.initOffset, data.initString.Length / 3 + 1); //Read initCode if (initCodeRead.Length != initCode.Length || !initCodeRead.SequenceEqual(initCode)) return false; @@ -168,14 +168,14 @@ namespace DSPRE { BDHCAMPatchData data = new BDHCAMPatchData(); byte[] branchCode = DSUtils.HexStringToByteArray(data.branchString); - byte[] branchCodeRead = DSUtils.ARM9.ReadBytes(data.branchOffset, branchCode.Length); + byte[] branchCodeRead = ARM9.ReadBytes(data.branchOffset, branchCode.Length); if (branchCode.Length != branchCodeRead.Length || !branchCode.SequenceEqual(branchCodeRead)) { return false; } - string overlayFilePath = DSUtils.GetOverlayPath(data.overlayNumber); - DSUtils.DecompressOverlay(data.overlayNumber); + string overlayFilePath = OverlayUtils.GetPath(data.overlayNumber); + OverlayUtils.Decompress(data.overlayNumber); byte[] overlayCode1 = DSUtils.HexStringToByteArray(data.overlayString1); byte[] overlayCode1Read = DSUtils.ReadFromFile(overlayFilePath, data.overlayOffset1, overlayCode1.Length); @@ -188,7 +188,7 @@ namespace DSPRE { 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"); + String fullFilePath = RomInfo.gameDirs[DirNames.synthOverlay].unpackedDir + '\\' + PatchToolboxDialog.expandedARMfileID.ToString("D4"); byte[] subroutineRead = DSUtils.ReadFromFile(fullFilePath, BDHCAMPatchData.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 @@ -203,7 +203,7 @@ namespace DSPRE { languageOffset = +8; } - byte[] read = DSUtils.ARM9.ReadBytes((uint)(offset - DSUtils.ARM9.address + languageOffset), kv.Value.Length / 3 + 1); + byte[] read = ARM9.ReadBytes((uint)(offset - ARM9.address + languageOffset), kv.Value.Length / 3 + 1); byte[] code = DSUtils.HexStringToByteArray(kv.Value); if (read.Length != code.Length || !read.SequenceEqual(code)) return false; @@ -227,39 +227,39 @@ namespace DSPRE { public bool CheckStandardizedItems() { DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.scripts }); - if (!ROMToolboxDialog.flag_standardizedItems) { - if (!ROMToolboxDialog.CheckScriptsStandardizedItemNumbers()) { + if (!PatchToolboxDialog.flag_standardizedItems) { + if (!PatchToolboxDialog.CheckScriptsStandardizedItemNumbers()) { return false; } } itemNumbersCB.Visible = true; - ROMToolboxDialog.flag_standardizedItems = true; + PatchToolboxDialog.flag_standardizedItems = true; DisableStandardizeItemsPatch("Already applied"); return true; } public bool CheckMatrixExpansionApplied() { - if (!ROMToolboxDialog.flag_MatrixExpansionApplied) { - if (!ROMToolboxDialog.CheckFilesMatrixExpansionApplied()) { + if (!PatchToolboxDialog.flag_MatrixExpansionApplied) { + if (!PatchToolboxDialog.CheckFilesMatrixExpansionApplied()) { return false; } } DisableMatrixExpansionPatch("Already applied"); - ROMToolboxDialog.flag_MatrixExpansionApplied = true; + PatchToolboxDialog.flag_MatrixExpansionApplied = true; expandedMatrixCB.Visible = true; return true; } public string backupSuffix = ".backup"; private bool CheckARM9ExpansionApplied() { - if (!ROMToolboxDialog.flag_arm9Expanded) { - if (!ROMToolboxDialog.CheckFilesArm9ExpansionApplied()) { + if (!PatchToolboxDialog.flag_arm9Expanded) { + if (!PatchToolboxDialog.CheckFilesArm9ExpansionApplied()) { return false; } } - ROMToolboxDialog.flag_arm9Expanded = true; + PatchToolboxDialog.flag_arm9Expanded = true; arm9patchCB.Visible = true; DisableARM9patch("Already applied"); @@ -277,12 +277,12 @@ namespace DSPRE { } public bool CheckDynamicHeadersPatchApplied() { if (!flag_DynamicHeadersPatchApplied) { - if (!ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (!PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { return false; } } - ROMToolboxDialog.flag_DynamicHeadersPatchApplied = true; + PatchToolboxDialog.flag_DynamicHeadersPatchApplied = true; dynamicHeadersPatchCB.Visible = true; DisableDynamicHeadersPatch("Already applied"); @@ -291,7 +291,7 @@ namespace DSPRE { public static bool CheckFilesDynamicHeadersPatchApplied() { DynamicHeadersPatchData data = new DynamicHeadersPatchData(); - ushort initValue = BitConverter.ToUInt16(DSUtils.ARM9.ReadBytes(data.initOffset, 0x2), 0); + ushort initValue = BitConverter.ToUInt16(ARM9.ReadBytes(data.initOffset, 0x2), 0); return initValue == 0xB500; } @@ -302,12 +302,12 @@ namespace DSPRE { return false; } - if (!ROMToolboxDialog.flag_BDHCamPatchApplied) { - if (!ROMToolboxDialog.CheckFilesBDHCamPatchApplied()) { + if (!PatchToolboxDialog.flag_BDHCamPatchApplied) { + if (!PatchToolboxDialog.CheckFilesBDHCamPatchApplied()) { return false; } } - ROMToolboxDialog.flag_BDHCamPatchApplied = true; + PatchToolboxDialog.flag_BDHCamPatchApplied = true; BDHCamCB.Visible = true; DisableBDHCamPatch("Already applied"); @@ -328,7 +328,7 @@ namespace DSPRE { if (v > TrainerFile.defaultNameLen+1) { DisableTrainerNameExpansionPatch("Already\nApplied"); - ROMToolboxDialog.flag_TrainerNamesExpanded = true; + PatchToolboxDialog.flag_TrainerNamesExpanded = true; } } } @@ -365,7 +365,7 @@ namespace DSPRE { BDHCAMPatchData data = new BDHCAMPatchData(); if (RomInfo.gameFamily == GameFamilies.HGSS) { - if (DSUtils.CheckOverlayHasCompressionFlag(data.overlayNumber)) { + 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); @@ -391,12 +391,12 @@ namespace DSPRE { File.Copy(RomInfo.arm9Path, RomInfo.arm9Path + backupSuffix, overwrite: true); try { - DSUtils.ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.branchString), data.branchOffset); //Write new branchOffset + ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.branchString), data.branchOffset); //Write new branchOffset /* Write to overlayfile */ - string overlayFilePath = DSUtils.GetOverlayPath(data.overlayNumber); - if (DSUtils.OverlayIsCompressed(data.overlayNumber)) { - DSUtils.DecompressOverlay(data.overlayNumber); + string overlayFilePath = OverlayUtils.GetPath(data.overlayNumber); + if (OverlayUtils.IsCompressed(data.overlayNumber)) { + OverlayUtils.Decompress(data.overlayNumber); } DSUtils.WriteToFile(overlayFilePath, DSUtils.HexStringToByteArray(data.overlayString1), data.overlayOffset1); //Write new overlayCode1 @@ -415,7 +415,7 @@ namespace DSPRE { overlay1MustBeRestoredFromBackup = false; DisableBDHCamPatch("Already applied"); - ROMToolboxDialog.flag_BDHCamPatchApplied = true; + PatchToolboxDialog.flag_BDHCamPatchApplied = true; BDHCamCB.Visible = true; MessageBox.Show("The BDHCAM patch has been applied.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -434,7 +434,7 @@ namespace DSPRE { bool isCompressed = false; string stringDecompressOverlay = ""; - if (DSUtils.OverlayIsCompressed(1)) { + if (OverlayUtils.IsCompressed(1)) { isCompressed = true; stringDecompressOverlay = "- Overlay 1 will be decompressed.\n\n"; } @@ -448,7 +448,7 @@ namespace DSPRE { if (d == DialogResult.Yes) { DSUtils.SetOverlayCompressionInTable(1, 0); if (isCompressed) { - DSUtils.DecompressOverlay(1); + OverlayUtils.Decompress(1); } MessageBox.Show("Overlay1 is now configured as uncompressed.", "Operation successful", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -469,7 +469,7 @@ namespace DSPRE { DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.scripts }); DSUtils.TryUnpackNarcs(new List { RomInfo.DirNames.eventFiles }); - if (ROMToolboxDialog.flag_standardizedItems) { + if (PatchToolboxDialog.flag_standardizedItems) { AlreadyApplied(); } else { @@ -529,7 +529,7 @@ namespace DSPRE { DisableStandardizeItemsPatch("Already applied"); itemNumbersCB.Visible = true; - ROMToolboxDialog.flag_standardizedItems = true; + PatchToolboxDialog.flag_standardizedItems = true; } } else { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -550,8 +550,8 @@ namespace DSPRE { File.Copy(RomInfo.arm9Path, RomInfo.arm9Path + backupSuffix, overwrite: true); try { - DSUtils.ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.branchString), data.branchOffset); //Write new branchOffset - DSUtils.ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.initString), data.initOffset); //Write new initOffset + 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); @@ -562,7 +562,7 @@ namespace DSPRE { DisableARM9patch("Already applied"); arm9patchCB.Visible = true; - ROMToolboxDialog.flag_arm9Expanded = true; + PatchToolboxDialog.flag_arm9Expanded = true; switch (RomInfo.gameFamily) { case GameFamilies.Plat: @@ -598,7 +598,7 @@ namespace DSPRE { listOfChanges += "s"; for (int i = 0; i < kv.Key.Length; i++) { - listOfChanges += " 0x" + (kv.Key[i] - DSUtils.ARM9.address + languageOffset).ToString("X"); + listOfChanges += " 0x" + (kv.Key[i] - ARM9.address + languageOffset).ToString("X"); if (i < kv.Key.Length - 1) listOfChanges += ","; @@ -616,7 +616,7 @@ namespace DSPRE { try { foreach (KeyValuePair kv in ToolboxDB.matrixExpansionDB) { foreach (uint offset in kv.Key) { - DSUtils.ARM9.WriteBytes(DSUtils.HexStringToByteArray(kv.Value), (uint)(offset - DSUtils.ARM9.address + languageOffset)); + ARM9.WriteBytes(DSUtils.HexStringToByteArray(kv.Value), (uint)(offset - ARM9.address + languageOffset)); } } } catch { @@ -625,7 +625,7 @@ namespace DSPRE { } DisableMatrixExpansionPatch("Already applied"); expandedMatrixCB.Visible = true; - ROMToolboxDialog.flag_MatrixExpansionApplied = 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 { MessageBox.Show("No changes have been made.", "Operation canceled", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -697,7 +697,7 @@ namespace DSPRE { DE F7 3D F9 bl 0x02017E6C @Free_Memory */ - DSUtils.ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.initString), data.initOffset); + 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: @@ -719,18 +719,18 @@ namespace DSPRE { */ foreach (Tuple reference in DynamicHeadersPatchData.dynamicHeadersPointersDB[RomInfo.gameFamily]) { - DSUtils.ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.REFERENCE_STRING), (uint)(reference.Item1 + data.pointerDiff)); - uint pointerValue = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes((uint)(reference.Item2 + data.pointerDiff), 4), 0) - RomInfo.headerTableOffset - DSUtils.ARM9.address; - DSUtils.ARM9.WriteBytes(BitConverter.GetBytes(pointerValue), (uint)(reference.Item2 + data.pointerDiff)); + 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 between the (mov r1, #0x18) and (mul r1, r0) commands, so we must handle this separately */ - DSUtils.ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.specialCaseData1), (uint)(data.specialCaseOffset1 + data.pointerDiff)); - DSUtils.ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.specialCaseData2), (uint)(data.specialCaseOffset2 + data.pointerDiff)); - DSUtils.ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.specialCaseData3), (uint)(data.specialCaseOffset3 + data.pointerDiff)); + ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.specialCaseData1), (uint)(data.specialCaseOffset1 + data.pointerDiff)); + ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.specialCaseData2), (uint)(data.specialCaseOffset2 + data.pointerDiff)); + ARM9.WriteBytes(DSUtils.HexStringToByteArray(data.specialCaseData3), (uint)(data.specialCaseOffset3 + data.pointerDiff)); } // Clear the dynamic headers directory in 'unpacked' @@ -749,7 +749,7 @@ namespace DSPRE { DisableDynamicHeadersPatch("Already applied"); dynamicHeadersPatchCB.Visible = true; - ROMToolboxDialog.flag_DynamicHeadersPatchApplied = true; + PatchToolboxDialog.flag_DynamicHeadersPatchApplied = true; MessageBox.Show("The headers are now dynamically allocated in memory.", "Operation successful.", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch { @@ -797,17 +797,17 @@ 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 {ROMToolboxDialog.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 (DSUtils.ARM9.Writer wr = new DSUtils.ARM9.Writer(RomInfo.trainerNameLenOffset)) { - wr.Write((byte)ROMToolboxDialog.expandedTrainerNameLength); + using (ARM9.Writer wr = new ARM9.Writer(RomInfo.trainerNameLenOffset)) { + wr.Write((byte)PatchToolboxDialog.expandedTrainerNameLength); } - ROMToolboxDialog.flag_TrainerNamesExpanded = true; + PatchToolboxDialog.flag_TrainerNamesExpanded = true; DisableTrainerNameExpansionPatch("Already applied"); expandTrainerNamesCB.Visible = true; RomInfo.SetTrainerNameMaxLen(); @@ -847,7 +847,7 @@ namespace DSPRE { 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 (DSUtils.ARM9.Reader r = new DSUtils.ARM9.Reader(pointerOffset)) { + using (ARM9.Reader r = new ARM9.Reader(pointerOffset)) { uint cmdTable = r.ReadUInt32(); uint offset = cmdTable - synthOverlayLoadAddress; @@ -873,7 +873,7 @@ namespace DSPRE { arm9FileStream.Close(); - using (DSUtils.ARM9.Writer wr = new DSUtils.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); diff --git a/DS_Map/ROMToolboxDialog.resx b/DS_Map/PatchToolboxDialog.resx similarity index 100% rename from DS_Map/ROMToolboxDialog.resx rename to DS_Map/PatchToolboxDialog.resx diff --git a/DS_Map/ROMFiles/MapHeader.cs b/DS_Map/ROMFiles/MapHeader.cs index 3bd95af..26a4ddb 100644 --- a/DS_Map/ROMFiles/MapHeader.cs +++ b/DS_Map/ROMFiles/MapHeader.cs @@ -173,7 +173,7 @@ namespace DSPRE.ROMFiles { } /* Check if dynamic headers patch has been applied, and load header from arm9 or a/0/5/0 accordingly */ - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied) { string path = Filesystem.GetDynamicHeaderPath(headerNumber); mapHeader = MapHeader.LoadFromFile(path, headerNumber, 0); } else { @@ -185,7 +185,7 @@ namespace DSPRE.ROMFiles { public static int GetHeaderCount() { int headerCount; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied) { headerCount = Filesystem.GetDynamicHeadersCount(); } else { headerCount = RomInfo.GetHeaderCount(); @@ -196,12 +196,12 @@ namespace DSPRE.ROMFiles { public void SaveFile() { /* Check if dynamic headers patch has been applied, and save header to arm9 or a/0/5/0 accordingly */ - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied) { string path = Filesystem.GetDynamicHeaderPath(ID); DSUtils.WriteToFile(path, this.ToByteArray(), 0, 0, fmode: FileMode.Create); } else { uint headerOffset = (uint)(RomInfo.headerTableOffset + MapHeader.length * this.ID); - DSUtils.ARM9.WriteBytes(this.ToByteArray(), headerOffset); + ARM9.WriteBytes(this.ToByteArray(), headerOffset); } } diff --git a/DS_Map/Resources/ROMToolboxDB/ToolboxDB.cs b/DS_Map/Resources/ROMToolboxDB/ToolboxDB.cs index d844273..fec026c 100644 --- a/DS_Map/Resources/ROMToolboxDB/ToolboxDB.cs +++ b/DS_Map/Resources/ROMToolboxDB/ToolboxDB.cs @@ -39,8 +39,8 @@ namespace DSPRE.Resources.ROMToolboxDB { ["initOffset" + "_" + RomInfo.GameFamilies.HGSS + "_" + RomInfo.GameLanguages.Spanish] = 0x02110354 }; internal ARM9PatchData() { - branchOffset = arm9ExpansionOffsetsDB[nameof(branchOffset) + "_" + RomInfo.gameFamily] - DSUtils.ARM9.address; - initOffset = arm9ExpansionOffsetsDB[nameof(initOffset) + "_" + RomInfo.gameFamily + "_" + RomInfo.gameLanguage] - DSUtils.ARM9.address; + branchOffset = arm9ExpansionOffsetsDB[nameof(branchOffset) + "_" + RomInfo.gameFamily] - ARM9.address; + initOffset = arm9ExpansionOffsetsDB[nameof(initOffset) + "_" + RomInfo.gameFamily + "_" + RomInfo.gameLanguage] - ARM9.address; branchString = arm9ExpansionCodeDB[nameof(branchString) + "_" + RomInfo.gameFamily + "_" + RomInfo.gameLanguage]; if (RomInfo.gameFamily == GameFamilies.Plat) { @@ -107,7 +107,7 @@ namespace DSPRE.Resources.ROMToolboxDB { overlayOffset2 = BDHCamOffsetsDB[nameof(overlayOffset2) + "_" + RomInfo.gameFamily]; break; } - branchOffset -= DSUtils.ARM9.address; + branchOffset -= ARM9.address; overlayString1 = BDHCamCodeDB[nameof(overlayString1)]; overlayString2 = BDHCamCodeDB[nameof(overlayString2)]; subroutine = (byte[])new ResourceManager("DSPRE.Resources.ROMToolboxDB.BDHCAMPatchDB", Assembly.GetExecutingAssembly()).GetObject(RomInfo.romID + "_cam"); diff --git a/DS_Map/RomInfo.cs b/DS_Map/RomInfo.cs index 21746b6..c2681fe 100644 --- a/DS_Map/RomInfo.cs +++ b/DS_Map/RomInfo.cs @@ -490,7 +490,7 @@ namespace DSPRE { public static void SetOWtable() { switch (gameFamily) { case GameFamilies.DP: - OWtablePath = DSUtils.GetOverlayPath(5); + OWtablePath = OverlayUtils.GetPath(5); switch (gameLanguage) { // Go to the beginning of the overworld table case GameLanguages.English: OWTableOffset = 0x22BCC; @@ -504,7 +504,7 @@ namespace DSPRE { } break; case GameFamilies.Plat: - OWtablePath = DSUtils.GetOverlayPath(5); + OWtablePath = OverlayUtils.GetPath(5); switch (gameLanguage) { // Go to the beginning of the overworld table case GameLanguages.Italian: OWTableOffset = 0x2BC44; @@ -525,16 +525,16 @@ namespace DSPRE { } break; case GameFamilies.HGSS: - if (DSUtils.CheckOverlayHasCompressionFlag(1)) { - if (DSUtils.OverlayIsCompressed(1)) { - if (DSUtils.DecompressOverlay(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); } } } - string ov1Path = DSUtils.GetOverlayPath(1); + string ov1Path = OverlayUtils.GetPath(1); uint ov1Address = DSUtils.GetOverlayRAMAddress(1); int ramAddrOfPointer; @@ -565,7 +565,7 @@ namespace DSPRE { return; } - string ov131path = DSUtils.GetOverlayPath(131); + string ov131path = OverlayUtils.GetPath(131); if (File.Exists(ov131path)) { // if HGE field extension overlay exists OWTableOffset = ramAddressOfTable - DSUtils.GetOverlayRAMAddress(131); @@ -573,7 +573,7 @@ namespace DSPRE { } 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 + "\\" + ROMToolboxDialog.expandedARMfileID.ToString("D4"); + OWtablePath = gameDirs[DirNames.synthOverlay].unpackedDir + "\\" + PatchToolboxDialog.expandedARMfileID.ToString("D4"); } else { OWTableOffset = ramAddressOfTable - ov1Address; OWtablePath = ov1Path; @@ -707,34 +707,34 @@ namespace DSPRE { case GameFamilies.DP: switch (gameLanguage) { case GameLanguages.English: - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x6B838, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x6B838, 4), 0); break; case GameLanguages.Italian: - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x6B874, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x6B874, 4), 0); break; case GameLanguages.German: case GameLanguages.French: case GameLanguages.Spanish: - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x6B894, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x6B894, 4), 0); break; case GameLanguages.Japanese: - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x6FDEC, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x6FDEC, 4), 0); break; } break; case GameFamilies.Plat: switch (gameLanguage) { case GameLanguages.English: - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x79F80, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x79F80, 4), 0); break; case GameLanguages.Italian: case GameLanguages.German: case GameLanguages.French: case GameLanguages.Spanish: - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x7A020, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x7A020, 4), 0); break; case GameLanguages.Japanese: - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x79858, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x79858, 4), 0); break; } break; @@ -743,25 +743,25 @@ namespace DSPRE { switch (gameLanguage) { case GameLanguages.English: case GameLanguages.Italian: - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x74408, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74408, 4), 0); break; case GameLanguages.German: if (gameVersion == GameVersions.HeartGold) { - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x74408, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74408, 4), 0); } else { - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x74400, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74400, 4), 0); } break; case GameLanguages.French: case GameLanguages.Spanish: if (gameVersion == GameVersions.HeartGold) { - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x74400, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74400, 4), 0); } else { - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x74408, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x74408, 4), 0); } break; case GameLanguages.Japanese: - monIconPalTableAddress = BitConverter.ToUInt32(DSUtils.ARM9.ReadBytes(0x73EA0, 4), 0); + monIconPalTableAddress = BitConverter.ToUInt32(ARM9.ReadBytes(0x73EA0, 4), 0); break; } break; @@ -973,7 +973,7 @@ namespace DSPRE { if(trainerNameLenOffset < 0) { trainerNameMaxLen = TrainerFile.defaultNameLen; } else { - using (DSUtils.ARM9.Reader ar = new DSUtils.ARM9.Reader(trainerNameLenOffset)) { + using (ARM9.Reader ar = new ARM9.Reader(trainerNameLenOffset)) { trainerNameMaxLen = ar.ReadByte(); } } diff --git a/DS_Map/SpawnEditor.cs b/DS_Map/SpawnEditor.cs index 998c790..109dcbf 100644 --- a/DS_Map/SpawnEditor.cs +++ b/DS_Map/SpawnEditor.cs @@ -52,13 +52,13 @@ namespace DSPRE { Environment.NewLine + "\nProceed?", "Confirmation required", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (d == DialogResult.Yes) { - string moneyOverlayPath = DSUtils.GetOverlayPath(RomInfo.initialMoneyOverlayNumber); + string moneyOverlayPath = OverlayUtils.GetPath(RomInfo.initialMoneyOverlayNumber); ushort headerNumber = ushort.Parse(spawnHeaderComboBox.SelectedItem.ToString().Split()[0]); - DSUtils.ARM9.WriteBytes(BitConverter.GetBytes(headerNumber), RomInfo.arm9spawnOffset); - DSUtils.ARM9.WriteBytes(BitConverter.GetBytes((short)(matrixxUpDown.Value * 32 + localmapxUpDown.Value)), RomInfo.arm9spawnOffset + 8); - DSUtils.ARM9.WriteBytes(BitConverter.GetBytes((short)(matrixyUpDown.Value * 32 + localmapyUpDown.Value)), RomInfo.arm9spawnOffset + 12); - DSUtils.ARM9.WriteBytes(BitConverter.GetBytes((short)playerDirCombobox.SelectedIndex), RomInfo.arm9spawnOffset + 16); + ARM9.WriteBytes(BitConverter.GetBytes(headerNumber), RomInfo.arm9spawnOffset); + ARM9.WriteBytes(BitConverter.GetBytes((short)(matrixxUpDown.Value * 32 + localmapxUpDown.Value)), RomInfo.arm9spawnOffset + 8); + ARM9.WriteBytes(BitConverter.GetBytes((short)(matrixyUpDown.Value * 32 + localmapyUpDown.Value)), RomInfo.arm9spawnOffset + 12); + ARM9.WriteBytes(BitConverter.GetBytes((short)playerDirCombobox.SelectedIndex), RomInfo.arm9spawnOffset + 16); DSUtils.WriteToFile(moneyOverlayPath, BitConverter.GetBytes((int)initialMoneyUpDown.Value), RomInfo.initialMoneyOverlayOffset); MessageBox.Show("Your spawn settings have been changed.", "Operation successful", MessageBoxButtons.OK, MessageBoxIcon.Information); @@ -69,9 +69,9 @@ namespace DSPRE { private void readDefaultSpawnPosButton_Click(object sender, EventArgs e) {; SetupFields(names); - ushort headerNumber = BitConverter.ToUInt16(DSUtils.ARM9.ReadBytes(RomInfo.arm9spawnOffset, 2), 0); - ushort globalX = BitConverter.ToUInt16(DSUtils.ARM9.ReadBytes(RomInfo.arm9spawnOffset + 8, 2), 0); - ushort globalY = BitConverter.ToUInt16(DSUtils.ARM9.ReadBytes(RomInfo.arm9spawnOffset + 12, 2), 0); + ushort headerNumber = BitConverter.ToUInt16(ARM9.ReadBytes(RomInfo.arm9spawnOffset, 2), 0); + ushort globalX = BitConverter.ToUInt16(ARM9.ReadBytes(RomInfo.arm9spawnOffset + 8, 2), 0); + ushort globalY = BitConverter.ToUInt16(ARM9.ReadBytes(RomInfo.arm9spawnOffset + 12, 2), 0); spawnHeaderComboBox.SelectedIndex = headerNumber; @@ -92,16 +92,16 @@ namespace DSPRE { } ReadDefaultMoney(); - playerDirCombobox.SelectedIndex = BitConverter.ToUInt16(DSUtils.ARM9.ReadBytes(RomInfo.arm9spawnOffset + 16, 2), 0); + playerDirCombobox.SelectedIndex = BitConverter.ToUInt16(ARM9.ReadBytes(RomInfo.arm9spawnOffset + 16, 2), 0); } private void ReadDefaultMoney() { - if (DSUtils.CheckOverlayHasCompressionFlag(RomInfo.initialMoneyOverlayNumber)) { - if (DSUtils.OverlayIsCompressed(RomInfo.initialMoneyOverlayNumber)) { - DSUtils.DecompressOverlay(RomInfo.initialMoneyOverlayNumber); + if (OverlayUtils.OverlayTable.IsDefaultCompressed(RomInfo.initialMoneyOverlayNumber)) { + if (OverlayUtils.IsCompressed(RomInfo.initialMoneyOverlayNumber)) { + OverlayUtils.Decompress(RomInfo.initialMoneyOverlayNumber); } } - string pathToMoneyOverlay = DSUtils.GetOverlayPath(RomInfo.initialMoneyOverlayNumber); + string pathToMoneyOverlay = OverlayUtils.GetPath(RomInfo.initialMoneyOverlayNumber); initialMoneyUpDown.Value = BitConverter.ToUInt32(DSUtils.ReadFromFile(pathToMoneyOverlay, RomInfo.initialMoneyOverlayOffset, 4), 0); } @@ -109,7 +109,7 @@ namespace DSPRE { ushort headerNumber = ushort.Parse(spawnHeaderComboBox.SelectedItem.ToString().Split()[0]); MapHeader currentHeader; - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { currentHeader = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + headerNumber.ToString("D4"), headerNumber, 0); } else { currentHeader = MapHeader.LoadFromARM9(headerNumber); diff --git a/DS_Map/WildEditorDPPt.cs b/DS_Map/WildEditorDPPt.cs index 2c58ae4..0412ebc 100644 --- a/DS_Map/WildEditorDPPt.cs +++ b/DS_Map/WildEditorDPPt.cs @@ -22,7 +22,7 @@ namespace DSPRE { Dictionary EncounterFileLocationName = new Dictionary(); for (ushort i = 0; i < totalNumHeaderFiles; i++) { - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { tempMapHeader = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + i.ToString("D4"), i, 0); } else { tempMapHeader = MapHeader.LoadFromARM9(i); diff --git a/DS_Map/WildEditorHGSS.cs b/DS_Map/WildEditorHGSS.cs index c592839..858b912 100644 --- a/DS_Map/WildEditorHGSS.cs +++ b/DS_Map/WildEditorHGSS.cs @@ -23,7 +23,7 @@ namespace DSPRE { for (ushort i = 0; i < totalNumHeaderFiles; i++) { - if (ROMToolboxDialog.flag_DynamicHeadersPatchApplied || ROMToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) + if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied()) { tempMapHeader = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + i.ToString("D4"), i, 0); }