Add an option to "Recompress ARM9 binary", improve arm9 blz

Revert #5b6afa1
Update changelog, compile batch and translations
[WIP] Basic command line support
This commit is contained in:
R-YaTian 2024-02-06 18:03:39 +08:00
parent 7ac89ea4dc
commit a39ebedf66
14 changed files with 727 additions and 611 deletions

View File

@ -130,7 +130,7 @@ namespace SDAT
for (int i = 0; i < sounds.Length; i++)
{
bw.Write(currOffset);
currOffset += (uint)sounds[i].data.data.Length + 0x0C;
currOffset += (uint)sounds[i].data.data.Length + 0x0A;
}
// Write data

View File

@ -32,6 +32,8 @@
this.checkBox2 = new System.Windows.Forms.CheckBox();
this.btn_OK = new System.Windows.Forms.Button();
this.btn_Cancel = new System.Windows.Forms.Button();
this.checkBox3 = new System.Windows.Forms.CheckBox();
this.checkBox4 = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// checkBox1
@ -39,7 +41,7 @@
this.checkBox1.AutoSize = true;
this.checkBox1.Location = new System.Drawing.Point(12, 12);
this.checkBox1.Name = "checkBox1";
this.checkBox1.Size = new System.Drawing.Size(42, 16);
this.checkBox1.Size = new System.Drawing.Size(53, 19);
this.checkBox1.TabIndex = 0;
this.checkBox1.Text = "S1E";
this.checkBox1.UseVisualStyleBackColor = true;
@ -47,9 +49,9 @@
// checkBox2
//
this.checkBox2.AutoSize = true;
this.checkBox2.Location = new System.Drawing.Point(12, 34);
this.checkBox2.Location = new System.Drawing.Point(12, 37);
this.checkBox2.Name = "checkBox2";
this.checkBox2.Size = new System.Drawing.Size(42, 16);
this.checkBox2.Size = new System.Drawing.Size(53, 19);
this.checkBox2.TabIndex = 2;
this.checkBox2.Text = "S1F";
this.checkBox2.UseVisualStyleBackColor = true;
@ -58,7 +60,7 @@
//
this.btn_OK.DialogResult = System.Windows.Forms.DialogResult.OK;
this.btn_OK.Image = global::Tinke.Properties.Resources.accept;
this.btn_OK.Location = new System.Drawing.Point(12, 56);
this.btn_OK.Location = new System.Drawing.Point(12, 112);
this.btn_OK.Name = "btn_OK";
this.btn_OK.Size = new System.Drawing.Size(90, 30);
this.btn_OK.TabIndex = 3;
@ -71,7 +73,7 @@
//
this.btn_Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btn_Cancel.Image = global::Tinke.Properties.Resources.cancel;
this.btn_Cancel.Location = new System.Drawing.Point(137, 56);
this.btn_Cancel.Location = new System.Drawing.Point(137, 112);
this.btn_Cancel.Name = "btn_Cancel";
this.btn_Cancel.Size = new System.Drawing.Size(90, 30);
this.btn_Cancel.TabIndex = 4;
@ -80,10 +82,34 @@
this.btn_Cancel.UseVisualStyleBackColor = true;
this.btn_Cancel.Click += new System.EventHandler(this.btn_Cancel_Click);
//
// checkBox3
//
this.checkBox3.AutoSize = true;
this.checkBox3.Location = new System.Drawing.Point(12, 62);
this.checkBox3.Name = "checkBox3";
this.checkBox3.Size = new System.Drawing.Size(53, 19);
this.checkBox3.TabIndex = 5;
this.checkBox3.Text = "S20";
this.checkBox3.UseVisualStyleBackColor = true;
this.checkBox3.CheckedChanged += new System.EventHandler(this.checkBox3_CheckedChanged);
//
// checkBox4
//
this.checkBox4.AutoSize = true;
this.checkBox4.Enabled = false;
this.checkBox4.Location = new System.Drawing.Point(12, 87);
this.checkBox4.Name = "checkBox4";
this.checkBox4.Size = new System.Drawing.Size(53, 19);
this.checkBox4.TabIndex = 6;
this.checkBox4.Text = "S21";
this.checkBox4.UseVisualStyleBackColor = true;
//
// SaveOptions
//
this.BackColor = System.Drawing.SystemColors.GradientInactiveCaption;
this.ClientSize = new System.Drawing.Size(239, 98);
this.ClientSize = new System.Drawing.Size(239, 154);
this.Controls.Add(this.checkBox4);
this.Controls.Add(this.checkBox3);
this.Controls.Add(this.btn_Cancel);
this.Controls.Add(this.btn_OK);
this.Controls.Add(this.checkBox2);
@ -107,5 +133,7 @@
private System.Windows.Forms.CheckBox checkBox2;
private System.Windows.Forms.Button btn_OK;
private System.Windows.Forms.Button btn_Cancel;
private System.Windows.Forms.CheckBox checkBox3;
private System.Windows.Forms.CheckBox checkBox4;
}
}

View File

@ -22,6 +22,8 @@ namespace Tinke.Dialog
btn_Cancel.Text = xml.Element("S1C").Value;
checkBox1.Text = xml.Element("S1E").Value;
checkBox2.Text = xml.Element("S1F").Value;
checkBox3.Text = xml.Element("S20").Value;
checkBox4.Text = xml.Element("S21").Value;
}
catch { throw new NotImplementedException("There was an error reading the language file"); }
}
@ -36,6 +38,16 @@ namespace Tinke.Dialog
get { return checkBox2.Checked; }
}
public bool IsReCompress
{
get { return checkBox3.Checked; }
}
public bool IsBetterCompress
{
get { return checkBox4.Checked; }
}
private void btn_OK_Click(object sender, EventArgs e)
{
this.Close();
@ -45,5 +57,17 @@ namespace Tinke.Dialog
{
this.Close();
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
if (checkBox3.Checked)
{
checkBox4.Enabled = true;
} else
{
checkBox4.Checked = false;
checkBox4.Enabled= false;
}
}
}
}

View File

@ -211,7 +211,7 @@ namespace Tinke.Nitro
hdr.ARM9size = arm9.size;
uint initptr = BitConverter.ToUInt32(hdr.reserved2, 0) & 0x3FFF;
uint hdrptr = BitConverter.ToUInt32(arm9Data, (int)initptr + 0x14) - hdr.ARM9ramAddress;
bool cmparm9 = ARM9BLZ.Decompress(arm9Data, hdr, out arm9Data);
uint cmparm9 = ARM9BLZ.Decompress(arm9Data, hdr, out arm9Data);
// Get hmac offset
uint offset = 0;
@ -227,7 +227,7 @@ namespace Tinke.Nitro
if (offset > 0)
{
for (int i = 0; i < ov9.Count; i++) Array.Copy(hashes[i], 0, arm9Data, offset + i * 0x14, 20);
if (!cmparm9) arm9Data = ARM9BLZ.Compress(arm9Data, hdr, arm9.size - hdrptr);
if (cmparm9 == 0) arm9Data = ARM9BLZ.Compress(arm9Data, hdr, arm9.size - hdrptr);
string arm9Binary = Path.GetTempFileName();
File.WriteAllBytes(arm9Binary, arm9Data);

View File

@ -18,16 +18,20 @@
*
*/
using System;
//using System.Collections.Generic;
//using System.Linq;
using System.Windows.Forms;
//using System.Reflection;
using System.IO;
using System.Runtime.InteropServices;
namespace Tinke
{
static class Program
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool AttachConsole(int dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool FreeConsole();
/// <summary>
/// Punto de entrada principal para la aplicación.
/// </summary>
@ -35,7 +39,7 @@ namespace Tinke
static void Main(string[] args)
{
#region Comprobación de archivos necesarios
string[] archivos = new string[] { "Ekona.dll", "DSDecmp.dll" };
string[] archivos = new string[] { "Ekona.dll", "DSDecmp.dll" , "Be.Windows.Forms.HexBox.dll" };
string faltan = "";
for (int i = 0; i < archivos.Length; i++)
{
@ -55,5 +59,4 @@ namespace Tinke
Application.Run(new Sistema());
}
}
}

View File

@ -62,12 +62,31 @@ namespace Tinke
// The IE control of the Debug windows doesn't work in Mono
isMono = (Type.GetType("Mono.Runtime") != null);
if (Environment.GetCommandLineArgs().Length == 2 && (Environment.GetCommandLineArgs()[1] == "-h" || Environment.GetCommandLineArgs()[1] == "--help"))
{
Program.AttachConsole(-1);
Console.WriteLine("\n" + this.Text);
Console.WriteLine("Usage: Tinke.exe rom_name [option]");
Console.WriteLine("options:");
Console.WriteLine("-x: Extract all files from nds rom");
Console.WriteLine("-r: Replace all nitrofs files by dir, need -o to set an output rom path(-o Only allowed after -r)");
Console.WriteLine("-h or --help: Show this message, must be the first param...");
Program.FreeConsole();
SendKeys.SendWait("{ENTER}");
}
sb = new StringBuilder();
TextWriter tw = new StringWriter(sb);
tw.NewLine = "<br>";
if (!isMono)
if (!isMono && !(Environment.GetCommandLineArgs().Length >= 3 && (Environment.GetCommandLineArgs()[2] == "-x" || Environment.GetCommandLineArgs()[2] == "-r")))
Console.SetOut(tw);
if (Environment.GetCommandLineArgs().Length >= 3 && (Environment.GetCommandLineArgs()[2] == "-x" || Environment.GetCommandLineArgs()[2] == "-r"))
{
Program.AttachConsole(-1);
Console.WriteLine("\n" + this.Text);
}
#region Language
if (!File.Exists(Application.StartupPath + Path.DirectorySeparatorChar + "Tinke.xml"))
{
@ -144,11 +163,47 @@ namespace Tinke
filesToRead[0] = o.SelectedPath;
o.Dispose();
}
else if (Environment.GetCommandLineArgs()[1] == "-h" || Environment.GetCommandLineArgs()[1] == "--help")
{
Application.Exit();
return;
}
else
filesToRead[0] = Environment.GetCommandLineArgs()[1];
}
else if (Environment.GetCommandLineArgs().Length >= 3)
{
if (Environment.GetCommandLineArgs()[2] == "-x")
{
filesToRead[0] = Environment.GetCommandLineArgs()[1];
ReadGame(filesToRead[0]);
sFolder folderSelect = accion.Root;
if (Environment.GetCommandLineArgs().Length > 3 && Environment.GetCommandLineArgs()[3] is string)
{
Directory.CreateDirectory(Environment.GetCommandLineArgs()[3] + Path.DirectorySeparatorChar + folderSelect.name);
RecursivoExtractFolder(folderSelect, Environment.GetCommandLineArgs()[3] + Path.DirectorySeparatorChar + folderSelect.name);
Console.WriteLine("Extract all files to " + Environment.GetCommandLineArgs()[3] + Path.DirectorySeparatorChar + folderSelect.name);
} else
Console.WriteLine("Param error...");
Program.FreeConsole();
SendKeys.SendWait("{ENTER}");
Application.Exit();
} else if (Environment.GetCommandLineArgs()[2] == "-r" && Environment.GetCommandLineArgs().Length > 5 && Environment.GetCommandLineArgs()[4] == "-o")
{
filesToRead[0] = Environment.GetCommandLineArgs()[1];
ReadGame(filesToRead[0]);
if (Environment.GetCommandLineArgs()[3] is string)
{
ChangeByDir(Environment.GetCommandLineArgs()[3]);
}
// parse saving args
for(int i = 5; i < Environment.GetCommandLineArgs().Length; i++)
{
}
return;
}
filesToRead = new String[Environment.GetCommandLineArgs().Length - 1];
Array.Copy(Environment.GetCommandLineArgs(), 1, filesToRead, 0, filesToRead.Length);
}
@ -1444,6 +1499,8 @@ namespace Tinke
* Files...
*/
bool keep_original = false;
bool a9_recomp = false;
bool a9_bestcomp = false;
Nitro.Estructuras.ROMHeader header = romInfo.Cabecera;
Dialog.SaveOptions dialog = new Dialog.SaveOptions();
@ -1453,6 +1510,10 @@ namespace Tinke
keep_original = true;
if (dialog.IsSafeTrim)
header.trimmedRom = true;
if (dialog.IsReCompress)
a9_recomp = true;
if (dialog.IsBetterCompress)
a9_bestcomp = true;
Thread create = new Thread(ThreadEspera)
{
@ -1533,16 +1594,19 @@ namespace Tinke
header.secureCRC16 = SecureArea.CalcCRC(this.secureArea.EncryptedData, gameCode);
}
bool cmparm9 = true;
uint cmparm9 = 0;
if (!ov9Sha1Hmac_updated)
{
uint initptr = BitConverter.ToUInt32(header.reserved2, 0) & 0x3FFF;
uint hdrptr = BitConverter.ToUInt32(arm9Data, (int)initptr + 0x14) - header.ARM9ramAddress;
byte[] arm9Data_dec;
cmparm9 = ARM9BLZ.Decompress(arm9Data, header, out arm9Data_dec);
if (!cmparm9)
if (cmparm9 == 0 && a9_recomp)
{
arm9Data = ARM9BLZ.Compress(arm9Data_dec, header, 0);
arm9Data = ARM9BLZ.Compress(arm9Data, header, 0, a9_bestcomp);
} else if (cmparm9 == 1 && a9_recomp)
{
arm9Data = ARM9BLZ.Compress(arm9Data_dec, header, 0, a9_bestcomp);
}
}
@ -1551,7 +1615,7 @@ namespace Tinke
bw.Flush();
br.Close();
if (!ov9Sha1Hmac_updated && !cmparm9)
if (!ov9Sha1Hmac_updated && a9_recomp)
{
arm9.path = arm9Binary;
arm9.offset = 0;
@ -1627,7 +1691,6 @@ namespace Tinke
Console.WriteLine(Tools.Helper.GetTranslation("Messages", "S09"), new FileInfo(arm9Binary).Length);
// Escribismo el ARM7 Binary
string arm7Binary = Path.GetTempFileName();
string overlays7 = Path.GetTempFileName();
@ -1690,7 +1753,6 @@ namespace Tinke
bw.Close();
Console.WriteLine(Tools.Helper.GetTranslation("Messages", "S09"), new FileInfo(arm7Binary).Length);
// Escribimos el FNT (File Name Table)
string fileFNT = Path.GetTempFileName();
Console.Write("\tFile Name Table (FNT)...");
@ -1865,15 +1927,8 @@ namespace Tinke
o.DefaultExt = ".nds";
o.Filter = "Nintendo DS ROM (*.nds)|*.nds";
o.OverwritePrompt = true;
Open_Dialog:
if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
if (o.FileName == accion.ROMFile)
{
MessageBox.Show(Tools.Helper.GetTranslation("Sistema", "S44"));
goto Open_Dialog;
}
Thread saverom = new Thread(ThreadEspera)
{
IsBackground = true
@ -1932,10 +1987,6 @@ namespace Tinke
File.Delete(fileFAT);
File.Delete(banner);
File.Delete(files);
//if (!isMono)
//debug.Add_Text(sb.ToString());
//sb.Length = 0;
}
private void btnImport_Click(object sender, EventArgs e)
{
@ -2249,11 +2300,7 @@ namespace Tinke
if (!isMono)
{
try
{
espera.Close();
}
catch { };
CloseEspera(wait);
debug.Add_Text(sb.ToString());
}
sb.Length = 0;
@ -2502,30 +2549,10 @@ namespace Tinke
btnDesplazar.Text = ">>>>>";
}
}
private void btnImport1_Click(object sender, EventArgs e)
private void ChangeByDir(string files_path)
{
Thread matching = new Thread(ThreadEspera)
{
IsBackground = true
};
if (!isMono)
matching.Start("S08");
FolderBrowserDialog FBD = new FolderBrowserDialog
{
Description = Tools.Helper.GetTranslation("Sistema", "S47"),
ShowNewFolderButton = false
};
if (FBD.ShowDialog() != DialogResult.OK)
{
if (!isMono)
CloseEspera(matching);
return;
}
Console.WriteLine(FBD.SelectedPath);
List<string> files = new List<string>();
files = GetAllSubFiles(FBD.SelectedPath, files);
files = GetAllSubFiles(files_path, files);
foreach (string currFile in files)
{
string nstr;
@ -2569,12 +2596,32 @@ namespace Tinke
accion.Change_File(fileToBeChanged.id, currFile);
Console.WriteLine(currFile);
}
if (!isMono)
try
{
espera.Close();
}
catch { };
private void btnImport1_Click(object sender, EventArgs e)
{
Thread matching = new Thread(ThreadEspera)
{
IsBackground = true
};
if (!isMono)
matching.Start("S08");
FolderBrowserDialog FBD = new FolderBrowserDialog
{
Description = Tools.Helper.GetTranslation("Sistema", "S47"),
ShowNewFolderButton = false
};
if (FBD.ShowDialog() != DialogResult.OK)
{
if (!isMono)
CloseEspera(matching);
return;
}
Console.WriteLine(FBD.SelectedPath);
ChangeByDir(FBD.SelectedPath);
if (!isMono)
CloseEspera(matching);
}
public static List<string> GetAllSubFiles(string directoryPath, List<string> files)
{

View File

@ -18,8 +18,8 @@ namespace Tinke.Tools
/// <param name="arm9Data">Compressed ARM9.bin data</param>
/// <param name="hdr">ROM header</param>
/// <param name="decompressed">Decompressed data</param>
/// <returns>True if the decompression was successful.</returns>
public static bool Decompress(byte[] arm9Data, Estructuras.ROMHeader hdr, out byte[] decompressed)
/// <returns>0 = uncompressed; 1 = compressed</returns>
public static uint Decompress(byte[] arm9Data, Estructuras.ROMHeader hdr, out byte[] decompressed)
{
decompressed = arm9Data;
uint nitrocode_length = 0;
@ -46,13 +46,13 @@ namespace Tinke.Tools
output.Write(arm9Data, arm9Data.Length - (int)postSize, (int)postSize);
input.Close();
decompressed = output.ToArray();
cmparm9 = false;
input.Close();
output.Close();
return 1;
}
return cmparm9;
return 0;
}
/// <summary>
@ -61,14 +61,16 @@ namespace Tinke.Tools
/// <param name="arm9Data">Uncompressed ARM9.bin data</param>
/// <param name="hdr">ROM header</param>
/// <param name="postSize">Data size from the end what will be ignored.</param>
/// <param name="method">0 = BLZ; 1 = BLZ-Cue</param>
/// <returns>Compressed data with uncompressed Secure Area (first 0x4000 bytes).</returns>
public static byte[] Compress(byte[] arm9Data, Estructuras.ROMHeader hdr, uint postSize = 0)
public static byte[] Compress(byte[] arm9Data, Estructuras.ROMHeader hdr, uint postSize = 0, bool method = false)
{
Stream input = new MemoryStream(arm9Data);
input.Position = 0x4000;
MemoryStream output = new MemoryStream();
output.Write(arm9Data, 0, 0x4000);
LZOvl blz = new LZOvl();
LZOvl.LookAhead = method;
blz.Compress(input, input.Length - 0x4000, output);
input.Close();
output.Write(arm9Data, arm9Data.Length - (int)postSize, (int)postSize);

View File

@ -425,6 +425,8 @@
<S1C>Cancel</S1C>
<S1E>Safe Trim</S1E>
<S1F>Keep Original RSA SHA1 Signature</S1F>
<S20>Recompress ARM9 binary (BLZ)</S20>
<S21>Better compress method (BLZ-Cue)</S21>
</Dialog>
<VisorHex>
<S00>File</S00>

View File

@ -429,6 +429,8 @@
<S1C>Cancelar</S1C>
<S1E>Safe Trim</S1E>
<S1F>Keep Original RSA SHA1 Signature</S1F>
<S20>Recompress ARM9 binary (BLZ)</S20>
<S21>Better compress method (BLZ-Cue)</S21>
</Dialog>
<VisorHex>
<S00>Archivo</S00>

View File

@ -425,6 +425,8 @@
<S1C>Annuler</S1C>
<S1E>Safe Trim</S1E>
<S1F>Keep Original RSA SHA1 Signature</S1F>
<S20>Recompress ARM9 binary (BLZ)</S20>
<S21>Better compress method (BLZ-Cue)</S21>
</Dialog>
<VisorHex>
<S00>Archive</S00>

View File

@ -424,6 +424,8 @@
<S1C>Cancella</S1C>
<S1E>Safe Trim</S1E>
<S1F>Keep Original RSA SHA1 Signature</S1F>
<S20>Recompress ARM9 binary (BLZ)</S20>
<S21>Better compress method (BLZ-Cue)</S21>
</Dialog>
<VisorHex>
<S00>File</S00>

View File

@ -422,6 +422,8 @@
<S1C>取消</S1C>
<S1E>安全裁剪</S1E>
<S1F>保持原始的 RSA SHA1 签名</S1F>
<S20>重压缩 ARM9 文件 (BLZ 算法)</S20>
<S21>更好的压缩率算法 (BLZ-Cue)</S21>
</Dialog>
<VisorHex>
<S00>文件</S00>

View File

@ -13,10 +13,12 @@ TinkeDSi 0.9.5 (Made by R-YaTian)
* DSDecmp: Add and use CUE's BLZ_Encoder, clean old method
* Add saveoptions window before saving rom (Allow keep original RSA signature, safe trim the rom)
* Allow opening .SRL .IDS .DSI .APP files
* WIP: Improve ARM9BLZ compression logic
* Improve ARM9BLZ compression logic
* Add McDonalds Maker Code to Estructuras.makerCode
* Image: Set gimp_error to default false, hope this will fix palette exporting for anything that's not GIMP
* 3DModels: Update to OpenTK 3.3.3, fix bug on fullscreen btn
* Improved SF Feather Plugin (By @mn1712trungson)
* Core: Improve Nitrocode check when saving rom
TODO: full i18n support (include plugins)
TinkeDSi 0.9.4

View File

@ -41,7 +41,7 @@ REM Get compiler
SET netver=v4.5
SET msbuild_path=%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
SET msbuild=%msbuild_path% /p:Configuration=%conf% /p:TargetFrameworkVersion=%netver%
SET msbuild_plugin=%msbuild% /p:OutputPath="%build_dir%\Plugins\\"
SET msbuild_plugin=%msbuild% /p:OutputPath="%build_dir%\Plugins\\" /m
REM Compile program in standard directory, to allow plugins find Ekona
ECHO Compiling base library
@ -49,7 +49,7 @@ ECHO Compiling base library
REM Compiling program
echo Compiling Tinke
%msbuild% /p:Platform=%plat% /p:OutputPath="%build_dir%\\" Tinke.sln > error.log || (TYPE error.log & EXIT /B 1)
%msbuild% /p:Platform=%plat% /p:OutputPath="%build_dir%\\" /m Tinke.sln > error.log || (TYPE error.log & EXIT /B 1)
REM Compiling format plugins
call :compile_plugin "Plugins\Pack\Pack.sln"