mirror of
https://github.com/Gericom/dspatch.git
synced 2025-06-19 09:25:39 -04:00
Multiple Rom Support
This commit is contained in:
parent
4b3548b6ab
commit
32856c4b68
@ -14,7 +14,7 @@ namespace dspatch.DS
|
|||||||
{
|
{
|
||||||
MemoryStream m = new MemoryStream();
|
MemoryStream m = new MemoryStream();
|
||||||
EndianBinaryWriter er = new EndianBinaryWriter(m);
|
EndianBinaryWriter er = new EndianBinaryWriter(m);
|
||||||
er.Write((byte)entries.Length);
|
er.Write((byte)entries.Count);
|
||||||
er.Write((byte)0);
|
er.Write((byte)0);
|
||||||
er.Write((byte)0);
|
er.Write((byte)0);
|
||||||
er.Write((byte)0);
|
er.Write((byte)0);
|
||||||
@ -25,7 +25,7 @@ namespace dspatch.DS
|
|||||||
er.Close();
|
er.Close();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
public DemoMenuEntry[] entries;
|
public List<DemoMenuEntry> entries = new List<DemoMenuEntry>();
|
||||||
public class DemoMenuEntry
|
public class DemoMenuEntry
|
||||||
{
|
{
|
||||||
private string createString(string text, int length, bool nullTerminated = true)
|
private string createString(string text, int length, bool nullTerminated = true)
|
||||||
|
278
dspatch/DownloadStationPatcher.cs
Normal file
278
dspatch/DownloadStationPatcher.cs
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
using dspatch.DS;
|
||||||
|
using dspatch.IO;
|
||||||
|
using dspatch.Nitro;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace dspatch
|
||||||
|
{
|
||||||
|
public class DownloadStationPatcher
|
||||||
|
{
|
||||||
|
private static byte[] haxxStationIconImage =
|
||||||
|
{
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x90, 0x61, 0x66, 0x66, 0x69, 0x66, 0x66, 0x66, 0x61, 0xC8, 0xCC, 0xCC,
|
||||||
|
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
|
||||||
|
0x66, 0x66, 0x66, 0x66, 0xCC, 0xCC, 0xCC, 0xCC, 0x66, 0x66, 0x66, 0x66,
|
||||||
|
0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x16, 0x09, 0x66, 0x66, 0x66, 0x96,
|
||||||
|
0xCC, 0xCC, 0x8C, 0x16, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xCC, 0xCC, 0x6C,
|
||||||
|
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C,
|
||||||
|
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0x8C, 0xCC, 0x6C, 0x45, 0x65, 0x41, 0x85,
|
||||||
|
0x89, 0xE2, 0xC0, 0x27, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||||
|
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||||
|
0x66, 0x66, 0x66, 0x66, 0x27, 0x16, 0x54, 0xB7, 0xD5, 0xE0, 0x9D, 0x14,
|
||||||
|
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
||||||
|
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0x99, 0xCC, 0x66,
|
||||||
|
0x5C, 0x11, 0xC5, 0x66, 0x42, 0xEE, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x20, 0x0E, 0x00,
|
||||||
|
0x00, 0x79, 0x00, 0x0B, 0x00, 0x01, 0x70, 0x08, 0xD0, 0x04, 0x2E, 0x00,
|
||||||
|
0xB0, 0x07, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x77, 0x0C,
|
||||||
|
0x24, 0x87, 0x52, 0x14, 0x66, 0x14, 0xC9, 0x6C, 0x66, 0xAC, 0xCC, 0x6C,
|
||||||
|
0x66, 0xCC, 0xC1, 0x6C, 0x66, 0x1C, 0x16, 0x6C, 0x66, 0xCC, 0xC1, 0x6C,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xA7, 0x00, 0x41, 0x88, 0x47, 0x41,
|
||||||
|
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xF3, 0x63, 0x66, 0x66,
|
||||||
|
0x36, 0x3F, 0x66, 0x66, 0x36, 0x3F, 0x66, 0x66, 0x0D, 0x00, 0xD0, 0x99,
|
||||||
|
0x00, 0x88, 0x00, 0x00, 0x18, 0x44, 0x81, 0x99, 0x76, 0xCC, 0x57, 0x44,
|
||||||
|
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0x6C, 0xCC, 0x66, 0xC6, 0xC6, 0xC6, 0x66,
|
||||||
|
0xC6, 0x6C, 0xCC, 0x66, 0x90, 0x09, 0x89, 0x00, 0xB0, 0x07, 0x4D, 0x00,
|
||||||
|
0xD0, 0x04, 0x10, 0x00, 0x00, 0x01, 0x80, 0x05, 0x00, 0x78, 0x00, 0x0E,
|
||||||
|
0x00, 0x10, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C,
|
||||||
|
0x61, 0xC8, 0xCC, 0xCC, 0x68, 0x66, 0x66, 0x66, 0x80, 0x61, 0x66, 0x66,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x63, 0xFF, 0x6F,
|
||||||
|
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCC, 0xCC, 0xCC, 0xCC,
|
||||||
|
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
||||||
|
0xC6, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x8C, 0x16, 0x66, 0x66, 0x66, 0x86,
|
||||||
|
0x66, 0x66, 0x16, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
private static byte[] haxxStationIconPltt =
|
||||||
|
{
|
||||||
|
0x1F, 0x7C, 0x42, 0x04, 0x83, 0x0C, 0xC5, 0x08, 0xC6, 0x18, 0xE7, 0x1C,
|
||||||
|
0x00, 0x00, 0x29, 0x25, 0x8C, 0x2D, 0xAD, 0x35, 0xCE, 0x39, 0x0F, 0x3E,
|
||||||
|
0x10, 0x42, 0x51, 0x46, 0x94, 0x52, 0x35, 0x23
|
||||||
|
};
|
||||||
|
|
||||||
|
private static byte[] haxxStationServer =
|
||||||
|
{
|
||||||
|
0x52, 0x43, 0x31, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x30, 0x31, 0x20,
|
||||||
|
0x32, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x65, 0x72, 0x69,
|
||||||
|
0x63, 0x6F, 0x6D, 0x00, 0x00, 0x00, 0x48, 0x61, 0x78, 0x78, 0x53, 0x74,
|
||||||
|
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x79, 0x20, 0x47, 0x65, 0x72,
|
||||||
|
0x69, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x73, 0x68, 0x75, 0x74, 0x74, 0x65,
|
||||||
|
0x72, 0x62, 0x75, 0x67, 0x32, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x6E, 0x64, 0x20, 0x41, 0x70,
|
||||||
|
0x61, 0x63, 0x68, 0x65, 0x20, 0x54, 0x68, 0x75, 0x6E, 0x64, 0x65, 0x72,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
private static byte[] exploitData =
|
||||||
|
{
|
||||||
|
0x44, 0x30, 0x9F, 0xE5, 0x2C, 0x00, 0x93, 0xE5, 0x2C, 0x10, 0x9F, 0xE5,
|
||||||
|
0x01, 0x00, 0x40, 0xE0, 0x28, 0x10, 0x9F, 0xE5, 0x01, 0x00, 0x80, 0xE0,
|
||||||
|
0x24, 0x10, 0x9F, 0xE5, 0x24, 0x20, 0x9F, 0xE5, 0x28, 0xE0, 0x9F, 0xE5,
|
||||||
|
0x3E, 0xFF, 0x2F, 0xE1, 0x24, 0xE0, 0x9F, 0xE5, 0x3E, 0xFF, 0x2F, 0xE1,
|
||||||
|
0x01, 0x00, 0xA0, 0xE3, 0x1C, 0xE0, 0x9F, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1,
|
||||||
|
0x00, 0xAE, 0x11, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
||||||
|
0x20, 0x6D, 0x11, 0x00, 0x40, 0xE8, 0x3F, 0x02, 0x08, 0xBB, 0x32, 0x02,
|
||||||
|
0x24, 0xAF, 0x32, 0x02, 0x78, 0x3A, 0x32, 0x02
|
||||||
|
};
|
||||||
|
|
||||||
|
private static byte[] arm7Fix =
|
||||||
|
{
|
||||||
|
0x2C, 0x00, 0x9F, 0xE5, 0x8E, 0x07, 0x80, 0xE2, 0x1C, 0x10, 0x9F, 0xE5,
|
||||||
|
0x1C, 0x20, 0x9F, 0xE5, 0x01, 0x30, 0xD0, 0xE4, 0x01, 0x30, 0xC1, 0xE4,
|
||||||
|
0x01, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0xCA, 0x00, 0x00, 0x9F, 0xE5,
|
||||||
|
0x10, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
private NDS mDownloadStation;
|
||||||
|
private SFSDirectory mFileSystem;
|
||||||
|
private DemoMenu mDemoMenu;
|
||||||
|
|
||||||
|
public DownloadStationPatcher(NDS downloadStation)
|
||||||
|
{
|
||||||
|
mDownloadStation = downloadStation;
|
||||||
|
mFileSystem = mDownloadStation.ToFileSystem();
|
||||||
|
|
||||||
|
SFSDirectory d = mFileSystem.GetDirectoryByPath("//ds_demo");
|
||||||
|
//this is shitty...
|
||||||
|
d.Files.Remove(d.GetFileByPath("ds_demo/ANDEdemo"));
|
||||||
|
d.Files.Remove(d.GetFileByPath("ds_demo/AGFEdemo"));
|
||||||
|
d.Files.Remove(d.GetFileByPath("ds_demo/AMFEclip"));
|
||||||
|
d.Files.Remove(d.GetFileByPath("ds_demo/AMTEdemo"));
|
||||||
|
d.Files.Remove(d.GetFileByPath("ds_demo/APTEdemo"));
|
||||||
|
d.Files.Remove(d.GetFileByPath("ds_demo/ATTEdemo"));
|
||||||
|
d.Files.Remove(d.GetFileByPath("ds_demo/ATTEpush"));
|
||||||
|
d.Files.Remove(d.GetFileByPath("ds_demo/testcode"));
|
||||||
|
d.Files.Remove(d.GetFileByPath("ds_demo/AMCEdemo"));
|
||||||
|
|
||||||
|
mFileSystem.GetFileByPath("//mb/server").Data = haxxStationServer;
|
||||||
|
mFileSystem.GetFileByPath("//mb/icon.nbfc").Data = haxxStationIconImage;
|
||||||
|
mFileSystem.GetFileByPath("//mb/icon.nbfp").Data = haxxStationIconPltt;
|
||||||
|
|
||||||
|
//change banner
|
||||||
|
mDownloadStation.Banner.Banner.Image = haxxStationIconImage;
|
||||||
|
mDownloadStation.Banner.Banner.Pltt = haxxStationIconPltt;
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
mDownloadStation.Banner.Banner.GameName[i] = "HaxxStation\nBy Gericom, shutterbug2000\nand Apache Thunder";
|
||||||
|
|
||||||
|
mDemoMenu = new DemoMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddRom(NDS rom)
|
||||||
|
{
|
||||||
|
if (rom.Header.SubRamAddress >= 0x03000000)
|
||||||
|
{
|
||||||
|
byte[] newArm7 = new byte[rom.SubRom.Length + arm7Fix.Length];
|
||||||
|
Array.Copy(arm7Fix, newArm7, arm7Fix.Length);
|
||||||
|
Array.Copy(rom.SubRom, 0, newArm7, arm7Fix.Length, rom.SubRom.Length);
|
||||||
|
IOUtil.WriteU32LE(newArm7, 0x28, rom.Header.SubEntryAddress);
|
||||||
|
IOUtil.WriteU32LE(newArm7, 0x2C, rom.Header.SubRamAddress);
|
||||||
|
IOUtil.WriteU32LE(newArm7, 0x30, rom.Header.SubSize);
|
||||||
|
rom.SubRom = newArm7;
|
||||||
|
rom.Header.SubSize = (uint)newArm7.Length;
|
||||||
|
rom.Header.SubRamAddress = 0x02380000;
|
||||||
|
rom.Header.SubEntryAddress = 0x02380000;
|
||||||
|
}
|
||||||
|
byte[] newRomFixed = rom.Write(true);
|
||||||
|
|
||||||
|
uint arm9offset = (uint)(newRomFixed[0x20] | (newRomFixed[0x21] << 8) | (newRomFixed[0x22] << 16) | (newRomFixed[0x23] << 24));
|
||||||
|
uint arm9loadaddr = (uint)(newRomFixed[0x28] | (newRomFixed[0x29] << 8) | (newRomFixed[0x2A] << 16) | (newRomFixed[0x2B] << 24));
|
||||||
|
uint arm9size = (uint)(newRomFixed[0x2C] | (newRomFixed[0x2D] << 8) | (newRomFixed[0x2E] << 16) | (newRomFixed[0x2F] << 24));
|
||||||
|
uint arm7offset = (uint)(newRomFixed[0x30] | (newRomFixed[0x31] << 8) | (newRomFixed[0x32] << 16) | (newRomFixed[0x33] << 24));
|
||||||
|
|
||||||
|
//arm9 offset becomes 0x180
|
||||||
|
newRomFixed[0x20] = 0x80;
|
||||||
|
newRomFixed[0x21] = 0x01;
|
||||||
|
newRomFixed[0x22] = 0x00;
|
||||||
|
newRomFixed[0x23] = 0x00;
|
||||||
|
//arm9 load becomes 0x02332C40 (rsa_GetDecodedHash)
|
||||||
|
newRomFixed[0x28] = 0x40;
|
||||||
|
newRomFixed[0x29] = 0x2C;
|
||||||
|
newRomFixed[0x2A] = 0x33;
|
||||||
|
newRomFixed[0x2B] = 0x02;
|
||||||
|
//arm9 size becomes 0x100
|
||||||
|
newRomFixed[0x2C] = 0x00;
|
||||||
|
newRomFixed[0x2D] = 0x01;
|
||||||
|
newRomFixed[0x2E] = 0x00;
|
||||||
|
newRomFixed[0x2F] = 0x00;
|
||||||
|
ushort newcrc = CRC16.GetCRC16(newRomFixed, 0, 0x15E);
|
||||||
|
newRomFixed[0x15E] = (byte)(newcrc & 0xFF);
|
||||||
|
newRomFixed[0x15F] = (byte)(newcrc >> 8);
|
||||||
|
|
||||||
|
Array.Copy(exploitData, 0, newRomFixed, 0x180, exploitData.Length);
|
||||||
|
|
||||||
|
newRomFixed[0x180 + 0x3C] = (byte)(arm7offset & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x3D] = (byte)((arm7offset >> 8) & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x3E] = (byte)((arm7offset >> 16) & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x3F] = (byte)((arm7offset >> 24) & 0xFF);
|
||||||
|
|
||||||
|
newRomFixed[0x180 + 0x40] = (byte)(arm9offset & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x41] = (byte)((arm9offset >> 8) & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x42] = (byte)((arm9offset >> 16) & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x43] = (byte)((arm9offset >> 24) & 0xFF);
|
||||||
|
|
||||||
|
newRomFixed[0x180 + 0x44] = (byte)(arm9loadaddr & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x45] = (byte)((arm9loadaddr >> 8) & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x46] = (byte)((arm9loadaddr >> 16) & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x47] = (byte)((arm9loadaddr >> 24) & 0xFF);
|
||||||
|
|
||||||
|
newRomFixed[0x180 + 0x48] = (byte)(arm9size & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x49] = (byte)((arm9size >> 8) & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x4A] = (byte)((arm9size >> 16) & 0xFF);
|
||||||
|
newRomFixed[0x180 + 0x4B] = (byte)((arm9size >> 24) & 0xFF);
|
||||||
|
|
||||||
|
string fileName = "rom" + mDemoMenu.entries.Count.ToString("0000") + "d";
|
||||||
|
|
||||||
|
var entry = new DemoMenu.DemoMenuEntry()
|
||||||
|
{
|
||||||
|
rating = 1,
|
||||||
|
guideMode = 0x15,
|
||||||
|
touchText1 = "HaxxStation by Gericom,",
|
||||||
|
touchText2 = "shutterbug2000, Apache Thunder",
|
||||||
|
internalName = fileName
|
||||||
|
};
|
||||||
|
if (rom.Banner != null)
|
||||||
|
{
|
||||||
|
string[] lines = rom.Banner.Banner.GameName[1].Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
if (lines.Length > 0)
|
||||||
|
entry.bannerText1 = lines[0];
|
||||||
|
else
|
||||||
|
entry.bannerText1 = "Bannerless Homebrew";
|
||||||
|
if (lines.Length > 1)
|
||||||
|
entry.bannerText2 = lines[1];
|
||||||
|
else
|
||||||
|
entry.bannerText2 = "";
|
||||||
|
entry.bannerImage = rom.Banner.Banner.Image;
|
||||||
|
entry.bannerPalette = rom.Banner.Banner.Pltt;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entry.bannerText1 = "Bannerless Homebrew";
|
||||||
|
entry.bannerText2 = "";
|
||||||
|
entry.bannerImage = new byte[512];
|
||||||
|
entry.bannerPalette = new byte[32];
|
||||||
|
}
|
||||||
|
mDemoMenu.entries.Add(entry);
|
||||||
|
var d = mFileSystem.GetDirectoryByPath("//ds_demo");
|
||||||
|
d.Files.Add(new SFSFile(-1, fileName, d) { Data = newRomFixed });
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public NDS ProduceRom()
|
||||||
|
{
|
||||||
|
string fileName = "rom" + (mDemoMenu.entries.Count - 1).ToString("0000") + "d";
|
||||||
|
while (mDemoMenu.entries.Count < 3)
|
||||||
|
{
|
||||||
|
mDemoMenu.entries.Add(new DemoMenu.DemoMenuEntry()
|
||||||
|
{
|
||||||
|
bannerImage = new byte[512],
|
||||||
|
bannerPalette = new byte[32],
|
||||||
|
bannerText1 = "",
|
||||||
|
bannerText2 = "",
|
||||||
|
rating = 1,
|
||||||
|
guideMode = 0x15,
|
||||||
|
touchText1 = "HaxxStation by Gericom,",
|
||||||
|
touchText2 = "shutterbug2000, Apache Thunder",
|
||||||
|
internalName = fileName
|
||||||
|
});
|
||||||
|
}
|
||||||
|
mFileSystem.GetFileByPath("//ds_demo/demomenu").Data = mDemoMenu.Write();
|
||||||
|
mDownloadStation.FromFileSystem(mFileSystem);
|
||||||
|
return mDownloadStation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,348 +13,116 @@ namespace dspatch
|
|||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
static byte[] lockIconImage =
|
|
||||||
{
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x8A,
|
|
||||||
0x00, 0xA0, 0x88, 0x88, 0x00, 0x88, 0x57, 0x34, 0x80, 0x58, 0x33, 0x33,
|
|
||||||
0x8A, 0x34, 0x04, 0x00, 0xA0, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0xA8, 0x0A, 0x00, 0x00, 0x88, 0x88, 0x0A, 0x00,
|
|
||||||
0x43, 0x75, 0x88, 0x00, 0x33, 0x33, 0x85, 0x08, 0x00, 0x40, 0x43, 0x88,
|
|
||||||
0x00, 0x00, 0x37, 0x85, 0x00, 0x00, 0x40, 0x73, 0x00, 0x00, 0x00, 0x53,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
|
||||||
0x08, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x33,
|
|
||||||
0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x33,
|
|
||||||
0x00, 0x00, 0x00, 0x33, 0xDD, 0xDD, 0xDD, 0xDD, 0xA8, 0x00, 0x00, 0x00,
|
|
||||||
0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
|
||||||
0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00,
|
|
||||||
0xDD, 0xED, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
|
||||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
|
||||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0x29, 0xFF, 0xFF, 0xBF, 0x11, 0xFF, 0xFF, 0x9F, 0x11,
|
|
||||||
0xFF, 0xFF, 0xBF, 0x11, 0xFF, 0xFF, 0xFF, 0x16, 0xDD, 0xDD, 0xDD, 0xDD,
|
|
||||||
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x92, 0xDD, 0xDD, 0xDD,
|
|
||||||
0x11, 0xDB, 0xDD, 0xDD, 0x11, 0xD9, 0xDD, 0xDD, 0x11, 0xDB, 0xDD, 0xDD,
|
|
||||||
0x61, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
|
||||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
|
||||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
|
||||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
|
|
||||||
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x16,
|
|
||||||
0xFF, 0xFF, 0xFF, 0x12, 0xFF, 0xFF, 0xCF, 0x11, 0xFF, 0xFF, 0x9F, 0x11,
|
|
||||||
0xFF, 0xFF, 0x9F, 0x11, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x61, 0xDD, 0xDD, 0xDD, 0x21, 0xDD, 0xDD, 0xDD,
|
|
||||||
0x11, 0xDB, 0xDD, 0xDD, 0x11, 0xD9, 0xDD, 0xDD, 0x11, 0xD9, 0xDD, 0xDD,
|
|
||||||
0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD,
|
|
||||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
|
||||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xDD, 0x00, 0x00,
|
|
||||||
0xDD, 0xDD, 0x00, 0x00, 0xDD, 0xED, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
static byte[] lockIconPltt =
|
|
||||||
{
|
|
||||||
0x1C, 0x3C, 0x07, 0x25, 0x49, 0x25, 0xAA, 0x3D, 0xCB, 0x3D, 0xEC, 0x41,
|
|
||||||
0xEF, 0x25, 0x0E, 0x4A, 0x2F, 0x4E, 0x74, 0x26, 0x71, 0x56, 0xF9, 0x2A,
|
|
||||||
0x5B, 0x2F, 0x5E, 0x1B, 0x7E, 0x37, 0xBF, 0x2F
|
|
||||||
};
|
|
||||||
|
|
||||||
static byte[] haxxStationIconImage =
|
|
||||||
{
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x90, 0x61, 0x66, 0x66, 0x69, 0x66, 0x66, 0x66, 0x61, 0xC8, 0xCC, 0xCC,
|
|
||||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0xCC, 0xCC, 0xCC, 0xCC, 0x66, 0x66, 0x66, 0x66,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x16, 0x09, 0x66, 0x66, 0x66, 0x96,
|
|
||||||
0xCC, 0xCC, 0x8C, 0x16, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xCC, 0xCC, 0x6C,
|
|
||||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C,
|
|
||||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0x8C, 0xCC, 0x6C, 0x45, 0x65, 0x41, 0x85,
|
|
||||||
0x89, 0xE2, 0xC0, 0x27, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0x27, 0x16, 0x54, 0xB7, 0xD5, 0xE0, 0x9D, 0x14,
|
|
||||||
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
|
||||||
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0x99, 0xCC, 0x66,
|
|
||||||
0x5C, 0x11, 0xC5, 0x66, 0x42, 0xEE, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x20, 0x0E, 0x00,
|
|
||||||
0x00, 0x79, 0x00, 0x0B, 0x00, 0x01, 0x70, 0x08, 0xD0, 0x04, 0x2E, 0x00,
|
|
||||||
0xB0, 0x07, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x00, 0x77, 0x0C,
|
|
||||||
0x24, 0x87, 0x52, 0x14, 0x66, 0x14, 0xC9, 0x6C, 0x66, 0xAC, 0xCC, 0x6C,
|
|
||||||
0x66, 0xCC, 0xC1, 0x6C, 0x66, 0x1C, 0x16, 0x6C, 0x66, 0xCC, 0xC1, 0x6C,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x21, 0xA7, 0x00, 0x41, 0x88, 0x47, 0x41,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xF3, 0x63, 0x66, 0x66,
|
|
||||||
0x36, 0x3F, 0x66, 0x66, 0x36, 0x3F, 0x66, 0x66, 0x0D, 0x00, 0xD0, 0x99,
|
|
||||||
0x00, 0x88, 0x00, 0x00, 0x18, 0x44, 0x81, 0x99, 0x76, 0xCC, 0x57, 0x44,
|
|
||||||
0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0x6C, 0xCC, 0x66, 0xC6, 0xC6, 0xC6, 0x66,
|
|
||||||
0xC6, 0x6C, 0xCC, 0x66, 0x90, 0x09, 0x89, 0x00, 0xB0, 0x07, 0x4D, 0x00,
|
|
||||||
0xD0, 0x04, 0x10, 0x00, 0x00, 0x01, 0x80, 0x05, 0x00, 0x78, 0x00, 0x0E,
|
|
||||||
0x00, 0x10, 0x0D, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C, 0x66, 0xCC, 0xCC, 0x6C,
|
|
||||||
0x61, 0xC8, 0xCC, 0xCC, 0x68, 0x66, 0x66, 0x66, 0x80, 0x61, 0x66, 0x66,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x63, 0xFF, 0x6F,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xCC, 0xCC, 0xCC, 0xCC,
|
|
||||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0xC6, 0xCC, 0xCC, 0x66, 0xC6, 0xCC, 0xCC, 0x66,
|
|
||||||
0xC6, 0xCC, 0xCC, 0x66, 0xCC, 0xCC, 0x8C, 0x16, 0x66, 0x66, 0x66, 0x86,
|
|
||||||
0x66, 0x66, 0x16, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
static byte[] haxxStationIconPltt =
|
|
||||||
{
|
|
||||||
0x1F, 0x7C, 0x42, 0x04, 0x83, 0x0C, 0xC5, 0x08, 0xC6, 0x18, 0xE7, 0x1C,
|
|
||||||
0x00, 0x00, 0x29, 0x25, 0x8C, 0x2D, 0xAD, 0x35, 0xCE, 0x39, 0x0F, 0x3E,
|
|
||||||
0x10, 0x42, 0x51, 0x46, 0x94, 0x52, 0x35, 0x23
|
|
||||||
};
|
|
||||||
|
|
||||||
static byte[] haxxStationServer =
|
|
||||||
{
|
|
||||||
0x52, 0x43, 0x31, 0x20, 0x32, 0x30, 0x30, 0x36, 0x20, 0x30, 0x31, 0x20,
|
|
||||||
0x32, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x65, 0x72, 0x69,
|
|
||||||
0x63, 0x6F, 0x6D, 0x00, 0x00, 0x00, 0x48, 0x61, 0x78, 0x78, 0x53, 0x74,
|
|
||||||
0x61, 0x74, 0x69, 0x6F, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x79, 0x20, 0x47, 0x65, 0x72,
|
|
||||||
0x69, 0x63, 0x6F, 0x6D, 0x2C, 0x20, 0x73, 0x68, 0x75, 0x74, 0x74, 0x65,
|
|
||||||
0x72, 0x62, 0x75, 0x67, 0x32, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x6E, 0x64, 0x20, 0x41, 0x70,
|
|
||||||
0x61, 0x63, 0x68, 0x65, 0x20, 0x54, 0x68, 0x75, 0x6E, 0x64, 0x65, 0x72,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
static byte[] dsHash =
|
static byte[] dsHash =
|
||||||
{
|
{
|
||||||
0xF1, 0x8B, 0x55, 0xF3, 0xE1, 0x25, 0x9C, 0x03, 0xE1, 0x0D, 0x0E, 0xCB,
|
0xF1, 0x8B, 0x55, 0xF3, 0xE1, 0x25, 0x9C, 0x03, 0xE1, 0x0D, 0x0E, 0xCB,
|
||||||
0x54, 0x96, 0x93, 0xB4, 0x29, 0x05, 0xCE, 0xB5
|
0x54, 0x96, 0x93, 0xB4, 0x29, 0x05, 0xCE, 0xB5
|
||||||
};
|
};
|
||||||
|
|
||||||
static byte[] exploitData =
|
|
||||||
{
|
|
||||||
0x44, 0x30, 0x9F, 0xE5, 0x2C, 0x00, 0x93, 0xE5, 0x2C, 0x10, 0x9F, 0xE5,
|
|
||||||
0x01, 0x00, 0x40, 0xE0, 0x28, 0x10, 0x9F, 0xE5, 0x01, 0x00, 0x80, 0xE0,
|
|
||||||
0x24, 0x10, 0x9F, 0xE5, 0x24, 0x20, 0x9F, 0xE5, 0x28, 0xE0, 0x9F, 0xE5,
|
|
||||||
0x3E, 0xFF, 0x2F, 0xE1, 0x24, 0xE0, 0x9F, 0xE5, 0x3E, 0xFF, 0x2F, 0xE1,
|
|
||||||
0x01, 0x00, 0xA0, 0xE3, 0x1C, 0xE0, 0x9F, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1,
|
|
||||||
0x00, 0xAE, 0x11, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
|
|
||||||
0x20, 0x6D, 0x11, 0x00, 0x40, 0xE8, 0x3F, 0x02, 0x08, 0xBB, 0x32, 0x02,
|
|
||||||
0x24, 0xAF, 0x32, 0x02, 0x78, 0x3A, 0x32, 0x02
|
|
||||||
};
|
|
||||||
|
|
||||||
static byte[] arm7Fix =
|
|
||||||
{
|
|
||||||
0x2C, 0x00, 0x9F, 0xE5, 0x8E, 0x07, 0x80, 0xE2, 0x1C, 0x10, 0x9F, 0xE5,
|
|
||||||
0x1C, 0x20, 0x9F, 0xE5, 0x01, 0x30, 0xD0, 0xE4, 0x01, 0x30, 0xC1, 0xE4,
|
|
||||||
0x01, 0x20, 0x52, 0xE2, 0xFB, 0xFF, 0xFF, 0xCA, 0x00, 0x00, 0x9F, 0xE5,
|
|
||||||
0x10, 0xFF, 0x2F, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
static void PrintUsage()
|
static void PrintUsage()
|
||||||
{
|
{
|
||||||
Console.WriteLine("Usage: dspatch download_station.nds rom_to_boot.nds result.nds");
|
Console.WriteLine("Usage: dspatch -s download_station.nds -o result.nds [-i rom1.nds] [-I romfolder1]");
|
||||||
|
Console.WriteLine("You can add multiple roms by using -I or -i multiple times");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
Console.WriteLine("== DS Download Station Patcher v1.0 ==");
|
Console.WriteLine("== DS Download Station Patcher v1.0 ==");
|
||||||
Console.WriteLine("Exploit by Gericom, shutterbug2000 and Apache Thunder\n");
|
Console.WriteLine("Exploit by Gericom, shutterbug2000 and Apache Thunder\n");
|
||||||
if (args.Length != 3)
|
|
||||||
PrintUsage();
|
if (args.Length <= 1)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
byte[] dsdata = File.ReadAllBytes(args[0]);
|
PrintUsage();
|
||||||
byte[] sha1 = SHA1.Create().ComputeHash(dsdata);
|
return;
|
||||||
for (int i = 0; i < 20; i++)
|
|
||||||
{
|
|
||||||
if (sha1[i] != dsHash[i])
|
|
||||||
{
|
|
||||||
Console.WriteLine("Error: Invalid download station rom!");
|
|
||||||
Console.WriteLine("The patcher is only compatible with:");
|
|
||||||
Console.WriteLine("xxxx - DS Download Station - Volume 1 (Kiosk WiFi Demo Cart) (U)(Independent).nds");
|
|
||||||
Console.WriteLine("SHA1: F18B55F3E1259C03E10D0ECB549693B42905CEB5");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NDS downloadStation = new NDS(dsdata);
|
|
||||||
var fs = downloadStation.ToFileSystem();
|
|
||||||
byte[] newRom = File.ReadAllBytes(args[1]);
|
|
||||||
NDS newRom2 = new NDS(newRom);
|
|
||||||
if (newRom2.Header.SubRamAddress >= 0x03000000)
|
|
||||||
{
|
|
||||||
byte[] newArm7 = new byte[newRom2.SubRom.Length + arm7Fix.Length];
|
|
||||||
Array.Copy(arm7Fix, newArm7, arm7Fix.Length);
|
|
||||||
Array.Copy(newRom2.SubRom, 0, newArm7, arm7Fix.Length, newRom2.SubRom.Length);
|
|
||||||
IOUtil.WriteU32LE(newArm7, 0x28, newRom2.Header.SubEntryAddress);
|
|
||||||
IOUtil.WriteU32LE(newArm7, 0x2C, newRom2.Header.SubRamAddress);
|
|
||||||
IOUtil.WriteU32LE(newArm7, 0x30, newRom2.Header.SubSize);
|
|
||||||
newRom2.SubRom = newArm7;
|
|
||||||
newRom2.Header.SubSize = (uint)newArm7.Length;
|
|
||||||
newRom2.Header.SubRamAddress = 0x02380000;
|
|
||||||
newRom2.Header.SubEntryAddress = 0x02380000;
|
|
||||||
}
|
|
||||||
byte[] newRomFixed = newRom2.Write(true);
|
|
||||||
{
|
|
||||||
uint arm9offset = (uint)(newRomFixed[0x20] | (newRomFixed[0x21] << 8) | (newRomFixed[0x22] << 16) | (newRomFixed[0x23] << 24));
|
|
||||||
uint arm9loadaddr = (uint)(newRomFixed[0x28] | (newRomFixed[0x29] << 8) | (newRomFixed[0x2A] << 16) | (newRomFixed[0x2B] << 24));
|
|
||||||
uint arm9size = (uint)(newRomFixed[0x2C] | (newRomFixed[0x2D] << 8) | (newRomFixed[0x2E] << 16) | (newRomFixed[0x2F] << 24));
|
|
||||||
uint arm7offset = (uint)(newRomFixed[0x30] | (newRomFixed[0x31] << 8) | (newRomFixed[0x32] << 16) | (newRomFixed[0x33] << 24));
|
|
||||||
|
|
||||||
//arm9 offset becomes 0x180
|
|
||||||
newRomFixed[0x20] = 0x80;
|
|
||||||
newRomFixed[0x21] = 0x01;
|
|
||||||
newRomFixed[0x22] = 0x00;
|
|
||||||
newRomFixed[0x23] = 0x00;
|
|
||||||
//arm9 load becomes 0x02332C40 (rsa_GetDecodedHash)
|
|
||||||
newRomFixed[0x28] = 0x40;
|
|
||||||
newRomFixed[0x29] = 0x2C;
|
|
||||||
newRomFixed[0x2A] = 0x33;
|
|
||||||
newRomFixed[0x2B] = 0x02;
|
|
||||||
//arm9 size becomes 0x100
|
|
||||||
newRomFixed[0x2C] = 0x00;
|
|
||||||
newRomFixed[0x2D] = 0x01;
|
|
||||||
newRomFixed[0x2E] = 0x00;
|
|
||||||
newRomFixed[0x2F] = 0x00;
|
|
||||||
ushort newcrc = CRC16.GetCRC16(newRomFixed, 0, 0x15E);
|
|
||||||
newRomFixed[0x15E] = (byte)(newcrc & 0xFF);
|
|
||||||
newRomFixed[0x15F] = (byte)(newcrc >> 8);
|
|
||||||
|
|
||||||
exploitData[0x3C] = (byte)(arm7offset & 0xFF);
|
|
||||||
exploitData[0x3D] = (byte)((arm7offset >> 8) & 0xFF);
|
|
||||||
exploitData[0x3E] = (byte)((arm7offset >> 16) & 0xFF);
|
|
||||||
exploitData[0x3F] = (byte)((arm7offset >> 24) & 0xFF);
|
|
||||||
|
|
||||||
exploitData[0x40] = (byte)(arm9offset & 0xFF);
|
|
||||||
exploitData[0x41] = (byte)((arm9offset >> 8) & 0xFF);
|
|
||||||
exploitData[0x42] = (byte)((arm9offset >> 16) & 0xFF);
|
|
||||||
exploitData[0x43] = (byte)((arm9offset >> 24) & 0xFF);
|
|
||||||
|
|
||||||
exploitData[0x44] = (byte)(arm9loadaddr & 0xFF);
|
|
||||||
exploitData[0x45] = (byte)((arm9loadaddr >> 8) & 0xFF);
|
|
||||||
exploitData[0x46] = (byte)((arm9loadaddr >> 16) & 0xFF);
|
|
||||||
exploitData[0x47] = (byte)((arm9loadaddr >> 24) & 0xFF);
|
|
||||||
|
|
||||||
exploitData[0x48] = (byte)(arm9size & 0xFF);
|
|
||||||
exploitData[0x49] = (byte)((arm9size >> 8) & 0xFF);
|
|
||||||
exploitData[0x4A] = (byte)((arm9size >> 16) & 0xFF);
|
|
||||||
exploitData[0x4B] = (byte)((arm9size >> 24) & 0xFF);
|
|
||||||
|
|
||||||
Array.Copy(exploitData, 0, newRomFixed, 0x180, exploitData.Length);
|
|
||||||
}
|
|
||||||
SFSDirectory d = fs.GetDirectoryByPath("//ds_demo");
|
|
||||||
d.Files.Add(new SFSFile(-1, "rom1.nds", d) { Data = newRomFixed });
|
|
||||||
//this is shitty...
|
|
||||||
d.Files.Remove(d.GetFileByPath("ds_demo/ANDEdemo"));
|
|
||||||
d.Files.Remove(d.GetFileByPath("ds_demo/AGFEdemo"));
|
|
||||||
d.Files.Remove(d.GetFileByPath("ds_demo/AMFEclip"));
|
|
||||||
d.Files.Remove(d.GetFileByPath("ds_demo/AMTEdemo"));
|
|
||||||
d.Files.Remove(d.GetFileByPath("ds_demo/APTEdemo"));
|
|
||||||
d.Files.Remove(d.GetFileByPath("ds_demo/ATTEdemo"));
|
|
||||||
d.Files.Remove(d.GetFileByPath("ds_demo/ATTEpush"));
|
|
||||||
d.Files.Remove(d.GetFileByPath("ds_demo/testcode"));
|
|
||||||
d.Files.Remove(d.GetFileByPath("ds_demo/AMCEdemo"));
|
|
||||||
DemoMenu menu = new DemoMenu();
|
|
||||||
menu.entries = new DemoMenu.DemoMenuEntry[]
|
|
||||||
{
|
|
||||||
new DemoMenu.DemoMenuEntry()
|
|
||||||
{
|
|
||||||
rating = 1,
|
|
||||||
guideMode = 0x15,
|
|
||||||
touchText1 = "HaxxStation by Gericom,",
|
|
||||||
touchText2 = "shutterbug2000, Apache Thunder",
|
|
||||||
internalName = "rom1.nds"
|
|
||||||
},
|
|
||||||
new DemoMenu.DemoMenuEntry()
|
|
||||||
{
|
|
||||||
bannerImage = new byte[512],
|
|
||||||
bannerPalette = new byte[32],
|
|
||||||
bannerText1 = "",
|
|
||||||
bannerText2 = "",
|
|
||||||
rating = 1,
|
|
||||||
guideMode = 0x15,
|
|
||||||
touchText1 = "HaxxStation by Gericom,",
|
|
||||||
touchText2 = "shutterbug2000, Apache Thunder",
|
|
||||||
internalName = "rom1.nds"
|
|
||||||
},
|
|
||||||
new DemoMenu.DemoMenuEntry()
|
|
||||||
{
|
|
||||||
bannerImage = new byte[512],
|
|
||||||
bannerPalette = new byte[32],
|
|
||||||
bannerText1 = "",
|
|
||||||
bannerText2 = "",
|
|
||||||
rating = 1,
|
|
||||||
guideMode = 0x15,
|
|
||||||
touchText1 = "HaxxStation by Gericom,",
|
|
||||||
touchText2 = "shutterbug2000, Apache Thunder",
|
|
||||||
internalName = "rom1.nds"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (newRom2.Banner != null)
|
|
||||||
{
|
|
||||||
string[] lines = newRom2.Banner.Banner.GameName[1].Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (lines.Length > 0)
|
|
||||||
menu.entries[0].bannerText1 = lines[0];
|
|
||||||
else
|
|
||||||
menu.entries[0].bannerText1 = "Bannerless Homebrew";
|
|
||||||
if (lines.Length > 1)
|
|
||||||
menu.entries[0].bannerText2 = lines[1];
|
|
||||||
else
|
|
||||||
menu.entries[0].bannerText2 = "";
|
|
||||||
menu.entries[0].bannerImage = newRom2.Banner.Banner.Image;
|
|
||||||
menu.entries[0].bannerPalette = newRom2.Banner.Banner.Pltt;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
menu.entries[0].bannerText1 = "Bannerless Homebrew";
|
|
||||||
menu.entries[0].bannerText2 = "";
|
|
||||||
menu.entries[0].bannerImage = new byte[512];
|
|
||||||
menu.entries[0].bannerPalette = new byte[32];
|
|
||||||
}
|
|
||||||
byte[] demoMenu = menu.Write();
|
|
||||||
fs.GetFileByPath("//ds_demo/demomenu").Data = demoMenu;
|
|
||||||
fs.GetFileByPath("//mb/server").Data = haxxStationServer;
|
|
||||||
fs.GetFileByPath("//mb/icon.nbfc").Data = haxxStationIconImage;
|
|
||||||
fs.GetFileByPath("//mb/icon.nbfp").Data = haxxStationIconPltt;
|
|
||||||
downloadStation.FromFileSystem(fs);
|
|
||||||
//change banner
|
|
||||||
downloadStation.Banner.Banner.Image = haxxStationIconImage;
|
|
||||||
downloadStation.Banner.Banner.Pltt = haxxStationIconPltt;
|
|
||||||
for(int i = 0; i < 6; i++)
|
|
||||||
downloadStation.Banner.Banner.GameName[i] = "HaxxStation\nBy Gericom, shutterbug2000\nand Apache Thunder";
|
|
||||||
byte[] finalResult = downloadStation.Write();
|
|
||||||
File.Create(args[2]).Close();
|
|
||||||
File.WriteAllBytes(args[2], finalResult);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string dsPath = null;
|
||||||
|
string outPath = null;
|
||||||
|
List<string> romPaths = new List<string>();
|
||||||
|
string filePath;
|
||||||
|
//parse arguments
|
||||||
|
int q = 0;
|
||||||
|
while (q < args.Length - 1)
|
||||||
|
{
|
||||||
|
string arg = args[q++];
|
||||||
|
switch (arg)
|
||||||
|
{
|
||||||
|
case "-s":
|
||||||
|
filePath = args[q++];
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Error: File (" + filePath + ") does not exist!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dsPath = filePath;
|
||||||
|
break;
|
||||||
|
case "-o":
|
||||||
|
outPath = args[q++];
|
||||||
|
break;
|
||||||
|
case "-i":
|
||||||
|
filePath = args[q++];
|
||||||
|
if (!File.Exists(filePath))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Error: File (" + filePath + ") does not exist!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
romPaths.Add(filePath);
|
||||||
|
break;
|
||||||
|
case "-I":
|
||||||
|
string dirPath = args[q++];
|
||||||
|
if (!Directory.Exists(dirPath))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Error: Directory (" + dirPath + ") does not exist!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
romPaths.AddRange(Directory.GetFiles(dirPath, "*.nds"));
|
||||||
|
romPaths.AddRange(Directory.GetFiles(dirPath, "*.srl"));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Console.WriteLine("Error: Invalid argument (" + arg + ")\n");
|
||||||
|
PrintUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dsPath == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Error: Specify a download station rom!\n");
|
||||||
|
PrintUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (outPath == null)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Error: Specify a destination path!\n");
|
||||||
|
PrintUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (romPaths.Count == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Error: Specify at least 1 rom!\n");
|
||||||
|
PrintUsage();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] dsdata = File.ReadAllBytes(dsPath);
|
||||||
|
byte[] sha1 = SHA1.Create().ComputeHash(dsdata);
|
||||||
|
for (int i = 0; i < 20; i++)
|
||||||
|
{
|
||||||
|
if (sha1[i] != dsHash[i])
|
||||||
|
{
|
||||||
|
Console.WriteLine("Error: Invalid download station rom!");
|
||||||
|
Console.WriteLine("The patcher is only compatible with:");
|
||||||
|
Console.WriteLine("xxxx - DS Download Station - Volume 1 (Kiosk WiFi Demo Cart) (U)(Independent).nds");
|
||||||
|
Console.WriteLine("SHA1: F18B55F3E1259C03E10D0ECB549693B42905CEB5");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DownloadStationPatcher p = new DownloadStationPatcher(new NDS(dsdata));
|
||||||
|
foreach(var r in romPaths)
|
||||||
|
p.AddRom(new NDS(File.ReadAllBytes(r)));
|
||||||
|
byte[] finalResult = p.ProduceRom().Write();
|
||||||
|
File.Create(outPath).Close();
|
||||||
|
File.WriteAllBytes(outPath, finalResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="DownloadStationPatcher.cs" />
|
||||||
<Compile Include="DS\DemoMenu.cs" />
|
<Compile Include="DS\DemoMenu.cs" />
|
||||||
<Compile Include="IO\IOUtil.cs" />
|
<Compile Include="IO\IOUtil.cs" />
|
||||||
<Compile Include="Nitro\ARM9.cs" />
|
<Compile Include="Nitro\ARM9.cs" />
|
||||||
|
Loading…
Reference in New Issue
Block a user