mirror of
https://github.com/AdAstra-LD/DS-Pokemon-Rom-Editor.git
synced 2026-05-09 12:51:54 -05:00
Started adding the DSUtils changes
Co-authored-by: AdAstra-LD <>
This commit is contained in:
parent
9e20cebee0
commit
8f1a2a003a
|
|
@ -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"))
|
||||
|
|
|
|||
|
|
@ -95,6 +95,11 @@
|
|||
<Reference Include="WindowsFormsIntegration" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="DSUtils\ARM9.cs" />
|
||||
<Compile Include="DSUtils\DSUtils.cs" />
|
||||
<Compile Include="DSUtils\ModelUtils.cs" />
|
||||
<Compile Include="DSUtils\NSBUtils.cs" />
|
||||
<Compile Include="DSUtils\OverlayUtils.cs" />
|
||||
<Compile Include="DVCalculator\DVCalc.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
|
@ -205,7 +210,6 @@
|
|||
<Compile Include="Resources\ROMToolboxDB\ToolboxDB.cs" />
|
||||
<Compile Include="Resources\ScriptDatabase.cs" />
|
||||
<Compile Include="ROMFiles\AreaData.cs" />
|
||||
<Compile Include="DSUtils.cs" />
|
||||
<Compile Include="Resources\CommandsDatabase.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
|
@ -252,11 +256,11 @@
|
|||
<Compile Include="ROMFiles\SpeciesFile.cs" />
|
||||
<Compile Include="ROMFiles\TrainerFile.cs" />
|
||||
<Compile Include="ROMFiles\VariableValueTrigger.cs" />
|
||||
<Compile Include="ROMToolboxDialog.cs">
|
||||
<Compile Include="PatchToolboxDialog.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="ROMToolboxDialog.Designer.cs">
|
||||
<DependentUpon>ROMToolboxDialog.cs</DependentUpon>
|
||||
<Compile Include="PatchToolboxDialog.Designer.cs">
|
||||
<DependentUpon>PatchToolboxDialog.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="BuildingEditor.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
|
@ -417,8 +421,8 @@
|
|||
<DependentUpon>CommandsDatabase.cs</DependentUpon>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="ROMToolboxDialog.resx">
|
||||
<DependentUpon>ROMToolboxDialog.cs</DependentUpon>
|
||||
<EmbeddedResource Include="PatchToolboxDialog.resx">
|
||||
<DependentUpon>PatchToolboxDialog.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="BuildingEditor.resx">
|
||||
<DependentUpon>BuildingEditor.cs</DependentUpon>
|
||||
|
|
|
|||
|
|
@ -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<RomInfo.DirNames> 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<DirNames> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
62
DS_Map/DSUtils/ARM9.cs
Normal file
62
DS_Map/DSUtils/ARM9.cs
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
232
DS_Map/DSUtils/DSUtils.cs
Normal file
232
DS_Map/DSUtils/DSUtils.cs
Normal file
|
|
@ -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<DirNames> 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<DirNames> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
139
DS_Map/DSUtils/ModelUtils.cs
Normal file
139
DS_Map/DSUtils/ModelUtils.cs
Normal file
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
142
DS_Map/DSUtils/NSBUtils.cs
Normal file
142
DS_Map/DSUtils/NSBUtils.cs
Normal file
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
123
DS_Map/DSUtils/OverlayUtils.cs
Normal file
123
DS_Map/DSUtils/OverlayUtils.cs
Normal file
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<string>();
|
||||
headerListBoxNames = new List<string>();
|
||||
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<byte, (uint entryOffset, ushort musicD, ushort? musicN)>();
|
||||
|
||||
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)));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
namespace DSPRE
|
||||
{
|
||||
partial class ROMToolboxDialog
|
||||
partial class PatchToolboxDialog
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
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();
|
||||
|
|
@ -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> { 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> { RomInfo.DirNames.scripts });
|
||||
DSUtils.TryUnpackNarcs(new List<RomInfo.DirNames> { 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<uint[], string> 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<uint, uint> 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);
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace DSPRE {
|
|||
Dictionary<int, string> EncounterFileLocationName = new Dictionary<int, string>();
|
||||
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user