Feature: Fix DSi roms' header and/or banner

Also improve Header2Data reading
Also fix banner_size if rom edited using CrystalTile2
This commit is contained in:
R-YaTian 2021-05-25 13:02:45 +08:00 committed by GitHub
parent bf60f4bdb8
commit f38b03639d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 242 additions and 25 deletions

View File

@ -204,6 +204,7 @@ namespace Tinke
this.btnImportiheader.TabIndex = 47;
this.btnImportiheader.Text = "S2E";
this.btnImportiheader.UseVisualStyleBackColor = true;
this.btnImportiheader.Click += new System.EventHandler(this.btnImportiheader_Click);
//
// lblEncryptionSeed
//
@ -881,6 +882,7 @@ namespace Tinke
this.btnImportAdata.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnImportAdata.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnImportAdata.UseVisualStyleBackColor = true;
this.btnImportAdata.Click += new System.EventHandler(this.btnImportAdata_Click);
//
// EditRomInfo
//

View File

@ -287,10 +287,12 @@ namespace Tinke
private void btnImage_Click(object sender, EventArgs e)
{
OpenFileDialog o = new OpenFileDialog();
o.CheckFileExists = true;
o.DefaultExt = "idat";
o.Filter = "Tinke icon data (*.idat)|*.idat";
OpenFileDialog o = new OpenFileDialog
{
CheckFileExists = true,
DefaultExt = "idat",
Filter = "Tinke icon data (*.idat)|*.idat"
};
if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
try
@ -461,5 +463,111 @@ namespace Tinke
ven.Text = xml.Element("S2A").Value;
ven.Show();
}
private void btnImportAdata_Click(object sender, EventArgs e)
{
OpenFileDialog o = new OpenFileDialog
{
CheckFileExists = true,
DefaultExt = "adat",
Filter = "Tinke animation data(*.adat)|*.adat"
};
if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
BinaryReader br = new BinaryReader(File.OpenRead(o.FileName));
banner.aniIconData = br.ReadBytes(0x1180);
br.Close();
byte[] zbyte = new byte[0x800];
banner.reservedDsi = zbyte;
}
}
private void btnImportiheader_Click(object sender, EventArgs e)
{
OpenFileDialog o = new OpenFileDialog
{
CheckFileExists = true,
DefaultExt = "ihdr",
Filter = "Tinke donor iheader (*.ihdr)|*.ihdr"
};
if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
BinaryReader br = new BinaryReader(File.OpenRead(o.FileName));
char[] temp_gameCode = br.ReadChars(4);
if (Enumerable.SequenceEqual(temp_gameCode, header.gameCode) != true)
{
MessageBox.Show(Tools.Helper.GetTranslation("Messages", "S2D"));
br.Close();
return;
}
header.global_mbk_setting = new byte[5][];
for (int i = 0; i < 5; i++) header.global_mbk_setting[i] = br.ReadBytes(4);
header.arm9_mbk_setting = new uint[3];
for (int i = 0; i < 3; i++) header.arm9_mbk_setting[i] = br.ReadUInt32();
header.arm7_mbk_setting = new uint[3];
for (int i = 0; i < 3; i++) header.arm7_mbk_setting[i] = br.ReadUInt32();
header.mbk9_wramcnt_setting = br.ReadUInt32();
header.region_flags = br.ReadUInt32();
header.access_control = br.ReadUInt32();
header.scfg_ext_mask = br.ReadUInt32();
header.appflags = br.ReadBytes(4);
header.dsi9_rom_offset = br.ReadUInt32();
header.offset_0x1C4 = br.ReadUInt32();
header.dsi9_ram_address = br.ReadUInt32();
header.dsi9_size = br.ReadUInt32();
header.dsi7_rom_offset = br.ReadUInt32();
header.offset_0x1D4 = br.ReadUInt32();
header.dsi7_ram_address = br.ReadUInt32();
header.dsi7_size = br.ReadUInt32();
header.digest_ntr_start = br.ReadUInt32();
header.digest_ntr_size = br.ReadUInt32();
header.digest_twl_start = br.ReadUInt32();
header.digest_twl_size = br.ReadUInt32();
header.sector_hashtable_start = br.ReadUInt32();
header.sector_hashtable_size = br.ReadUInt32();
header.block_hashtable_start = br.ReadUInt32();
header.block_hashtable_size = br.ReadUInt32();
header.digest_sector_size = br.ReadUInt32();
header.digest_block_sectorcount = br.ReadUInt32();
header.banner_size = br.ReadUInt32();
header.offset_0x20C = br.ReadUInt32();
header.total_rom_size = br.ReadUInt32();
header.offset_0x214 = br.ReadUInt32();
header.offset_0x218 = br.ReadUInt32();
header.offset_0x21C = br.ReadUInt32();
header.modcrypt1_start = br.ReadUInt32();
header.modcrypt1_size = br.ReadUInt32();
header.modcrypt2_start = br.ReadUInt32();
header.modcrypt2_size = br.ReadUInt32();
header.tid_low = br.ReadUInt32();
header.tid_high = br.ReadUInt32();
header.public_sav_size = br.ReadUInt32();
header.private_sav_size = br.ReadUInt32();
header.reserved5 = br.ReadBytes(0xB0);
header.age_ratings = br.ReadBytes(0x10);
header.hmac_arm9 = br.ReadBytes(20);
header.hmac_arm7 = br.ReadBytes(20);
header.hmac_digest_master = br.ReadBytes(20);
header.hmac_icon_title = br.ReadBytes(20);
header.hmac_arm9i = br.ReadBytes(20);
header.hmac_arm7i = br.ReadBytes(20);
header.reserved6 = br.ReadBytes(40);
header.hmac_arm9_no_secure = br.ReadBytes(20);
header.reserved7 = br.ReadBytes(0xA4C);
header.debug_args = br.ReadBytes(0x180);
header.rsa_signature = br.ReadBytes(0x80);
br.Close();
header.trimmedRom = false;
}
}
}
}

View File

@ -487,7 +487,7 @@ namespace Tinke.Nitro
if (bn.version >> 8 == 1)
{
bn.reservedDsi = br.ReadBytes(0x800);
if (size == 0 || size == 0xFFFFFFFF) size = 0x23C0;
if (size == 0 || size == 0xFFFFFFFF || size > 0x23C0) size = 0x23C0;
bn.aniIconData = br.ReadBytes((int)(offset + size - br.BaseStream.Position));
}
@ -525,9 +525,9 @@ namespace Tinke.Nitro
// DSi Enchansed
if ((banner.version >> 8) == 1)
{
//bw.Write(banner.reservedDsi);
byte[] zbyte = new byte[0x800];
bw.Write(zbyte);
bw.Write(banner.reservedDsi);
//byte[] zbyte = new byte[0x800];
//bw.Write(zbyte);
bw.Write(banner.aniIconData);
}

View File

@ -83,7 +83,7 @@ namespace Tinke.Nitro
bool twlEncrypted;
public byte[][] Overlays9Sha1Hmac { get; private set; }
public byte[] Header2Data { get; private set; }
public byte[][] Header2Data { get; private set; }
public byte[] DSi9Data { get; private set; }
public byte[] DSi7Data { get; private set; }
public byte[] Hashtable1Data { get; private set; }
@ -105,11 +105,17 @@ namespace Tinke.Nitro
this.DSi9Data = br.ReadBytes(Math.Max((int)hdr.modcrypt1_size, (int)hdr.dsi9_size));
br.BaseStream.Position = hdr.dsi7_rom_offset;
this.DSi7Data = br.ReadBytes(Math.Max((int)hdr.modcrypt2_size, (int)hdr.dsi7_size));
//if (!hdr.trimmedRom)
//{
br.BaseStream.Position = hdr.digest_twl_start - 0x3000;
this.Header2Data = br.ReadBytes(0x3000);
//}
if (!hdr.trimmedRom)
{
//br.BaseStream.Position = hdr.digest_twl_start - 0x3000;
//this.Header2Data = br.ReadBytes(0x3000);
this.Header2Data = new byte[3][];
for (int i = 0; i < 3; i++)
{
br.BaseStream.Position = hdr.digest_ntr_start + 0x4000;
this.Header2Data[i] = br.ReadBytes(0x1000);
}
}
// Calc SHA1-HMAC of overlays9
HMACSHA1 hmac = new HMACSHA1(TWL.hmac_sha1_key);
@ -255,11 +261,11 @@ namespace Tinke.Nitro
while (bw.BaseStream.Position < hdr.block_hashtable_start) bw.Write((byte)0xFF);
bw.BaseStream.Position = hdr.block_hashtable_start + hdr.block_hashtable_size;
while (bw.BaseStream.Position < hdr.dsi9_rom_offset) bw.Write((byte)0xFF);
//if (this.Header2Data != null && !hdr.trimmedRom)
if (this.Header2Data != null)
if (this.Header2Data != null && !hdr.trimmedRom)
//if (this.Header2Data != null)
{
bw.BaseStream.Position = hdr.digest_twl_start - 0x3000;
bw.Write(this.Header2Data);
for (int j = 0; j < 3; j++) bw.Write(this.Header2Data[j]);
}
bw.Write(this.DSi9Data, 0, this.DSi9Data.Length);

View File

@ -241,6 +241,7 @@ namespace Tinke
this.btnDumpiheader.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnDumpiheader.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnDumpiheader.UseVisualStyleBackColor = true;
this.btnDumpiheader.Click += new System.EventHandler(this.btnDumpiheader_Click);
//
// btnDumpAdata
//
@ -255,6 +256,7 @@ namespace Tinke
this.btnDumpAdata.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.btnDumpAdata.TextImageRelation = System.Windows.Forms.TextImageRelation.ImageBeforeText;
this.btnDumpAdata.UseVisualStyleBackColor = true;
this.btnDumpAdata.Click += new System.EventHandler(this.btnDumpAdata_Click);
//
// btnDumpicondata
//

View File

@ -344,12 +344,14 @@ namespace Tinke
private void btnDumpicondata_Click(object sender, EventArgs e)
{
SaveFileDialog o = new SaveFileDialog();
o.AddExtension = true;
o.CheckPathExists = true;
o.DefaultExt = ".idat";
o.OverwritePrompt = true;
o.Filter = "Tinke icon data (*.idat)|*.idat";
SaveFileDialog o = new SaveFileDialog
{
AddExtension = true,
CheckPathExists = true,
DefaultExt = ".idat",
OverwritePrompt = true,
Filter = "Tinke icon data (*.idat)|*.idat"
};
if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
BinaryWriter bw;
@ -360,5 +362,98 @@ namespace Tinke
bw.Close();
}
}
private void btnDumpAdata_Click(object sender, EventArgs e)
{
SaveFileDialog o = new SaveFileDialog
{
AddExtension = true,
CheckPathExists = true,
DefaultExt = ".adat",
OverwritePrompt = true,
Filter = "Tinke animation data(*.adat)|*.adat"
};
if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
BinaryWriter bw;
bw = new BinaryWriter(new FileStream(o.FileName, FileMode.Create));
bw.Write(banner.aniIconData);
bw.Flush();
bw.Close();
}
}
private void btnDumpiheader_Click(object sender, EventArgs e)
{
SaveFileDialog o = new SaveFileDialog
{
AddExtension = true,
CheckPathExists = true,
DefaultExt = ".ihdr",
OverwritePrompt = true,
Filter = "Tinke donor iheader (*.ihdr)|*.ihdr"
};
if (o.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
BinaryWriter bw;
bw = new BinaryWriter(new FileStream(o.FileName, FileMode.Create));
bw.Write(cabecera.gameCode);
for (int i = 0; i < 5; i++) bw.Write(cabecera.global_mbk_setting[i]);
for (int i = 0; i < 3; i++) bw.Write(cabecera.arm9_mbk_setting[i]);
for (int i = 0; i < 3; i++) bw.Write(cabecera.arm7_mbk_setting[i]);
bw.Write(cabecera.mbk9_wramcnt_setting);
bw.Write(cabecera.region_flags);
bw.Write(cabecera.access_control);
bw.Write(cabecera.scfg_ext_mask);
bw.Write(cabecera.appflags);
bw.Write(cabecera.dsi9_rom_offset);
bw.Write(cabecera.offset_0x1C4);
bw.Write(cabecera.dsi9_ram_address);
bw.Write(cabecera.dsi9_size);
bw.Write(cabecera.dsi7_rom_offset);
bw.Write(cabecera.offset_0x1D4);
bw.Write(cabecera.dsi7_ram_address);
bw.Write(cabecera.dsi7_size);
bw.Write(cabecera.digest_ntr_start);
bw.Write(cabecera.digest_ntr_size);
bw.Write(cabecera.digest_twl_start);
bw.Write(cabecera.digest_twl_size);
bw.Write(cabecera.sector_hashtable_start);
bw.Write(cabecera.sector_hashtable_size);
bw.Write(cabecera.block_hashtable_start);
bw.Write(cabecera.block_hashtable_size);
bw.Write(cabecera.digest_sector_size);
bw.Write(cabecera.digest_block_sectorcount);
bw.Write(cabecera.banner_size);
bw.Write(cabecera.offset_0x20C);
bw.Write(cabecera.total_rom_size);
bw.Write(cabecera.offset_0x214);
bw.Write(cabecera.offset_0x218);
bw.Write(cabecera.offset_0x21C);
bw.Write(cabecera.modcrypt1_start);
bw.Write(cabecera.modcrypt1_size);
bw.Write(cabecera.modcrypt2_start);
bw.Write(cabecera.modcrypt2_size);
bw.Write(cabecera.tid_low);
bw.Write(cabecera.tid_high);
bw.Write(cabecera.public_sav_size);
bw.Write(cabecera.private_sav_size);
bw.Write(cabecera.reserved5);
bw.Write(cabecera.age_ratings);
bw.Write(cabecera.hmac_arm9);
bw.Write(cabecera.hmac_arm7);
bw.Write(cabecera.hmac_digest_master);
bw.Write(cabecera.hmac_icon_title);
bw.Write(cabecera.hmac_arm9i);
bw.Write(cabecera.hmac_arm7i);
bw.Write(cabecera.reserved6);
bw.Write(cabecera.hmac_arm9_no_secure);
bw.Write(cabecera.reserved7);
bw.Write(cabecera.debug_args);
bw.Write(cabecera.rsa_signature);
bw.Flush();
bw.Close();
}
}
}
}

View File

@ -1728,8 +1728,8 @@ namespace Tinke
header.digest_twl_start = header.block_hashtable_start + header.block_hashtable_size;
header.digest_twl_start += 0x200 - header.digest_twl_start % 0x200;
header.digest_twl_start += header.digest_sector_size - header.digest_twl_start % header.digest_sector_size;
//if (!header.trimmedRom && header.digest_twl_start % 0x80000 != 0) header.digest_twl_start += 0x80000 - (header.digest_twl_start % 0x80000) + 0x3000;
if (header.digest_twl_start % 0x80000 != 0) header.digest_twl_start += 0x80000 - (header.digest_twl_start % 0x80000) + 0x3000;
if (!header.trimmedRom && header.digest_twl_start % 0x80000 != 0) header.digest_twl_start += 0x80000 - (header.digest_twl_start % 0x80000) + 0x3000;
//if (header.digest_twl_start % 0x80000 != 0) header.digest_twl_start += 0x80000 - (header.digest_twl_start % 0x80000) + 0x3000;
header.dsi9_rom_offset += header.digest_twl_start;
header.dsi7_rom_offset += header.digest_twl_start;

View File

@ -251,6 +251,7 @@
<S2A>The Version 3 Banner is incomplete or corrupted.</S2A>
<S2B>The DSi Banner is good!</S2B>
<S2C>The DSi Banner is incomplete or corrupted.</S2C>
<S2D>The donor iheader mismatch!</S2D>
</Messages>
<DSDecmp>
<!-- LZ10 -->

View File

@ -262,6 +262,7 @@
<S2A>The Version 3 Banner is incomplete or corrupted.</S2A>
<S2B>The DSi Banner is good!</S2B>
<S2C>The DSi Banner is incomplete or corrupted.</S2C>
<S2D>The donor iheader mismatch!</S2D>
</Messages>
<DSDecmp>
<!-- LZ10 -->

View File

@ -251,6 +251,7 @@
<S2A>The Version 3 Banner is incomplete or corrupted.</S2A>
<S2B>The DSi Banner is good!</S2B>
<S2C>The DSi Banner is incomplete or corrupted.</S2C>
<S2D>The donor iheader mismatch!</S2D>
</Messages>
<NCLR>
<S01>Nombre de la palette :</S01>

View File

@ -251,6 +251,7 @@
<S2A>The Version 3 Banner is incomplete or corrupted.</S2A>
<S2B>The DSi Banner is good!</S2B>
<S2C>The DSi Banner is incomplete or corrupted.</S2C>
<S2D>The donor iheader mismatch!</S2D>
</Messages>
<NANR>
<S01>Intervallo:</S01>