From 0e1ed4a3b3883d639b0a2eae865dda1a635f62bf Mon Sep 17 00:00:00 2001 From: "e.bovendeur" Date: Sat, 10 Apr 2010 09:15:22 +0000 Subject: [PATCH] - Fixed Hermes rev5 issues (I think :)) - Added support for ciosx (yes, including FAT/NTFS) (As always, say thanks to oggzee for this) - Fixed bug with game specific settings (which *could* end up using other settings than you expected) - Removed fat_ffs for now (save game emulation might conflict with FAT/NTFS support, we have to test this) - Maybe more, but I forgot them, I think --- data/ehcmodule_frag_v4.bin | Bin 68696 -> 0 bytes data/ehcmodule_frag_v5.bin | Bin 27774 -> 0 bytes gui.pnproj | 2 +- gui.pnps | 2 +- source/audio.cpp | 4 + source/main.cpp | 112 +----- source/menu.cpp | 51 +-- source/menu.h | 2 +- source/mload/dip_plugin_249.c | 334 ++++++++++++++++ source/mload/dip_plugin_249.h | 3 + source/mload/fatffs_util.c | 291 -------------- source/mload/fatffs_util.h | 24 -- source/mload/mload.c | 153 +++----- source/mload/mload.h | 2 + source/mload/mload_modules.c | 144 ++----- source/patches/fst.c | 6 +- source/prompts/PromptWindows.cpp | 8 - source/prompts/TitleBrowser.cpp | 2 +- source/settings/Settings.cpp | 78 +--- source/settings/cfg.c | 36 +- source/settings/cfg.h | 12 +- source/{sys.cpp => sys.c} | 606 +++++++++++++++-------------- source/sys.h | 17 + source/usbloader/apploader.c | 3 +- source/usbloader/disc.c | 43 +- source/usbloader/frag.c | 27 +- source/usbloader/usbstorage2.c | 4 +- source/usbloader/wbfs.cpp | 10 - source/usbloader/wbfs/wbfs_fat.cpp | 3 - source/usbloader/wdvd.c | 52 ++- source/usbloader/wdvd.h | 2 + source/video.h | 4 +- source/wad/title.h | 2 +- 33 files changed, 953 insertions(+), 1086 deletions(-) delete mode 100644 data/ehcmodule_frag_v4.bin delete mode 100644 data/ehcmodule_frag_v5.bin create mode 100644 source/mload/dip_plugin_249.c create mode 100644 source/mload/dip_plugin_249.h delete mode 100644 source/mload/fatffs_util.c delete mode 100644 source/mload/fatffs_util.h rename source/{sys.cpp => sys.c} (79%) diff --git a/data/ehcmodule_frag_v4.bin b/data/ehcmodule_frag_v4.bin deleted file mode 100644 index 869e15cf0b89da12c85d8515dc35ee81073c9549..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68696 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 Tie9v99B?Dy>@Q8~dF1;)lrmbk diff --git a/data/ehcmodule_frag_v5.bin b/data/ehcmodule_frag_v5.bin deleted file mode 100644 index 894727ea067e18df8aa718be196106e49e455075..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27774 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

`1Lv2~v+^&`^ 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 \ No newline at end of file + \ No newline at end of file diff --git a/gui.pnps b/gui.pnps index 37a2c6da..e62a4311 100644 --- a/gui.pnps +++ b/gui.pnps @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/source/audio.cpp b/source/audio.cpp index b8e301ad..afbc67ce 100644 --- a/source/audio.cpp +++ b/source/audio.cpp @@ -31,3 +31,7 @@ void ShutdownAudio() { ASND_Pause(1); ASND_End(); } + +extern "C" void StopAudio() { + ShutdownAudio(); +} diff --git a/source/main.cpp b/source/main.cpp index c79c7117..70df64ab 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -95,21 +95,6 @@ static void BootUpProblems() time_t endtime = time(0) + 30; do { - /*ret2 = IOS_ReloadIOSsafe(249); - if (ret2 < 0) { - ret2 = IOS_ReloadIOSsafe(222); - SDCard_Init(); - load_ehc_module(); - SDCard_deInit(); - if(ret2 <0) { - boottext.SetText("ERROR: cIOS could not be loaded!"); - bootimage.Draw(); - boottext.Draw(); - Menu_Render(); - sleep(5); - SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); - } - }*/ USBDevice_deInit(); USBDevice_Init(); ret2 = WBFS_Init(WBFS_DEVICE_USB); @@ -162,7 +147,8 @@ void InitTextVideo () } dbvideo=1; VIDEO_Init(); - // get default video mode + + // get default video mode GXRModeObj *vmode = VIDEO_GetPreferredMode(NULL); // widescreen fix @@ -293,7 +279,7 @@ main(int argc, char *argv[]) if (ret < 0) { - printf("\n\tIOS 249 failed, reloading ios 222..."); + printf("\n\tIOS 249 failed, reloading ios 222..."); ret = IOS_ReloadIOSsafe(222); printf("%d", ret); @@ -317,12 +303,7 @@ main(int argc, char *argv[]) } } } - printf("\n\tInitialize sd card"); - SDCard_Init(); - printf("\n\tLoad ehc module"); - load_ehc_module(); - printf("\n\tdeinit sd card"); - SDCard_deInit(); + load_ehc_module(); } printf("\n\tInit wbfs..."); @@ -334,22 +315,8 @@ main(int argc, char *argv[]) printf("\n\tYou have issues with a slow disc, or a difficult disc\n\tReloading 222..."); ret = IOS_ReloadIOSsafe(222); printf("%d", ret); - /*if(ret < 0) { - // printf("\n\tSleeping for 4 seconds"); - // sleep(4); - - InitVideo(); // Initialise video - Menu_Render(); - BootUpProblems(); - startupproblem = true; - ret = 1; - }*/ - printf("\n\tInitialize sd card"); - SDCard_Init(); printf("\n\tLoad ehc module"); load_ehc_module(); - printf("\n\tdeinit sd card"); - SDCard_deInit(); printf("\n\tInitialize wbfs..."); USBDevice_deInit(); @@ -407,66 +374,25 @@ main(int argc, char *argv[]) // gprintf("\n\tbootDevice = %s",bootDevice); /* Load Custom IOS */ - if ((Settings.cios == ios222 && IOS_GetVersion() != 222) || - (Settings.cios == ios223 && IOS_GetVersion() != 223)) - { - printf("\n\tReloading IOS to config setting (%d)...", Settings.cios == ios222 ? 222 : 223); - SDCard_deInit(); // unmount SD for reloading IOS - USBDevice_deInit(); // unmount USB for reloading IOS - USBStorage2_Deinit(); - ret = IOS_ReloadIOSsafe(Settings.cios == ios222 ? 222 : 223); - printf("%d", ret); + if (Settings.cios != IOS_GetVersion()) + { + printf("\n\tReloading IOS to config setting (%d)...", ciosSetting2Cios(Settings.cios)); + if (Sys_IosReload(ciosSetting2Cios(Settings.cios)) < 0) { + int alt_ios = (Settings.cios == ios222 || Settings.cios == ios223) ? 249 : 222; + ret = Sys_IosReload(alt_ios); + + if (ret < 0) + { + printf("\nERROR: cIOS could not be loaded!"); + sleep(5); + exit(0); + } + } SDCard_Init(); - load_ehc_module(); - if (ret < 0) - { - SDCard_deInit(); - Settings.cios = ios249; - ret = IOS_ReloadIOSsafe(249); - // now mount SD:/ //no need to keep mindlessly mounting and unmounting SD card - SDCard_Init(); - } + } - USBDevice_Init(); // and mount USB:/ - WBFS_Init(WBFS_DEVICE_USB); - } else if ((Settings.cios == ios249 && IOS_GetVersion() != 249) || - (Settings.cios == ios250 && IOS_GetVersion() != 250)) - { - - printf("\n\tReloading IOS to config setting (%d)...", ios249 ? 249 : 250); - SDCard_deInit(); // unmount SD for reloading IOS - USBDevice_deInit(); // unmount USB for reloading IOS - USBStorage2_Deinit(); - ret = IOS_ReloadIOSsafe(ios249 ? 249 : 250); - printf("%d", ret); - if (ret < 0) - { - Settings.cios = ios222; - ret = IOS_ReloadIOSsafe(222); - SDCard_Init(); - load_ehc_module(); - } - - else SDCard_Init(); // now mount SD:/ //no need to keep mindlessly mounting and unmounting SD card - USBDevice_Init(); // and mount USB:/ - WBFS_Init(WBFS_DEVICE_USB); - } - - // Partition_GetList(&partitions); - - if (ret < 0) - { - printf("\nERROR: cIOS could not be loaded!"); - sleep(5); - exit(0); - //SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); - } - //gprintf("\n\tcIOS = %u (Rev %u)",IOS_GetVersion(), IOS_GetRevision());//don't need gprintf if sending console shit to gecko, too printf("\n\tcIOS = %u (Rev %u)",IOS_GetVersion(), IOS_GetRevision()); - // printf("Sleeping for 5 seconds\n"); - // sleep(5); - //if a ID was passed via args copy it and try to boot it after the partition is mounted //its not really a headless mode. more like hairless. if (argc > 1 && argv[1]) diff --git a/source/menu.cpp b/source/menu.cpp index 215bf1b8..657bf22c 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -25,9 +25,9 @@ #include "usbloader/getentries.h" #include "wad/title.h" #include "xml/xml.h" -#include "audio.h" #include "gecko.h" #include "menu.h" +#include "audio.h" #include "sys.h" #include "wpad.h" #include "settings/newtitles.h" @@ -345,6 +345,7 @@ int MainMenu(int menu) { delete coverImg; delete fontClock; delete fontSystem; + ShutdownAudio(); StopGX(); gettextCleanUp(); @@ -414,7 +415,6 @@ int MainMenu(int menu) { } } - int ret = 0; header = (mountMethod?dvdheader:&gameList[gameSelected]); @@ -433,48 +433,9 @@ int MainMenu(int menu) { alternatedoloffset = game_cfg->alternatedolstart; } reloadblock = game_cfg->iosreloadblock; - } else { - videoChoice = Settings.video; - languageChoice = Settings.language; - ocarinaChoice = Settings.ocarina; - viChoice = Settings.vpatch; - if (Settings.cios == ios222) { - iosChoice = i222; - } else { - iosChoice = i249; - } - fix002 = Settings.error002; - countrystrings = Settings.patchcountrystrings; - if (!altdoldefault) { - alternatedol = off; - alternatedoloffset = 0; - } - reloadblock = off; } - int ios2; - - switch (iosChoice) { - case i249: - ios2 = 249; - break; - - case i222: - ios2 = 222; - break; - - case i223: - ios2 = 223; - break; - - default: - ios2 = 249; - break; - } - - // When the selected ios is 249, and you're loading from FAT, reset ios to 222 - if (load_from_fs != PART_FS_WBFS && ios2 == 249) { - ios2 = 222; - } + + int ios2 = ciosSetting2Cios(iosChoice); bool onlinefix = ShutdownWC24(); // You cannot reload ios when loading from fat @@ -490,10 +451,6 @@ int MainMenu(int menu) { ret = get_frag_list(header->id); gprintf("%d\n", ret); - gprintf("\nSetting fragment list..."); - ret = set_frag_list(header->id); - gprintf("%d\n", ret); - ret = Disc_SetUSB(header->id); if (ret < 0) Sys_BackToLoader(); gprintf("\n\tUSB set to game"); diff --git a/source/menu.h b/source/menu.h index 0ffb3a75..eec2b7df 100644 --- a/source/menu.h +++ b/source/menu.h @@ -14,7 +14,7 @@ #include "main.h" void InitGUIThreads(void); -void ExitGUIThreads(void); +extern "C" void ExitGUIThreads(void); int MainMenu (int menuitem); diff --git a/source/mload/dip_plugin_249.c b/source/mload/dip_plugin_249.c new file mode 100644 index 00000000..22ef3def --- /dev/null +++ b/source/mload/dip_plugin_249.c @@ -0,0 +1,334 @@ +#define size_dip_plugin_249 5276 + +unsigned char dip_plugin_249[5276] __attribute__((aligned (32)))={ + 0x7f, 0x45, 0x4c, 0x46, 0x01, 0x02, 0x01, 0x61, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x28, 0x00, 0x00, 0x00, 0x01, 0x13, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x34, 0x00, 0x20, 0x00, 0x05, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xa0, 0x00, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0xa0, + 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0xd4, 0x00, 0xf0, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x08, 0x13, 0x70, 0x00, 0x00, + 0x13, 0x70, 0x00, 0x00, 0x00, 0x00, 0x12, 0xa4, 0x00, 0x00, 0x12, 0xa4, 0x00, 0xf0, 0x00, 0x05, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0xac, 0x13, 0x70, 0x20, 0x00, + 0x13, 0x70, 0x20, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x03, 0xc3, 0x00, 0x00, 0xf0, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, + 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x13, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x7f, 0x13, 0x73, 0xe3, 0x00, 0xe3, 0xa0, 0x00, 0x00, 0xe3, 0xa0, 0x10, 0x00, + 0xe5, 0x9f, 0x30, 0x00, 0xe1, 0x2f, 0xff, 0x13, 0x13, 0x70, 0x03, 0x51, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x4b, 0x06, 0xb0, 0x89, 0x93, 0x00, + 0x46, 0x68, 0x23, 0x00, 0x21, 0x00, 0x22, 0x00, 0x93, 0x01, 0x93, 0x02, 0xf0, 0x00, 0xf9, 0x1f, + 0xb0, 0x09, 0xbd, 0x00, 0xe3, 0x00, 0x00, 0x00, 0xb5, 0x10, 0x1c, 0x03, 0x22, 0x20, 0x1c, 0x0c, + 0x48, 0x09, 0x1c, 0x19, 0xf0, 0x01, 0xf8, 0xa0, 0x4a, 0x08, 0x23, 0x01, 0x68, 0x11, 0x42, 0x19, + 0xd1, 0xfc, 0x2c, 0x00, 0xd0, 0x04, 0x1c, 0x20, 0x49, 0x03, 0x22, 0x20, 0xf0, 0x01, 0xf8, 0x94, + 0x4b, 0x03, 0x68, 0x18, 0xbd, 0x10, 0x46, 0xc0, 0x0d, 0x00, 0x60, 0x00, 0x0d, 0x00, 0x60, 0x1c, + 0x0d, 0x00, 0x60, 0x20, 0xb5, 0xf0, 0xb0, 0x8b, 0x1c, 0x07, 0x0a, 0xcb, 0x20, 0xa0, 0x1c, 0x0d, + 0x92, 0x01, 0x93, 0x00, 0x02, 0x00, 0x26, 0x00, 0xac, 0x02, 0xe0, 0x17, 0x22, 0x20, 0x21, 0x00, + 0x1c, 0x20, 0xf0, 0x01, 0xf8, 0xb9, 0x4b, 0x0c, 0x1c, 0x38, 0x60, 0x23, 0x23, 0x00, 0x60, 0x63, + 0x60, 0xa3, 0x9b, 0x00, 0x1c, 0x29, 0x60, 0xe3, 0x9b, 0x01, 0x36, 0x01, 0x61, 0x23, 0xf0, 0x00, + 0xed, 0x2a, 0x1c, 0x20, 0x1c, 0x39, 0x1c, 0x2a, 0xf0, 0x00, 0xf8, 0xd9, 0x2e, 0x0f, 0xd8, 0x01, + 0x28, 0x00, 0xd1, 0xe3, 0xb0, 0x0b, 0xbd, 0xf0, 0xd0, 0x00, 0x00, 0x00, 0xb5, 0xf0, 0xb0, 0x83, + 0x24, 0x80, 0x93, 0x01, 0x01, 0x24, 0x18, 0x53, 0x90, 0x00, 0x1c, 0x0f, 0x1c, 0x16, 0x42, 0xa3, + 0xd9, 0x01, 0x24, 0x65, 0xe0, 0x07, 0x1c, 0x20, 0x21, 0x20, 0xf0, 0x00, 0xe8, 0x92, 0x1c, 0x05, + 0x28, 0x00, 0xd1, 0x02, 0x24, 0x16, 0x42, 0x64, 0xe0, 0x0e, 0x1c, 0x21, 0x9a, 0x01, 0xf7, 0xff, + 0xff, 0xb9, 0x1c, 0x04, 0x28, 0x00, 0xd1, 0x04, 0x19, 0xa9, 0x98, 0x00, 0x1c, 0x3a, 0xf0, 0x01, + 0xf8, 0x3b, 0x1c, 0x28, 0xf0, 0x00, 0xe8, 0x88, 0xb0, 0x03, 0x1c, 0x20, 0xbd, 0xf0, 0x46, 0xc0, + 0xb5, 0xf0, 0xb0, 0x87, 0x92, 0x02, 0x0a, 0x56, 0x23, 0xff, 0x22, 0x80, 0x01, 0x12, 0x03, 0xdb, + 0x90, 0x05, 0x91, 0x04, 0x20, 0x00, 0x27, 0x00, 0x92, 0x00, 0x93, 0x03, 0xe0, 0x32, 0x9a, 0x04, + 0x9b, 0x02, 0x02, 0x75, 0x1b, 0xd4, 0x42, 0xab, 0xd8, 0x01, 0x25, 0x00, 0xe0, 0x02, 0x9a, 0x02, + 0x1b, 0x55, 0x00, 0xad, 0x9b, 0x05, 0x22, 0x80, 0x19, 0xdb, 0x1c, 0x18, 0x1c, 0x21, 0x01, 0x12, + 0x93, 0x01, 0xf0, 0x00, 0xf8, 0x99, 0x28, 0x00, 0xd0, 0x01, 0x2d, 0x00, 0xd0, 0x0b, 0x9a, 0x00, + 0x19, 0x2b, 0x42, 0x93, 0xd9, 0x00, 0x1b, 0x54, 0x98, 0x01, 0x1c, 0x21, 0x1c, 0x2a, 0x1c, 0x33, + 0xf7, 0xff, 0xff, 0xa4, 0xe0, 0x0a, 0x9b, 0x03, 0x1c, 0x04, 0x42, 0x98, 0xd9, 0x01, 0x24, 0xff, + 0x03, 0xe4, 0x98, 0x01, 0x1c, 0x21, 0x1c, 0x32, 0xf7, 0xff, 0xff, 0x6c, 0x19, 0x65, 0x0a, 0xed, + 0x19, 0x76, 0x19, 0x3f, 0x9a, 0x04, 0x42, 0x97, 0xd3, 0xc9, 0xb0, 0x07, 0xbd, 0xf0, 0x46, 0xc0, + 0xb5, 0xf0, 0xb0, 0x89, 0x1c, 0x0d, 0x1c, 0x06, 0x1c, 0x17, 0x46, 0x68, 0x22, 0x20, 0x21, 0x00, + 0xf0, 0x01, 0xf8, 0x22, 0x4b, 0x07, 0x1c, 0x30, 0x1c, 0x29, 0x93, 0x00, 0x95, 0x01, 0x97, 0x02, + 0xf0, 0x00, 0xec, 0x98, 0x1c, 0x31, 0x1c, 0x2a, 0x46, 0x68, 0xf0, 0x00, 0xf8, 0x48, 0xb0, 0x09, + 0xbd, 0xf0, 0x46, 0xc0, 0xa8, 0x00, 0x00, 0x00, 0xb5, 0x10, 0xf7, 0xff, 0xff, 0xe1, 0xbd, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x80, 0xe5, 0x9f, 0x70, 0x7c, + 0xe5, 0x97, 0x70, 0x00, 0xeb, 0x00, 0x00, 0x13, 0xe8, 0xbd, 0x40, 0x80, 0xe1, 0x2f, 0xff, 0x1e, + 0xe9, 0x2d, 0x40, 0x80, 0xe5, 0x9f, 0x70, 0x68, 0xe5, 0x97, 0x70, 0x00, 0xeb, 0x00, 0x00, 0x0d, + 0xe8, 0xbd, 0x40, 0x80, 0xe1, 0x2f, 0xff, 0x1e, 0xe9, 0x2d, 0x40, 0x80, 0xe5, 0x9f, 0x70, 0x54, + 0xe5, 0x97, 0x70, 0x00, 0xeb, 0x00, 0x00, 0x07, 0xe8, 0xbd, 0x40, 0x80, 0xe1, 0x2f, 0xff, 0x1e, + 0xe9, 0x2d, 0x40, 0x80, 0xe5, 0x9f, 0x70, 0x40, 0xe5, 0x97, 0x70, 0x00, 0xeb, 0x00, 0x00, 0x01, + 0xe8, 0xbd, 0x40, 0x80, 0xe1, 0x2f, 0xff, 0x1e, 0xe1, 0x2f, 0xff, 0x17, 0xb5, 0xf0, 0x46, 0x57, + 0x46, 0x46, 0xb4, 0xc0, 0x68, 0x05, 0x46, 0x8a, 0x4b, 0x09, 0x68, 0x1b, 0x47, 0x18, 0xb5, 0xf0, + 0x46, 0x5f, 0x46, 0x56, 0x46, 0x4d, 0x46, 0x44, 0xb4, 0xf0, 0x4b, 0x06, 0x68, 0x1b, 0x47, 0x18, + 0x13, 0x70, 0x21, 0x14, 0x13, 0x70, 0x21, 0x20, 0x13, 0x70, 0x21, 0x24, 0x13, 0x70, 0x21, 0x28, + 0x13, 0x70, 0x21, 0x18, 0x13, 0x70, 0x21, 0x1c, 0xb5, 0x30, 0x06, 0xc3, 0xd0, 0x01, 0x20, 0x00, + 0xe0, 0x18, 0x4b, 0x0d, 0x42, 0x98, 0xd9, 0x01, 0x23, 0x00, 0xe0, 0x02, 0x23, 0xc0, 0x04, 0x5b, + 0x1a, 0x1b, 0x4c, 0x0a, 0x19, 0x05, 0x4c, 0x0a, 0x42, 0xa5, 0xd8, 0x01, 0x4b, 0x09, 0x1a, 0x1b, + 0x42, 0x93, 0xd2, 0x01, 0x20, 0x00, 0xe0, 0x03, 0x1c, 0x18, 0x42, 0x8b, 0xd9, 0x00, 0x1c, 0x08, + 0x3a, 0x01, 0x43, 0x90, 0xbd, 0x30, 0x46, 0xc0, 0x01, 0x7f, 0xff, 0xff, 0xf0, 0x00, 0x00, 0x00, + 0x03, 0x61, 0x7f, 0xff, 0x13, 0x61, 0x80, 0x00, 0xb5, 0x70, 0x4c, 0x09, 0x1c, 0x05, 0x1c, 0x0e, + 0x68, 0x20, 0x00, 0x91, 0x22, 0x00, 0xf0, 0x00, 0xeb, 0xd6, 0x28, 0x00, 0xdb, 0x07, 0x68, 0x20, + 0x1c, 0x29, 0x1c, 0x32, 0xf0, 0x00, 0xeb, 0xc6, 0x28, 0x00, 0xdd, 0x00, 0x20, 0x00, 0xbd, 0x70, + 0x13, 0x70, 0x20, 0x00, 0xb5, 0x10, 0x4b, 0x05, 0x68, 0x18, 0x28, 0x00, 0xdb, 0x01, 0xf0, 0x00, + 0xeb, 0xb6, 0x4a, 0x02, 0x23, 0x01, 0x42, 0x5b, 0x60, 0x13, 0xbd, 0x10, 0x13, 0x70, 0x20, 0x00, + 0xb5, 0x10, 0x21, 0x00, 0xf0, 0x00, 0xeb, 0xa6, 0x4b, 0x02, 0x60, 0x18, 0x28, 0x00, 0xdd, 0x00, + 0x20, 0x00, 0xbd, 0x10, 0x13, 0x70, 0x20, 0x00, 0xb5, 0x10, 0x48, 0x06, 0xf0, 0x00, 0xeb, 0xea, + 0x48, 0x05, 0xf0, 0x00, 0xfb, 0x15, 0x48, 0x05, 0x21, 0x00, 0x22, 0x00, 0xf0, 0x00, 0xfb, 0x18, + 0x20, 0x00, 0xbd, 0x10, 0x13, 0x70, 0x20, 0xa8, 0x13, 0x70, 0x21, 0x00, 0x13, 0x70, 0x03, 0x79, + 0xb5, 0x10, 0xf0, 0x00, 0xeb, 0xf6, 0xf0, 0x00, 0xeb, 0xfa, 0x1c, 0x04, 0x20, 0x01, 0x42, 0x40, + 0xf0, 0x00, 0xeb, 0xf8, 0x4b, 0x04, 0x68, 0x58, 0xf0, 0x00, 0xf8, 0x08, 0x1c, 0x20, 0xf0, 0x00, + 0xeb, 0xf2, 0x20, 0x00, 0xbd, 0x10, 0x46, 0xc0, 0x13, 0x70, 0x21, 0x00, 0xb5, 0x10, 0x4b, 0x41, + 0x42, 0x98, 0xd0, 0x32, 0x42, 0x98, 0xd8, 0x03, 0x4b, 0x3f, 0x42, 0x98, 0xd1, 0x79, 0xe0, 0x06, + 0x4b, 0x3e, 0x42, 0x98, 0xd0, 0x4f, 0x4b, 0x3e, 0x42, 0x98, 0xd1, 0x72, 0xe0, 0x4b, 0x48, 0x3d, + 0x4c, 0x3d, 0x21, 0x04, 0x60, 0x04, 0xf0, 0x00, 0xeb, 0xc8, 0x4b, 0x3c, 0x48, 0x3c, 0x21, 0x04, + 0x60, 0x03, 0xf0, 0x00, 0xeb, 0xc2, 0x48, 0x3b, 0x21, 0x04, 0x60, 0x04, 0xf0, 0x00, 0xeb, 0xbc, + 0x4b, 0x39, 0x48, 0x3a, 0x21, 0x04, 0x60, 0x03, 0xf0, 0x00, 0xeb, 0xb6, 0x4b, 0x38, 0x4a, 0x39, + 0x60, 0x1a, 0x4a, 0x39, 0x60, 0x5a, 0x4a, 0x39, 0x60, 0x9a, 0x4a, 0x39, 0x60, 0xda, 0x3a, 0x30, + 0x61, 0x1a, 0x4a, 0x38, 0x61, 0x5a, 0x4a, 0x38, 0xe0, 0x4a, 0x48, 0x38, 0x4c, 0x2a, 0x21, 0x04, + 0x60, 0x04, 0xf0, 0x00, 0xeb, 0xa2, 0x4b, 0x29, 0x48, 0x35, 0x21, 0x04, 0x60, 0x03, 0xf0, 0x00, + 0xeb, 0x9c, 0x48, 0x34, 0x21, 0x04, 0x60, 0x04, 0xf0, 0x00, 0xeb, 0x96, 0x4b, 0x26, 0x48, 0x32, + 0x21, 0x04, 0x60, 0x03, 0xf0, 0x00, 0xeb, 0x90, 0x4b, 0x25, 0x4a, 0x30, 0x60, 0x1a, 0x4a, 0x30, + 0x60, 0x5a, 0x4a, 0x30, 0x60, 0x9a, 0x4a, 0x30, 0x60, 0xda, 0x3a, 0x2c, 0x61, 0x1a, 0x4a, 0x2f, + 0x61, 0x5a, 0x4a, 0x2f, 0xe0, 0x24, 0x48, 0x17, 0x4c, 0x17, 0x21, 0x04, 0x60, 0x04, 0xf0, 0x00, + 0xeb, 0x7c, 0x4b, 0x16, 0x48, 0x16, 0x21, 0x04, 0x60, 0x03, 0xf0, 0x00, 0xeb, 0x76, 0x48, 0x15, + 0x21, 0x04, 0x60, 0x04, 0xf0, 0x00, 0xeb, 0x70, 0x4b, 0x13, 0x48, 0x14, 0x21, 0x04, 0x60, 0x03, + 0xf0, 0x00, 0xeb, 0x6a, 0x4b, 0x12, 0x4a, 0x23, 0x60, 0x1a, 0x4a, 0x13, 0x60, 0x5a, 0x4a, 0x13, + 0x60, 0x9a, 0x4a, 0x13, 0x60, 0xda, 0x3a, 0x30, 0x61, 0x1a, 0x4a, 0x1f, 0x61, 0x5a, 0x4a, 0x1f, + 0x61, 0x9a, 0xbd, 0x10, 0x48, 0x88, 0xe1, 0x4c, 0x48, 0x77, 0x6f, 0x72, 0x49, 0x2a, 0xca, 0x9d, + 0x4a, 0x26, 0x2a, 0xf5, 0x20, 0x20, 0x04, 0x00, 0x4b, 0x00, 0x47, 0x18, 0x13, 0x70, 0x05, 0x29, + 0x20, 0x20, 0x04, 0x04, 0x20, 0x20, 0x0e, 0xf8, 0x13, 0x70, 0x06, 0x81, 0x20, 0x20, 0x0e, 0xfc, + 0x13, 0x70, 0x21, 0x14, 0x20, 0x20, 0x2a, 0x71, 0x20, 0x20, 0x04, 0x0d, 0x20, 0x20, 0x0f, 0x05, + 0x20, 0x20, 0x09, 0x6d, 0x20, 0x20, 0x38, 0x7d, 0x20, 0x22, 0xdd, 0x60, 0x20, 0x20, 0x03, 0xb8, + 0x20, 0x20, 0x03, 0xbc, 0x20, 0x20, 0x0d, 0x2c, 0x20, 0x20, 0x0d, 0x30, 0x20, 0x20, 0x28, 0x75, + 0x20, 0x20, 0x03, 0xc5, 0x20, 0x20, 0x0d, 0x39, 0x20, 0x20, 0x08, 0xc5, 0x20, 0x20, 0x36, 0x5d, + 0x20, 0x22, 0xcd, 0xac, 0x20, 0x20, 0x29, 0x45, 0x20, 0x20, 0x37, 0x51, 0x20, 0x22, 0xcd, 0x60, + 0xb5, 0x70, 0x68, 0x03, 0x68, 0xc2, 0x2b, 0x86, 0xd0, 0x1a, 0x2b, 0x86, 0xd8, 0x04, 0x2b, 0x79, + 0xd0, 0x07, 0x2b, 0x7a, 0xd1, 0x2c, 0xe0, 0x0a, 0x2b, 0x88, 0xd0, 0x1b, 0x2b, 0x95, 0xd1, 0x27, + 0xe0, 0x1f, 0x4b, 0x15, 0x68, 0x1a, 0x23, 0x1c, 0x42, 0x1a, 0xd1, 0x07, 0xe0, 0x20, 0x4b, 0x12, + 0x24, 0x1c, 0x68, 0x1d, 0x42, 0x25, 0xd0, 0x1b, 0x69, 0x5b, 0x60, 0x13, 0x20, 0x01, 0xe0, 0x19, + 0x4b, 0x0d, 0x22, 0x1c, 0x68, 0x1c, 0x42, 0x14, 0xd0, 0x12, 0x69, 0x5a, 0x21, 0x04, 0x43, 0x8a, + 0x61, 0x5a, 0xe7, 0xf3, 0x4b, 0x08, 0x68, 0x1c, 0x23, 0x1c, 0x42, 0x1c, 0xd0, 0x08, 0x23, 0x02, + 0xe7, 0xeb, 0x4b, 0x05, 0x68, 0x1c, 0x23, 0x1c, 0x42, 0x1c, 0xd0, 0x01, 0x23, 0x0a, 0xe7, 0xe4, + 0xf7, 0xff, 0xfe, 0x64, 0xbd, 0x70, 0x46, 0xc0, 0x13, 0x70, 0x21, 0x30, 0xb5, 0x70, 0x4b, 0x17, + 0x68, 0x5b, 0x2b, 0x01, 0xd0, 0x03, 0x2b, 0x02, 0xd1, 0x0a, 0x4b, 0x15, 0xe0, 0x00, 0x4b, 0x15, + 0x42, 0x9a, 0xd3, 0x05, 0x4a, 0x14, 0x4b, 0x11, 0x20, 0xa0, 0x61, 0x1a, 0x02, 0x00, 0xe0, 0x1b, + 0x4b, 0x0e, 0x68, 0xdd, 0x68, 0x9c, 0x68, 0x1b, 0x19, 0x2c, 0x18, 0xa2, 0x06, 0xdc, 0xd5, 0x02, + 0xf0, 0x00, 0xfd, 0x2a, 0xe0, 0x10, 0x07, 0x1c, 0xd5, 0x02, 0xf7, 0xff, 0xfe, 0x85, 0xe0, 0x0b, + 0x07, 0x5c, 0xd5, 0x02, 0xf0, 0x00, 0xfa, 0xd8, 0xe0, 0x06, 0x07, 0xdc, 0xd5, 0x02, 0xf7, 0xff, + 0xfd, 0x97, 0xe0, 0x01, 0xf7, 0xff, 0xfd, 0xf8, 0xbd, 0x70, 0x46, 0xc0, 0x13, 0x70, 0x21, 0x30, + 0x7e, 0xd3, 0x80, 0x00, 0x46, 0x09, 0x00, 0x00, 0x00, 0x05, 0x21, 0x00, 0xb5, 0x10, 0x20, 0x80, + 0x01, 0x00, 0x21, 0x20, 0xf7, 0xff, 0xed, 0xfc, 0x1c, 0x04, 0x28, 0x00, 0xd0, 0x0f, 0x21, 0x80, + 0x22, 0xa0, 0x01, 0x09, 0x05, 0xd2, 0xf7, 0xff, 0xff, 0xb9, 0x28, 0x00, 0xd0, 0x01, 0x23, 0x01, + 0xe0, 0x00, 0x23, 0x02, 0x4a, 0x02, 0x1c, 0x20, 0x60, 0x53, 0xf7, 0xff, 0xed, 0xf6, 0xbd, 0x10, + 0x13, 0x70, 0x21, 0x30, 0xb5, 0x10, 0x22, 0x00, 0x1c, 0x04, 0xf7, 0xff, 0xff, 0xa7, 0x28, 0x00, + 0xdb, 0x0d, 0x69, 0xa2, 0x4b, 0x06, 0x42, 0x9a, 0xd1, 0x09, 0x4b, 0x06, 0x21, 0x01, 0x68, 0x1a, + 0x70, 0x11, 0x68, 0x1b, 0x78, 0x5b, 0x2b, 0x00, 0xd1, 0x01, 0xf7, 0xff, 0xed, 0xc6, 0xbd, 0x10, + 0x5d, 0x1c, 0x9e, 0xa3, 0x13, 0x70, 0x21, 0x2c, 0xb5, 0xf0, 0x78, 0x03, 0xb0, 0x83, 0x1c, 0x05, + 0x1c, 0x0e, 0x1c, 0x17, 0x2b, 0xe0, 0xd1, 0x00, 0xe0, 0xde, 0x4c, 0xb7, 0x22, 0x00, 0x61, 0x22, + 0x2b, 0xe4, 0xd1, 0x00, 0xe0, 0xc0, 0x2b, 0xe4, 0xd8, 0x2b, 0x2b, 0xa8, 0xd1, 0x00, 0xe0, 0xa0, + 0x2b, 0xa8, 0xd8, 0x10, 0x2b, 0x8a, 0xd0, 0x52, 0x2b, 0x8a, 0xd8, 0x05, 0x2b, 0x70, 0xd0, 0x66, + 0x2b, 0x71, 0xd0, 0x00, 0xe1, 0x50, 0xe0, 0x8d, 0x2b, 0x8d, 0xd1, 0x00, 0xe0, 0x91, 0x2b, 0xa4, + 0xd0, 0x00, 0xe1, 0x49, 0xe0, 0xae, 0x2b, 0xd9, 0xd1, 0x00, 0xe0, 0x98, 0x2b, 0xd9, 0xd8, 0x06, + 0x2b, 0xab, 0xd1, 0x00, 0xe0, 0xa0, 0x2b, 0xd0, 0xd0, 0x00, 0xe1, 0x3d, 0xe0, 0x81, 0x2b, 0xdb, + 0xd1, 0x00, 0xe0, 0xaa, 0x2b, 0xdb, 0xd2, 0x00, 0xe0, 0x83, 0x2b, 0xe0, 0xd0, 0x00, 0xe1, 0x33, + 0xe0, 0xaa, 0x2b, 0xf6, 0xd1, 0x00, 0xe1, 0x25, 0x2b, 0xf6, 0xd8, 0x12, 0x2b, 0xf2, 0xd1, 0x00, + 0xe0, 0xb2, 0x2b, 0xf2, 0xd8, 0x06, 0x2b, 0xf0, 0xd1, 0x00, 0xe0, 0xa8, 0x2b, 0xf1, 0xd0, 0x00, + 0xe1, 0x22, 0xe0, 0xa7, 0x2b, 0xf4, 0xd1, 0x00, 0xe0, 0xb5, 0x2b, 0xf4, 0xd9, 0x00, 0xe0, 0xc7, + 0xe0, 0xae, 0x2b, 0xf9, 0xd1, 0x00, 0xe0, 0xe2, 0x2b, 0xf9, 0xd8, 0x06, 0x2b, 0xf7, 0xd1, 0x00, + 0xe0, 0xc1, 0x2b, 0xf8, 0xd0, 0x00, 0xe1, 0x0f, 0xe0, 0xd4, 0x2b, 0xfb, 0xd1, 0x00, 0xe0, 0xfa, + 0x2b, 0xfb, 0xd2, 0x00, 0xe0, 0xf5, 0x2b, 0xff, 0xd0, 0x00, 0xe1, 0x05, 0xe0, 0xfd, 0x69, 0xa3, + 0x2b, 0x00, 0xd0, 0x00, 0xe1, 0x10, 0x68, 0x22, 0x21, 0x03, 0x43, 0x8a, 0x60, 0xa3, 0x60, 0xe3, + 0x60, 0x63, 0x61, 0x23, 0x61, 0x63, 0x23, 0x1c, 0x60, 0x22, 0x42, 0x1a, 0xd1, 0x00, 0xe0, 0xf3, + 0xf7, 0xff, 0xfc, 0x52, 0x69, 0x62, 0x23, 0x04, 0x43, 0x13, 0x61, 0x63, 0xe0, 0xfc, 0x68, 0xa2, + 0x68, 0xe3, 0x92, 0x01, 0x68, 0x22, 0x93, 0x00, 0x23, 0x1c, 0x42, 0x1a, 0xd0, 0x01, 0x24, 0x00, + 0xe0, 0x0a, 0x1c, 0x3a, 0xf7, 0xff, 0xfd, 0x6b, 0x1c, 0x04, 0x28, 0x00, 0xd0, 0x04, 0x4b, 0x72, + 0x22, 0x01, 0x68, 0x19, 0x43, 0x0a, 0x60, 0x1a, 0x9a, 0x00, 0x2a, 0x00, 0xd1, 0x07, 0x9b, 0x01, + 0x2b, 0x00, 0xd1, 0x04, 0x4b, 0x6c, 0x68, 0x1a, 0x23, 0x1d, 0x42, 0x1a, 0xd0, 0x04, 0x1c, 0x30, + 0x1c, 0x39, 0xf7, 0xff, 0xff, 0x3f, 0x1c, 0x04, 0x2c, 0x00, 0xd0, 0x00, 0xe0, 0xd5, 0xf7, 0xff, + 0xff, 0x1d, 0xe0, 0xd2, 0x68, 0x23, 0x07, 0x9a, 0xd4, 0x00, 0xe0, 0xbd, 0x68, 0x41, 0x68, 0x82, + 0xe0, 0x05, 0x68, 0x69, 0x68, 0xaa, 0x2b, 0xd0, 0xd1, 0x01, 0x02, 0xc9, 0x02, 0x52, 0x1c, 0x30, + 0xe0, 0x02, 0x1c, 0x08, 0x22, 0x40, 0x1c, 0x39, 0xf7, 0xff, 0xfe, 0xd0, 0xe0, 0xb1, 0x68, 0x22, + 0x23, 0x1d, 0x42, 0x1a, 0xd1, 0x00, 0xe0, 0xa7, 0x68, 0x43, 0x68, 0x82, 0x07, 0x9b, 0x43, 0x13, + 0x4a, 0x56, 0x40, 0x13, 0x60, 0xe3, 0xe0, 0xaf, 0x68, 0x22, 0x23, 0x1d, 0x42, 0x1a, 0xd0, 0x00, + 0xe0, 0xaa, 0xe0, 0x99, 0x68, 0x22, 0x23, 0x1d, 0x42, 0x1a, 0xd1, 0x00, 0xe0, 0x94, 0x4a, 0x50, + 0x4b, 0x4d, 0x24, 0xa0, 0x61, 0x1a, 0x02, 0x24, 0xe0, 0x9f, 0x68, 0x21, 0x23, 0x1c, 0x42, 0x19, + 0xd1, 0x00, 0xe0, 0x89, 0x60, 0x32, 0xe0, 0x97, 0x4b, 0x47, 0x22, 0x1c, 0x68, 0x19, 0x42, 0x11, + 0xd1, 0x02, 0x69, 0x1b, 0x2b, 0x00, 0xd0, 0x7f, 0x4b, 0x43, 0x69, 0x1b, 0xe0, 0x45, 0x68, 0x43, + 0x60, 0xa3, 0xe0, 0x89, 0x68, 0xa3, 0xe0, 0x40, 0x68, 0x43, 0x2b, 0x00, 0xd0, 0x03, 0x68, 0x22, + 0x23, 0x02, 0x43, 0x13, 0xe0, 0x02, 0x68, 0x23, 0x22, 0x02, 0x43, 0x93, 0x60, 0x23, 0xe0, 0x7b, + 0x68, 0x22, 0x23, 0x02, 0xe0, 0x30, 0x68, 0x46, 0xf0, 0x00, 0xf9, 0xb4, 0x68, 0x23, 0x22, 0x04, + 0x43, 0x93, 0x60, 0x23, 0x2e, 0x00, 0xd0, 0x6f, 0x1c, 0x29, 0x1e, 0x70, 0x31, 0x08, 0xf0, 0x00, + 0xf9, 0xb7, 0x1c, 0x04, 0x28, 0x00, 0xd1, 0x68, 0x4b, 0x2f, 0x22, 0x04, 0x68, 0x19, 0xe0, 0x16, + 0x68, 0x22, 0x23, 0x04, 0xe0, 0x18, 0x68, 0x45, 0xf7, 0xff, 0xfd, 0x2c, 0x68, 0x23, 0x22, 0x08, + 0x43, 0x93, 0x60, 0x23, 0x2d, 0x00, 0xd0, 0x57, 0x1c, 0x28, 0xf0, 0x00, 0xe9, 0x5c, 0xf7, 0xff, + 0xfd, 0x2f, 0x1c, 0x04, 0x28, 0x00, 0xd1, 0x50, 0x4b, 0x23, 0x22, 0x08, 0x68, 0x19, 0x43, 0x0a, + 0x60, 0x1a, 0xe0, 0x4a, 0x68, 0x22, 0x23, 0x08, 0x40, 0x13, 0x60, 0x33, 0xe0, 0x44, 0x68, 0x43, + 0x68, 0x87, 0x93, 0x00, 0x68, 0xc5, 0xf0, 0x00, 0xfa, 0x8b, 0x68, 0x23, 0x22, 0x10, 0x43, 0x93, + 0x60, 0x23, 0x2f, 0x00, 0xd0, 0x38, 0x9a, 0x00, 0x2a, 0x00, 0xd0, 0x35, 0x2d, 0x00, 0xd0, 0x33, + 0x1c, 0x38, 0xf0, 0x00, 0xe9, 0x38, 0x1c, 0x2a, 0x1c, 0x01, 0x98, 0x00, 0xf0, 0x00, 0xfb, 0xc8, + 0x60, 0x30, 0x28, 0x00, 0xdd, 0x28, 0x4b, 0x10, 0x22, 0x10, 0x68, 0x19, 0x43, 0x0a, 0x60, 0x1a, + 0xe0, 0x22, 0x68, 0x23, 0xe7, 0xd9, 0x4b, 0x0f, 0x60, 0x0b, 0x68, 0x23, 0x60, 0x4b, 0x68, 0x63, + 0x60, 0x8b, 0xe0, 0x19, 0x68, 0x43, 0x61, 0xa3, 0xe0, 0x16, 0x68, 0x40, 0xf0, 0x00, 0xe9, 0x1a, + 0x1c, 0x31, 0xf7, 0xff, 0xfb, 0x71, 0xe0, 0x04, 0x1c, 0x28, 0x1c, 0x31, 0x1c, 0x3a, 0xf7, 0xff, + 0xfc, 0x86, 0x1c, 0x04, 0xe0, 0x09, 0x46, 0xc0, 0x13, 0x70, 0x21, 0x30, 0xff, 0xff, 0x80, 0x00, + 0x00, 0x05, 0x31, 0x00, 0x48, 0x45, 0x4c, 0x4f, 0x24, 0x00, 0xb0, 0x03, 0x1c, 0x20, 0xbd, 0xf0, + 0xb5, 0x10, 0x1c, 0x01, 0x22, 0x00, 0x20, 0x12, 0x23, 0x00, 0xf0, 0x00, 0xe8, 0xf8, 0xbd, 0x10, + 0xb5, 0x70, 0x1c, 0x05, 0x1c, 0x0c, 0x1c, 0x13, 0x1c, 0x29, 0x1c, 0x22, 0x20, 0x10, 0xf0, 0x00, + 0xe8, 0xee, 0xbd, 0x70, 0xe6, 0x00, 0x00, 0x10, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x00, 0x30, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x00, 0x50, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x00, 0x70, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x00, 0x90, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x00, 0xb0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x00, 0xd0, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x00, 0xf0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x01, 0x10, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x01, 0x30, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x01, 0x50, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x01, 0x70, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x01, 0x90, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x01, 0xb0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x01, 0xd0, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x01, 0xf0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x02, 0x10, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x02, 0x30, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x02, 0x50, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x02, 0x70, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x02, 0x90, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x02, 0xb0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x02, 0xd0, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x02, 0xf0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x03, 0x10, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x03, 0x30, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x03, 0x50, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x03, 0x70, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x03, 0x90, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x03, 0xb0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x03, 0xd0, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x03, 0xf0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x04, 0x10, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x04, 0x30, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x04, 0x50, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x04, 0x70, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x04, 0x90, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x04, 0xb0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x04, 0xd0, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x04, 0xf0, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x05, 0x10, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x05, 0x30, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x05, 0x50, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x06, 0x90, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x07, 0xf0, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x08, 0x10, + 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x09, 0xf0, 0xe1, 0x2f, 0xff, 0x1e, 0xe6, 0x00, 0x0a, 0x10, + 0xe1, 0x2f, 0xff, 0x1e, 0xe1, 0xa0, 0x20, 0x0e, 0xe2, 0x90, 0x10, 0x00, 0xe3, 0xb0, 0x00, 0x04, + 0xef, 0x00, 0x00, 0xab, 0xe1, 0x2f, 0xff, 0x12, 0xe5, 0x9f, 0xc0, 0x54, 0xe5, 0x9c, 0xc0, 0x00, + 0xe1, 0xa0, 0x00, 0x00, 0xe7, 0x9c, 0xc1, 0x0b, 0xe1, 0xa0, 0x00, 0x00, 0xe1, 0x2f, 0xff, 0x1c, + 0xe3, 0xa0, 0xb0, 0x3f, 0xea, 0xff, 0xff, 0xf7, 0xe3, 0xa0, 0xb0, 0x40, 0xea, 0xff, 0xff, 0xf5, + 0xe3, 0xa0, 0x00, 0x00, 0xee, 0x07, 0x0f, 0x15, 0xe1, 0x2f, 0xff, 0x1e, 0xee, 0x13, 0x0f, 0x10, + 0xe1, 0x2f, 0xff, 0x1e, 0xee, 0x03, 0x0f, 0x10, 0xe1, 0x2f, 0xff, 0x1e, 0xef, 0x00, 0x00, 0xcc, + 0xe1, 0x2f, 0xff, 0x1e, 0xe3, 0xc0, 0x01, 0x02, 0xe1, 0x2f, 0xff, 0x1e, 0xe3, 0x80, 0x01, 0x02, + 0xe1, 0x2f, 0xff, 0x1e, 0x13, 0x70, 0x21, 0x00, 0xb5, 0x70, 0x4c, 0x13, 0x1c, 0x06, 0x68, 0x20, + 0x23, 0x04, 0x62, 0x02, 0x1c, 0x02, 0x32, 0x20, 0x60, 0x02, 0x32, 0x20, 0xb0, 0x82, 0x64, 0x01, + 0x60, 0x43, 0x60, 0x82, 0x60, 0xc3, 0x61, 0x41, 0x61, 0x06, 0x1c, 0x0d, 0x21, 0x44, 0xf7, 0xff, + 0xef, 0xa6, 0x4b, 0x0a, 0x49, 0x0a, 0x68, 0x18, 0x68, 0x23, 0x22, 0x02, 0x93, 0x00, 0x23, 0x01, + 0xf7, 0xff, 0xef, 0x70, 0x1c, 0x04, 0x28, 0x00, 0xd1, 0x03, 0x1c, 0x30, 0x1c, 0x29, 0xf7, 0xff, + 0xef, 0x92, 0xb0, 0x02, 0x1c, 0x20, 0xbd, 0x70, 0x13, 0x70, 0x21, 0x4c, 0x13, 0x70, 0x20, 0x04, + 0x57, 0x46, 0x53, 0x02, 0xb5, 0x10, 0x4b, 0x05, 0x68, 0x18, 0x28, 0x00, 0xdd, 0x01, 0xf7, 0xff, + 0xef, 0x46, 0x4a, 0x02, 0x23, 0x01, 0x42, 0x5b, 0x60, 0x13, 0xbd, 0x10, 0x13, 0x70, 0x20, 0x04, + 0xb5, 0x70, 0x4c, 0x18, 0xb0, 0x82, 0x68, 0x23, 0x1c, 0x05, 0x1c, 0x0e, 0x2b, 0x00, 0xd1, 0x09, + 0x20, 0x44, 0x21, 0x20, 0xf7, 0xff, 0xea, 0xf4, 0x60, 0x20, 0x28, 0x00, 0xd1, 0x02, 0x20, 0x16, + 0x42, 0x40, 0xe0, 0x1d, 0x4b, 0x10, 0x00, 0xad, 0x58, 0xe8, 0x21, 0x01, 0xf7, 0xff, 0xef, 0x22, + 0x4d, 0x0e, 0x60, 0x28, 0x28, 0x00, 0xdb, 0x13, 0x4c, 0x0a, 0x1c, 0x31, 0x68, 0x20, 0x22, 0x06, + 0x30, 0x20, 0xf0, 0x00, 0xfa, 0x99, 0x68, 0x23, 0x68, 0x28, 0x1c, 0x1a, 0x32, 0x20, 0x60, 0x1a, + 0x22, 0x06, 0x60, 0x5a, 0x49, 0x06, 0x93, 0x00, 0x22, 0x01, 0x23, 0x00, 0xf7, 0xff, 0xef, 0x22, + 0xb0, 0x02, 0xbd, 0x70, 0x13, 0x70, 0x21, 0x4c, 0x13, 0x70, 0x20, 0xa0, 0x13, 0x70, 0x20, 0x04, + 0x57, 0x46, 0x53, 0x01, 0xb5, 0x10, 0x4c, 0x0e, 0xb0, 0x82, 0x68, 0x23, 0x2b, 0x00, 0xda, 0x14, + 0x1c, 0x20, 0x30, 0x20, 0x21, 0x01, 0xf7, 0xff, 0xee, 0xf6, 0x60, 0x20, 0x28, 0x00, 0xda, 0x02, + 0x20, 0x0b, 0x42, 0x40, 0xe0, 0x0a, 0x23, 0x00, 0x22, 0x00, 0x49, 0x06, 0x93, 0x00, 0xf7, 0xff, + 0xef, 0x02, 0x4a, 0x05, 0x23, 0x80, 0x00, 0x9b, 0x60, 0x13, 0x20, 0x00, 0xb0, 0x02, 0xbd, 0x10, + 0x13, 0x70, 0x20, 0x20, 0x55, 0x4d, 0x53, 0x01, 0x13, 0x70, 0x21, 0x60, 0xb5, 0x70, 0x4b, 0x1e, + 0xb0, 0x82, 0x68, 0x1b, 0x2b, 0x00, 0xdb, 0x33, 0x4e, 0x1c, 0x1c, 0x33, 0x33, 0x40, 0x62, 0x33, + 0x23, 0x04, 0x62, 0x73, 0x62, 0xf3, 0x68, 0x33, 0x64, 0x71, 0x43, 0x59, 0x64, 0x30, 0x1c, 0x34, + 0x1c, 0x30, 0x30, 0x44, 0x34, 0x20, 0x62, 0xb0, 0x63, 0x32, 0x63, 0x71, 0x1c, 0x25, 0x36, 0x38, + 0x68, 0x28, 0x68, 0x69, 0xf7, 0xff, 0xef, 0x02, 0x35, 0x08, 0x42, 0xb5, 0xd1, 0xf8, 0x4d, 0x0f, + 0x21, 0x18, 0x35, 0x20, 0x1c, 0x28, 0xf7, 0xff, 0xee, 0xfa, 0x4b, 0x0b, 0x49, 0x0c, 0x68, 0x18, + 0x22, 0x02, 0x23, 0x01, 0x95, 0x00, 0xf7, 0xff, 0xee, 0xc6, 0x28, 0x00, 0xdb, 0x08, 0x68, 0x20, + 0x68, 0x61, 0xf7, 0xff, 0xee, 0xe8, 0x34, 0x08, 0x42, 0xb4, 0xd1, 0xf8, 0x20, 0x01, 0xe0, 0x00, + 0x20, 0x00, 0xb0, 0x02, 0xbd, 0x70, 0x46, 0xc0, 0x13, 0x70, 0x20, 0x20, 0x13, 0x70, 0x21, 0x60, + 0x55, 0x4d, 0x53, 0x03, 0xb5, 0x70, 0x4b, 0x1c, 0xb0, 0x82, 0x68, 0x1c, 0x2c, 0x00, 0xdb, 0x2f, + 0x4e, 0x1a, 0x60, 0x30, 0x20, 0x04, 0x62, 0x70, 0x62, 0xf0, 0x68, 0x5b, 0x60, 0x71, 0x43, 0x59, + 0x1d, 0x34, 0x62, 0xb4, 0x34, 0x1c, 0x62, 0x36, 0x63, 0x32, 0x63, 0x71, 0x1c, 0x25, 0x36, 0x38, + 0x68, 0x28, 0x68, 0x69, 0xf7, 0xff, 0xee, 0xc2, 0x35, 0x08, 0x42, 0xb5, 0xd1, 0xf8, 0x4d, 0x0f, + 0x21, 0x18, 0x35, 0x20, 0x1c, 0x28, 0xf7, 0xff, 0xee, 0xba, 0x4b, 0x0b, 0x21, 0x02, 0x68, 0x18, + 0x22, 0x02, 0x23, 0x01, 0x95, 0x00, 0xf7, 0xff, 0xee, 0x86, 0x28, 0x00, 0xdb, 0x08, 0x68, 0x20, + 0x68, 0x61, 0xf7, 0xff, 0xee, 0xa8, 0x34, 0x08, 0x42, 0xb4, 0xd1, 0xf8, 0x20, 0x01, 0xe0, 0x00, + 0x20, 0x00, 0xb0, 0x02, 0xbd, 0x70, 0x46, 0xc0, 0x13, 0x70, 0x20, 0x60, 0x13, 0x70, 0x21, 0xc0, + 0xb5, 0x10, 0x4c, 0x0e, 0xb0, 0x82, 0x68, 0x23, 0x2b, 0x00, 0xda, 0x13, 0x1c, 0x20, 0x30, 0x20, + 0x21, 0x01, 0xf7, 0xff, 0xee, 0x50, 0x60, 0x20, 0x28, 0x00, 0xda, 0x02, 0x20, 0x0b, 0x42, 0x40, + 0xe0, 0x09, 0x23, 0x00, 0x21, 0x01, 0x22, 0x00, 0x93, 0x00, 0xf7, 0xff, 0xee, 0x5c, 0x23, 0x80, + 0x00, 0x9b, 0x60, 0x63, 0x20, 0x00, 0xb0, 0x02, 0xbd, 0x10, 0x46, 0xc0, 0x13, 0x70, 0x20, 0x60, + 0x4b, 0x02, 0x22, 0x00, 0x60, 0x1a, 0x60, 0x5a, 0x60, 0x9a, 0x47, 0x70, 0x13, 0x70, 0x22, 0x00, + 0xb5, 0xf0, 0x4d, 0x33, 0x24, 0xa0, 0xb0, 0x83, 0x0b, 0xcf, 0x00, 0xa4, 0x9e, 0x09, 0x60, 0xef, + 0x42, 0xa7, 0xd9, 0x01, 0x4c, 0x2f, 0x60, 0xec, 0x4d, 0x2d, 0x4f, 0x2f, 0x68, 0xec, 0x46, 0x9c, + 0x00, 0x64, 0x19, 0x3c, 0x89, 0xa4, 0x61, 0x2c, 0x61, 0x6c, 0x00, 0x67, 0x68, 0x45, 0x19, 0x3f, + 0x00, 0xbf, 0x95, 0x00, 0x19, 0xc7, 0x18, 0x55, 0x37, 0x0c, 0x95, 0x01, 0xe0, 0x33, 0x68, 0x3d, + 0x42, 0x8d, 0xd8, 0x17, 0x68, 0xbb, 0x18, 0xeb, 0x42, 0x8b, 0xd9, 0x2a, 0x4f, 0x20, 0x1b, 0x4d, + 0x46, 0x63, 0x61, 0x7c, 0x61, 0xbd, 0x60, 0x19, 0x00, 0x63, 0x19, 0x1c, 0x00, 0xa4, 0x19, 0x00, + 0x69, 0x03, 0x99, 0x08, 0x18, 0xeb, 0x60, 0x0b, 0x69, 0x43, 0x1b, 0x5d, 0x60, 0x35, 0x42, 0x95, + 0xd9, 0x2b, 0xe0, 0x14, 0x9b, 0x01, 0x42, 0x9d, 0xd2, 0x13, 0x4f, 0x15, 0x46, 0x63, 0x1a, 0x69, + 0x61, 0x7c, 0x61, 0xb9, 0x60, 0x1d, 0x00, 0x63, 0x19, 0x1c, 0x00, 0xa4, 0x19, 0x00, 0x69, 0x03, + 0x9c, 0x08, 0x1a, 0x52, 0x60, 0x23, 0x69, 0x43, 0x60, 0x33, 0x42, 0x93, 0xd9, 0x15, 0x60, 0x32, + 0xe0, 0x13, 0x34, 0x01, 0x37, 0x0c, 0x9d, 0x00, 0x42, 0xac, 0xd3, 0xc8, 0x4d, 0x08, 0x18, 0x51, + 0x61, 0x6c, 0x68, 0x02, 0x46, 0x63, 0x42, 0x91, 0xd9, 0x02, 0x20, 0x02, 0x42, 0x40, 0xe0, 0x05, + 0x60, 0x19, 0x99, 0x08, 0x23, 0x00, 0x60, 0x0b, 0x60, 0x33, 0x20, 0x00, 0xb0, 0x03, 0xbd, 0xf0, + 0x13, 0x70, 0x27, 0x00, 0x00, 0x00, 0x02, 0x7f, 0x13, 0x70, 0x22, 0x00, 0xb5, 0xf0, 0xb0, 0x85, + 0x1c, 0x07, 0x1c, 0x0e, 0x92, 0x03, 0x4c, 0x28, 0xe0, 0x47, 0x4a, 0x28, 0x4b, 0x28, 0x68, 0x50, + 0x93, 0x00, 0x1c, 0x23, 0x33, 0x24, 0x93, 0x01, 0x1c, 0x39, 0x9a, 0x03, 0x4b, 0x25, 0xf7, 0xff, + 0xff, 0x7f, 0x62, 0xa0, 0x28, 0x00, 0xd1, 0x3c, 0x69, 0xe2, 0x1b, 0xd2, 0x62, 0xe2, 0x2a, 0x00, + 0xd0, 0x0b, 0x02, 0x52, 0x1c, 0x30, 0x21, 0x00, 0xf0, 0x00, 0xf9, 0x66, 0x6a, 0xe3, 0x02, 0x5a, + 0x18, 0xb6, 0x9a, 0x03, 0x18, 0xff, 0x1a, 0xd2, 0x92, 0x03, 0x4d, 0x17, 0x6a, 0x69, 0x29, 0x00, + 0xd0, 0x1a, 0x4b, 0x16, 0x68, 0x9b, 0x2b, 0x01, 0xd1, 0x04, 0x6a, 0x28, 0x1c, 0x32, 0xf7, 0xff, + 0xfe, 0xb5, 0xe0, 0x03, 0x6a, 0x28, 0x1c, 0x32, 0xf7, 0xff, 0xfe, 0xf4, 0x4b, 0x0e, 0x62, 0xa8, + 0x6a, 0x9a, 0x2a, 0x00, 0xd1, 0x01, 0x20, 0x03, 0xe0, 0x0d, 0x6a, 0x5b, 0x02, 0x5a, 0x18, 0xb6, + 0x9a, 0x03, 0x18, 0xff, 0x1a, 0xd2, 0x92, 0x03, 0x4b, 0x07, 0x6a, 0x5a, 0x6a, 0xdb, 0x18, 0xd3, + 0x2b, 0x00, 0xd1, 0x02, 0x20, 0x04, 0x42, 0x40, 0xe0, 0x03, 0x9b, 0x03, 0x2b, 0x00, 0xd1, 0xb4, + 0x20, 0x00, 0xb0, 0x05, 0xbd, 0xf0, 0x46, 0xc0, 0x13, 0x70, 0x27, 0x00, 0x13, 0x70, 0x22, 0x00, + 0x13, 0x70, 0x27, 0x20, 0x13, 0x70, 0x27, 0x1c, 0xb5, 0xf8, 0x24, 0x7f, 0x1c, 0x0f, 0x1c, 0x1e, + 0x09, 0xc1, 0x4b, 0x17, 0x40, 0x20, 0x24, 0x80, 0x00, 0x80, 0x00, 0xa4, 0x1a, 0x24, 0x63, 0x19, + 0x63, 0x58, 0x63, 0x9c, 0x42, 0x94, 0xd9, 0x00, 0x63, 0x9a, 0x4a, 0x11, 0x23, 0x80, 0x6b, 0x90, + 0x00, 0x9b, 0x42, 0x98, 0xd1, 0x01, 0x23, 0x00, 0x63, 0x93, 0x4c, 0x0d, 0x6b, 0xa3, 0x2b, 0x00, + 0xd0, 0x10, 0x1c, 0x25, 0x35, 0x40, 0x1c, 0x08, 0x22, 0x01, 0x1c, 0x29, 0xf7, 0xff, 0xff, 0x7e, + 0x4b, 0x08, 0x64, 0x18, 0x28, 0x00, 0xd1, 0x09, 0x6b, 0x61, 0x6b, 0xa2, 0x18, 0x69, 0x1c, 0x38, + 0xf0, 0x00, 0xf8, 0xba, 0x4b, 0x02, 0x20, 0x00, 0x6b, 0x9b, 0x60, 0x33, 0xbd, 0xf8, 0x46, 0xc0, + 0x13, 0x70, 0x27, 0x00, 0x13, 0x70, 0x29, 0x00, 0xb5, 0xf0, 0x4c, 0x1f, 0x1c, 0x07, 0x1c, 0x0d, + 0x1c, 0x23, 0xb0, 0x83, 0x1c, 0x10, 0x1c, 0x16, 0x33, 0x44, 0x1c, 0x39, 0x1c, 0x2a, 0xf7, 0xff, + 0xff, 0xbb, 0x90, 0x01, 0x64, 0xa0, 0x28, 0x00, 0xd1, 0x2a, 0x6c, 0x63, 0x08, 0x9a, 0x18, 0xff, + 0x1a, 0xed, 0x4b, 0x16, 0x18, 0xb6, 0x42, 0x9d, 0xd9, 0x0f, 0x09, 0xf0, 0x0a, 0x6a, 0x64, 0xe0, + 0x65, 0x22, 0x1c, 0x39, 0xf7, 0xff, 0xff, 0x4a, 0x64, 0xa0, 0x28, 0x00, 0xd1, 0x19, 0x6d, 0x23, + 0x01, 0xda, 0x02, 0x5b, 0x18, 0xb6, 0x18, 0xff, 0x1a, 0xed, 0x2d, 0x00, 0xd0, 0x10, 0x4c, 0x0a, + 0x1c, 0x30, 0x1c, 0x23, 0x33, 0x44, 0x1c, 0x39, 0x1c, 0x2a, 0xf7, 0xff, 0xff, 0x95, 0x64, 0xa0, + 0x28, 0x00, 0xd1, 0x06, 0x6c, 0x63, 0x42, 0x9d, 0xd0, 0x03, 0x20, 0x05, 0x42, 0x40, 0xe0, 0x00, + 0x98, 0x01, 0xb0, 0x03, 0xbd, 0xf0, 0x46, 0xc0, 0x13, 0x70, 0x29, 0x00, 0x00, 0x00, 0x01, 0xff, + 0xb5, 0xf0, 0x4b, 0x32, 0x1c, 0x15, 0x68, 0x1a, 0xb0, 0x83, 0x1c, 0x06, 0x1c, 0x0f, 0x2a, 0x00, + 0xd0, 0x03, 0x22, 0x00, 0x60, 0x1a, 0x60, 0x5a, 0x60, 0x9a, 0x1e, 0x73, 0x2b, 0x01, 0xd8, 0x4f, + 0x2d, 0x00, 0xd0, 0x4d, 0x4b, 0x2a, 0x42, 0x9d, 0xd9, 0x01, 0x25, 0x02, 0xe0, 0x49, 0x4c, 0x29, + 0x2e, 0x01, 0xd1, 0x02, 0xf7, 0xff, 0xfd, 0xce, 0xe0, 0x01, 0xf7, 0xff, 0xfe, 0x71, 0x4b, 0x25, + 0x65, 0x60, 0x6d, 0x5a, 0x2a, 0x00, 0xd0, 0x01, 0x1c, 0x15, 0xe0, 0x3b, 0x4c, 0x1f, 0x33, 0x58, + 0x60, 0x63, 0x60, 0xa6, 0x1c, 0x38, 0x1c, 0x29, 0xf7, 0xff, 0xec, 0xfc, 0x68, 0x60, 0x21, 0x00, + 0x4a, 0x1b, 0xf0, 0x00, 0xf8, 0x79, 0x1c, 0x2a, 0x68, 0x60, 0x1c, 0x39, 0xf0, 0x00, 0xf8, 0x34, + 0x1c, 0x38, 0x1c, 0x29, 0xf7, 0xff, 0xec, 0xf2, 0x21, 0xa0, 0x68, 0x60, 0x23, 0x00, 0x34, 0x0c, + 0x22, 0x00, 0x00, 0x89, 0x03, 0xd6, 0x96, 0x01, 0xe0, 0x01, 0x04, 0x33, 0x0c, 0x1b, 0x00, 0x5e, + 0x18, 0xf6, 0x00, 0xb6, 0x19, 0x86, 0x69, 0x77, 0x68, 0xf6, 0x46, 0xbc, 0x9f, 0x01, 0x44, 0x66, + 0x42, 0xb7, 0xd3, 0x04, 0x68, 0x47, 0x1c, 0x5e, 0x46, 0xbc, 0x45, 0x66, 0xd3, 0xed, 0x32, 0x01, + 0x80, 0x23, 0x34, 0x02, 0x42, 0x8a, 0xd1, 0xe5, 0x4b, 0x04, 0x22, 0x01, 0x60, 0x1a, 0xe0, 0x01, + 0x25, 0x01, 0x42, 0x6d, 0xb0, 0x03, 0x1c, 0x28, 0xbd, 0xf0, 0x46, 0xc0, 0x13, 0x70, 0x22, 0x00, + 0x00, 0x03, 0xa9, 0x8c, 0x13, 0x70, 0x29, 0x00, 0xb5, 0xf0, 0x1c, 0x06, 0x1c, 0x0d, 0x1c, 0x14, + 0x2a, 0x0f, 0xd9, 0x03, 0x1c, 0x0b, 0x43, 0x03, 0x07, 0x9f, 0xd0, 0x0a, 0x2c, 0x00, 0xd0, 0x05, + 0x23, 0x00, 0x5c, 0xea, 0x54, 0xf2, 0x33, 0x01, 0x42, 0xa3, 0xd1, 0xfa, 0xbc, 0xf0, 0xbc, 0x02, + 0x47, 0x08, 0x1c, 0x15, 0x1c, 0x0c, 0x1c, 0x03, 0x68, 0x26, 0x60, 0x1e, 0x68, 0x66, 0x60, 0x5e, + 0x68, 0xa6, 0x60, 0x9e, 0x68, 0xe6, 0x3d, 0x10, 0x60, 0xde, 0x34, 0x10, 0x33, 0x10, 0x2d, 0x0f, + 0xd8, 0xf2, 0x3a, 0x10, 0x09, 0x13, 0x1c, 0x5d, 0x01, 0x2d, 0x01, 0x1b, 0x19, 0x46, 0x19, 0x4d, + 0x1a, 0xd1, 0x1c, 0x0c, 0x29, 0x03, 0xd9, 0xd9, 0x23, 0x00, 0x58, 0xea, 0x50, 0xf2, 0x33, 0x04, + 0x1a, 0xca, 0x2a, 0x03, 0xd8, 0xf9, 0x39, 0x04, 0x08, 0x8c, 0x1c, 0x63, 0x00, 0x9b, 0x00, 0xa4, + 0x18, 0xf6, 0x18, 0xed, 0x1b, 0x0c, 0xe7, 0xc9, 0xb5, 0x70, 0x1c, 0x03, 0x07, 0x84, 0xd0, 0x0d, + 0x2a, 0x00, 0xd0, 0x40, 0x06, 0x0d, 0x3a, 0x01, 0x0e, 0x2d, 0x24, 0x03, 0xe0, 0x02, 0x2a, 0x00, + 0xd0, 0x39, 0x3a, 0x01, 0x70, 0x1d, 0x33, 0x01, 0x42, 0x23, 0xd1, 0xf8, 0x2a, 0x03, 0xd9, 0x29, + 0x25, 0xff, 0x40, 0x0d, 0x02, 0x2c, 0x43, 0x25, 0x04, 0x2c, 0x1c, 0x1e, 0x43, 0x25, 0x2a, 0x0f, + 0xd9, 0x12, 0x1c, 0x16, 0x1c, 0x1c, 0x3e, 0x10, 0x60, 0x25, 0x60, 0x65, 0x60, 0xa5, 0x60, 0xe5, + 0x34, 0x10, 0x2e, 0x0f, 0xd8, 0xf7, 0x3a, 0x10, 0x09, 0x16, 0x36, 0x01, 0x01, 0x36, 0x19, 0x9e, + 0x23, 0x0f, 0x40, 0x1a, 0x2a, 0x03, 0xd9, 0x0c, 0x23, 0x00, 0x50, 0xf5, 0x33, 0x04, 0x1a, 0xd4, + 0x2c, 0x03, 0xd8, 0xfa, 0x3a, 0x04, 0x08, 0x93, 0x33, 0x01, 0x00, 0x9b, 0x18, 0xf6, 0x23, 0x03, + 0x40, 0x1a, 0x1c, 0x33, 0x2a, 0x00, 0xd0, 0x06, 0x06, 0x09, 0x0e, 0x0c, 0x21, 0x00, 0x54, 0x5c, + 0x31, 0x01, 0x42, 0x8a, 0xd1, 0xfb, 0xbc, 0x70, 0xbc, 0x02, 0x47, 0x08, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 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, 0xff, 0xff, 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, 0x2f, 0x64, 0x65, 0x76, + 0x2f, 0x75, 0x73, 0x62, 0x32, 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, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x64, 0x65, 0x76, + 0x2f, 0x73, 0x64, 0x69, 0x6f, 0x2f, 0x73, 0x64, 0x68, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x70, 0x20, 0xd6, + 0x13, 0x70, 0x20, 0xe0, 0x24, 0x49, 0x4f, 0x53, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x44, 0x49, 0x50, 0x50, 0x3a, 0x20, 0x4d, 0x61, 0x72, 0x20, 0x20, 0x37, 0x20, 0x32, 0x30, + 0x31, 0x30, 0x20, 0x31, 0x31, 0x3a, 0x35, 0x34, 0x3a, 0x32, 0x36, 0x20, 0x36, 0x34, 0x4d, 0x24, + 0x0a, 0x00, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x75, 0x73, 0x62, 0x32, 0x00, 0x2f, 0x64, 0x65, 0x76, + 0x2f, 0x73, 0x64, 0x69, 0x6f, 0x2f, 0x73, 0x64, 0x68, 0x63, 0x00, 0x00 +}; diff --git a/source/mload/dip_plugin_249.h b/source/mload/dip_plugin_249.h new file mode 100644 index 00000000..1138a27f --- /dev/null +++ b/source/mload/dip_plugin_249.h @@ -0,0 +1,3 @@ +#define size_dip_plugin_249 5276 + +extern unsigned char dip_plugin_249[5276]; diff --git a/source/mload/fatffs_util.c b/source/mload/fatffs_util.c deleted file mode 100644 index 27b5a072..00000000 --- a/source/mload/fatffs_util.c +++ /dev/null @@ -1,291 +0,0 @@ -/* - From Custom IOS Module (FAT) - - Copyright (C) 2009 Waninkoko. - Copyright (C) 2010 Hermes. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#include "fatffs_util.h" - -#include - -#include -#include -#include -#include - -extern u32 nand_mode; - -s32 FAT_DeleteDir(const char *dirpath) -{ - DIR_ITER *dir; - - s32 ret; - - /* Open directory */ - dir = diropen(dirpath); - if (!dir) - return -1; - - /* Read entries */ - for (;;) { - char filename[256], newpath[256]; - struct stat filestat; - - /* Read entry */ - if (dirnext(dir, filename, &filestat)) - break; - - /* Non valid entry */ - if (filename[0]=='.') - continue; - - /* Generate entry path */ - strcpy(newpath, dirpath); - strcat(newpath, "/"); - strcat(newpath, filename); - - /* Delete directory contents */ - if (filestat.st_mode & S_IFDIR) - FAT_DeleteDir(newpath); - - /* Delete object */ - ret = remove(newpath); - - /* Error */ - if (ret != 0) - break; - } - - /* Close directory */ - dirclose(dir); - - return 0; -} - -static int global_error=0; - -static char temp_read_buffer[16384] ATTRIBUTE_ALIGN(32); - -s32 _FFS_to_FAT_Copy(const char *ffsdirpath, const char *fatdirpath) -{ -int n; -u32 blocks, ionodes; -int pos=0; -char *list; -s32 ret; - -u32 ionodes_temp; - - if(ISFS_GetUsage(ffsdirpath, &blocks, &ionodes)) {global_error=-1;return -1;} - - - list= memalign(32, ionodes*13); - - if(!list) {global_error=-2;return -2;} - - if(ISFS_ReadDir(ffsdirpath, list , &ionodes)) {free(list);global_error=-3;return -3;} - - if(ionodes) mkdir(fatdirpath, S_IRWXO | S_IRWXG | S_IRWXU); - - - /* Read entries */ - for (n=0;n0) - { - ret=len; if(len>16384) ret=16384; - if(ISFS_Read(fd, temp_read_buffer, ret)!=ret) - { - global_error=-7; - break; - } - if(fwrite(temp_read_buffer, 1, ret, fp)!=ret) - { - global_error=-8; - break; - } - len-=ret; - } - - fclose(fp); - ISFS_Close(fd); - - if(global_error) {free(list);return global_error;} - } - } - - } - - free(list); - return 0; -} - -s32 FFS_to_FAT_Copy(const char *ffsdirpath, const char *fatdirpath) -{ -u32 blocks, ionodes; -int ret; - -char create_dir[256]; - - ISFS_Initialize(); - - ret=ISFS_GetUsage(ffsdirpath, &blocks, &ionodes); - - if(ret==0) - { - int n=0; - - // creating the path directory - - strcpy(create_dir, fatdirpath); - - while(create_dir[n]!=0 && create_dir[n]!='/') n++; - - if(create_dir[n]=='/') n++; - - while(create_dir[n]!=0) - { - if(create_dir[n]=='/') - { - create_dir[n]=0; - mkdir(create_dir, S_IRWXO | S_IRWXG | S_IRWXU); - create_dir[n]='/'; - } - n++; - } - global_error=0; - // copy files - _FFS_to_FAT_Copy(ffsdirpath, fatdirpath); - - ret=global_error=0; - } - else ret=-101; - - ISFS_Deinitialize(); - - -return ret; - -} - -static char temp_cad[512]; - -void create_FAT_FFS_Directory(struct discHdr *header) -{ - -char device[2][4]={ - "sd:", - "ud:" -}; - - -if(!header) return; - - sprintf((char *) temp_cad,"%s/nand%c", &device[(nand_mode & 2)!=0][0], (nand_mode & 0xc) ? 49+((nand_mode>>2) & 3) : '\0'); - - sprintf((char *) temp_cad+32,"%2.2x%2.2x%2.2x%2.2x", header->id[0], header->id[1], header->id[2], header->id[3]); - - - sprintf((char *) temp_cad+64,"%s/title/00010000/%s", temp_cad, temp_cad+32); - sprintf((char *) temp_cad+128,"%s/title/00010004/%s", temp_cad, temp_cad+32); - sprintf((char *) temp_cad+256,"/title/00010000/%s", temp_cad+32); - sprintf((char *) temp_cad+384,"/title/00010004/%s", temp_cad+32); - - -} - -int test_FAT_game(char * directory) -{ -DIR_ITER * dir=NULL; - - dir= diropen(directory); - - if(dir) {dirclose(dir);return 1;} - -return 0; -} - - -char *get_FAT_directory1(void) -{ - return temp_cad+64; -} - -char *get_FAT_directory2(void) -{ - return temp_cad+128; -} - -char *get_FFS_directory1(void) -{ - return temp_cad+256; -} - -char *get_FFS_directory2(void) -{ - return temp_cad+384; -} diff --git a/source/mload/fatffs_util.h b/source/mload/fatffs_util.h deleted file mode 100644 index c438776b..00000000 --- a/source/mload/fatffs_util.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef _FAT_UTIL_ -#define _FAT_UTIL_ - -#include - -#include "usbloader/disc.h" - -s32 FAT_DeleteDir(const char *dirpath); - -s32 FFS_to_FAT_Copy(const char *ffsdirpath, const char *fatdirpath); - -void create_FAT_FFS_Directory(struct discHdr *header); - -int test_FAT_game(char * directory); - -char *get_FAT_directory1(void); - -char *get_FAT_directory2(void); - -char *get_FFS_directory1(void); - -char *get_FFS_directory2(void); - -#endif diff --git a/source/mload/mload.c b/source/mload/mload.c index 709b5067..612009c7 100644 --- a/source/mload/mload.c +++ b/source/mload/mload.c @@ -484,115 +484,52 @@ return ret; } -/* -int load_ehc_module() +int mload_get_version() { - int is_ios=0; - FILE *fp; - - if(!external_ehcmodule) - { - - fp=fopen("SD:/apps/usbloader_gx/ehcmodule.elf","rb"); - if(fp==NULL) - fp=fopen("SD:/apps/usbloadergx/ehcmodule.elf","rb"); - - if(fp!=NULL) - { - - fseek(fp, 0, SEEK_END); - size_external_ehcmodule = ftell(fp); - external_ehcmodule = memalign(32, size_external_ehcmodule); - if(!external_ehcmodule) - {fclose(fp);} - else - { - fseek(fp, 0, SEEK_SET); - - if(fread(external_ehcmodule,1, size_external_ehcmodule ,fp)!=size_external_ehcmodule) - {free(external_ehcmodule); external_ehcmodule=NULL;} - - fclose(fp); - } - } - } - - if(!external_ehcmodule) - { - if(mload_init()<0) return -1; - - if (IOS_GetRevision() == 4) { - gprintf("Loading ehcmodule v4\n"); - mload_elf((void *) ehcmodule_frag_v4_bin, &my_data_elf); - } else if (IOS_GetRevision() == 0) { // 0? Strange value for v5 ehcmodule - gprintf("Loading ehcmodule v5\n"); - mload_elf((void *) ehcmodule_frag_v5_bin, &my_data_elf); - } - thread_id = mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio); - if(thread_id < 0) return -1; - } - else - { - if(mload_init()<0) return -1; - mload_elf((void *) external_ehcmodule, &my_data_elf); - thread_id = mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio); - if(thread_id<0) return -1; - } - usleep(350*1000); - - - // Test for IOS - mload_seek(0x20207c84, SEEK_SET); - mload_read(patch_datas, 4); - if(patch_datas[0]==0x6e657665) - { - is_ios=38; - } - else - { - is_ios=36; - } - - if(is_ios==36) - { - // IOS 36 - memcpy(ios_36, dip_plugin, 4); // copy the entry_point - memcpy((void *) dip_plugin, ios_36, 4*10); // copy the adresses from the array - - mload_seek(0x1377E000, SEEK_SET); // copy dip_plugin in the starlet - mload_write(dip_plugin,size_dip_plugin); - - // enables DIP plugin - mload_seek(0x20209040, SEEK_SET); - mload_write(ios_36, 4); - - } - if(is_ios==38) - { - // IOS 38 - - memcpy(ios_38, dip_plugin, 4); // copy the entry_point - memcpy((void *) dip_plugin, ios_38, 4*10); // copy the adresses from the array - - mload_seek(0x1377E000, SEEK_SET); // copy dip_plugin in the starlet - mload_write(dip_plugin,size_dip_plugin); - - // enables DIP plugin - mload_seek(0x20208030, SEEK_SET); - mload_write(ios_38, 4); - - } - - mload_close(); - -return 0; + int ret; + if(mload_init()<0) return -1; + ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_MLOAD_VERSION, ":"); + return ret; } -int patch_cios_data() { - patch_datas[0]=*((u32 *) (dip_plugin+16*4)); - mload_set_ES_ioctlv_vector((void *) patch_datas[0]); - return 1; + + +/* IOS info structure */ +typedef struct { + /* Syscall base */ + u32 syscall; + + /* Module versions */ + u32 dipVersion; + u32 esVersion; + u32 ffsVersion; + u32 iopVersion; +} iosInfo; + +int wanin_mload_get_IOS_base() +{ + int ret; + iosInfo ios; + memset(&ios, 0, sizeof(ios)); + + if(mload_init()<0) return -1; + + ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_IOS_BASE, ":d", &ios, sizeof(ios)); + //printf("get_ios_base: %d %x\n", ret, ios.dipVersion); + if (ret == 0) { + switch(ios.dipVersion) { + case 0x48776F72: /* DIP: 07/11/08 14:34:26 */ + return 37; + + case 0x4888E14C: /* DIP: 07/24/08 20:08:44 */ + return 38; + + case 0x4A262AF5: /* DIP: 06/03/09 07:49:09 */ + return 57; + + case 0x492ACA9D: /* DIP: 11/24/08 15:39:09 */ + return 60; + } + } + return ret; } -*/ - - diff --git a/source/mload/mload.h b/source/mload/mload.h index b360faf6..a5d1f56b 100644 --- a/source/mload/mload.h +++ b/source/mload/mload.h @@ -28,6 +28,8 @@ #define MLOAD_MLOAD_THREAD_ID 0x4D4C4400 #define MLOAD_GET_IOS_BASE 0x4D4C4401 +#define MLOAD_GET_MLOAD_VERSION 0x4D4C4402 + #define MLOAD_LOAD_MODULE 0x4D4C4480 #define MLOAD_RUN_MODULE 0x4D4C4481 #define MLOAD_RUN_THREAD 0x4D4C4482 diff --git a/source/mload/mload_modules.c b/source/mload/mload_modules.c index a1090d51..a13164da 100644 --- a/source/mload/mload_modules.c +++ b/source/mload/mload_modules.c @@ -1,12 +1,11 @@ #include "mload_modules.h" -#include "ehcmodule_frag_v4_bin.h" -#include "ehcmodule_frag_v5_bin.h" +#include "ehcmodule_frag_bin.h" +#include "dip_plugin_249.h" +#include "sys.h" #include "gecko.h" #define ALIGNED(x) __attribute__((aligned(x))) -#define DEBUG_MLOAD - /* Used for Hermes NAND emulation */ int global_mount; int sd_ok=0; @@ -83,7 +82,6 @@ static u32 ios_60[16] ATTRIBUTE_ALIGN(32)= 0x20203750+1, // ios_printf (thumb) }; - u32 patch_datas[8] ATTRIBUTE_ALIGN(32); data_elf my_data_elf; @@ -93,105 +91,19 @@ int size_external_ehcmodule=0; static int my_thread_id=0; -int load_ehc_module() +int load_ehc_module_hermes() { -int is_ios=0; + int is_ios=0; -#if 0 - -FILE *fp; - -// WARNING!!!: load external module suspended -if(sd_ok && !external_ehcmodule) - { - - fp=fopen("sd:/apps/usbloader_gx/ehcmodule.elf","rb"); - if(fp==NULL) - fp=fopen("sd:/apps/usbloadergx/ehcmodule.elf","rb"); - - if(fp!=0) - { - fseek(fp, 0, SEEK_END); - size_external_ehcmodule = ftell(fp); - external_ehcmodule= memalign(32, size_external_ehcmodule); - if(!external_ehcmodule) - {fclose(fp);} - else - { - fseek(fp, 0, SEEK_SET); - - if(fread(external_ehcmodule,1, size_external_ehcmodule ,fp)!=size_external_ehcmodule) - {free(external_ehcmodule); external_ehcmodule=NULL;} - - fclose(fp); - } - } - } -#endif - -/* if(mload_init()<0) return -1; - mload_elf((void *) logmodule, &my_data_elf); + mload_elf((void *) ehcmodule_frag_bin, &my_data_elf); my_thread_id= mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio); - if(my_thread_id<0) return -1; - */ - - if(!external_ehcmodule) - { -#ifdef DEBUG_MLOAD -gprintf("before mload_init\n"); -#endif - if(mload_init()<0) return -1; -#ifdef DEBUG_MLOAD - gprintf("after mload_init\n"); -#endif - if (IOS_GetRevision() == 4) { -#ifdef DEBUG_MLOAD - gprintf("Loading ehcmodule v4\n"); -#endif - mload_elf((void *) ehcmodule_frag_v4_bin, &my_data_elf); - } else if (IOS_GetRevision() == 65535) { -#ifdef DEBUG_MLOAD - gprintf("Loading ehcmodule v5\n"); -#endif - mload_elf((void *) ehcmodule_frag_v5_bin, &my_data_elf); - } else { - return -2; - } -// mload_elf((void *) ehcmodule, &my_data_elf); -#ifdef DEBUG_MLOAD - gprintf("before mload_run_thread\n"); -#endif - my_thread_id= mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio); - if(my_thread_id<0) return -1; - //if(mload_module(ehcmodule, size_ehcmodule)<0) return -1; - } - else - { - //if(mload_module(external_ehcmodule, size_external_ehcmodule)<0) return -1; - if(mload_init()<0) return -1; - mload_elf((void *) external_ehcmodule, &my_data_elf); - my_thread_id= mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, my_data_elf.prio); - if(my_thread_id<0) return -1; - } + if(my_thread_id<0) return -2; usleep(350*1000); // Test for IOS - #if 0 - mload_seek(0x20207c84, SEEK_SET); - mload_read(patch_datas, 32); - if(patch_datas[0]==0x6e657665 ) - { - is_ios=38; - } - else - { - is_ios=36; - } - -#endif is_ios=mload_get_IOS_base(); switch(is_ios) @@ -264,11 +176,39 @@ gprintf("before mload_init\n"); } - mload_close(); - -return 0; + return 0; } +int load_dip_249() +{ + gprintf("load_dip_249\n"); + int ret = -1; + if (is_ios_type(IOS_TYPE_WANIN) && IOS_GetRevision() >= 18) + { + gprintf("mload_init\n"); + if(mload_init()<0) { + return -2; + } + gprintf("mload_module\n"); + ret = mload_module(dip_plugin_249, size_dip_plugin_249); + gprintf("mload_close\n"); + mload_close(); + } + gprintf("mload done\n"); + return ret; +} + +int load_ehc_module() +{ + if (is_ios_type(IOS_TYPE_HERMES)) + return load_ehc_module_hermes(); + else if (is_ios_type(IOS_TYPE_WANIN)) + return load_dip_249(); + return -1; +} + +#if 0 + #define IOCTL_FAT_MOUNTSD 0xF0 #define IOCTL_FAT_UMOUNTSD 0xF1 #define IOCTL_FAT_MOUNTUSB 0xF2 @@ -428,6 +368,8 @@ s32 ret; return ret; } +#endif + void enable_ES_ioctlv_vector(void) { patch_datas[0]=*((u32 *) (dip_plugin+16*4)); @@ -463,11 +405,7 @@ void test_and_patch_for_port1() u8 * ehc_data = NULL; - if (IOS_GetRevision() == 4) { - ehc_data=search_for_ehcmodule_cfg((void *) ehcmodule_frag_v4_bin, ehcmodule_frag_v4_bin_size); - } else if (IOS_GetRevision() == 65535) { - ehc_data=search_for_ehcmodule_cfg((void *) ehcmodule_frag_v5_bin, ehcmodule_frag_v5_bin_size); - } + ehc_data=search_for_ehcmodule_cfg((void *) ehcmodule_frag_bin, ehcmodule_frag_bin_size); if(ehc_data) { diff --git a/source/patches/fst.c b/source/patches/fst.c index d243a503..8ac1dc57 100644 --- a/source/patches/fst.c +++ b/source/patches/fst.c @@ -32,7 +32,7 @@ #include "fatmounter.h" #include "settings/cfg.h" #include "mload/mload.h" -#include "mload/dip_plugin.h" +#include "mload/mload_modules.h" #include "gecko.h" #include "patchcode.h" @@ -830,9 +830,7 @@ u32 do_bca_code(u8 *gameid) } } - mload_seek(*((u32 *) (dip_plugin+15*4)), SEEK_SET); // offset 15 (bca_data area) - mload_write(bcaCode, 64); - mload_close(); + Set_DIP_BCA_Datas((u8 *) &bcaCode); } return 0; } diff --git a/source/prompts/PromptWindows.cpp b/source/prompts/PromptWindows.cpp index 8433cde0..4536fe8a 100644 --- a/source/prompts/PromptWindows.cpp +++ b/source/prompts/PromptWindows.cpp @@ -1772,14 +1772,6 @@ DiscWait(const char *title, const char *msg, const char *btn1Label, const char * while (i >= 0) { VIDEO_WaitVSync(); timerTxt.SetTextf("%u %s", i,tr("seconds left")); - /* HaltGui(); - if (Settings.cios == ios222) { - ret = IOS_ReloadIOS(222); - load_ehc_module(); - } else { - ret = IOS_ReloadIOS(249); - } - ResumeGui();*/ sleep(1); USBDevice_deInit(); USBDevice_Init(); diff --git a/source/prompts/TitleBrowser.cpp b/source/prompts/TitleBrowser.cpp index ba08b19a..35d7f6dc 100644 --- a/source/prompts/TitleBrowser.cpp +++ b/source/prompts/TitleBrowser.cpp @@ -205,7 +205,7 @@ int TitleBrowser(u32 type) { } } if (!found) { - if (getName00(name[i], TITLE_ID(0x00010002, sys_titles[i-num_titles]))>=0) + if (getName00(name[i], TITLE_ID(0x00010002, sys_titles[i-num_titles]), 2)>=0) found=2; if (!found) { diff --git a/source/settings/Settings.cpp b/source/settings/Settings.cpp index 29e899b5..8639f9bc 100644 --- a/source/settings/Settings.cpp +++ b/source/settings/Settings.cpp @@ -47,20 +47,12 @@ static const char *opts_no_yes[settings_off_on_max] = {trNOOP("No"),trNOOP("Yes" static const char *opts_off_on[settings_off_on_max] = {trNOOP("OFF"),trNOOP("ON") }; static const char *opts_videomode[settings_language_max][2] = {{"",trNOOP("Disc Default")},{trNOOP("System Default"),""},{trNOOP("AutoPatch"),""},{trNOOP("Force"), " PAL50"},{trNOOP("Force")," PAL60"},{trNOOP("Force")," NTSC"}}; static const char *opts_language[settings_language_max] = {trNOOP("Console Default"),trNOOP("Japanese"),trNOOP("English"),trNOOP("German"),trNOOP("French"),trNOOP("Spanish"),trNOOP("Italian"),trNOOP("Dutch"),trNOOP("SChinese"),trNOOP("TChinese"),trNOOP("Korean")}; -static const char *opts_cios[settings_ios_max] = {"IOS 249","IOS 222", "IOS 223", "IOS 250"}; +static const char *opts_cios[settings_cios_max] = {"IOS 249","IOS 222", "IOS 223", "IOS 224", "IOS 250"}; static const char *opts_parentalcontrol[5] = {trNOOP("0 (Everyone)"),trNOOP("1 (Child 7+)"),trNOOP("2 (Teen 12+)"),trNOOP("3 (Mature 16+)"),trNOOP("4 (Adults Only 18+)")}; static const char *opts_error002[settings_error002_max] = {trNOOP("No"),trNOOP("Yes"),trNOOP("Anti")}; static const char *opts_partitions[settings_partitions_max] = {trNOOP("Game partition"),trNOOP("All partitions"), trNOOP("Remove update")}; static const char *opts_installdir[settings_installdir_max] = {trNOOP("None"), trNOOP("GAMEID_Gamename"), trNOOP("Gamename [GAMEID]")}; -bool IsValidPartition(int fs_type, int cios) { - if (cios == 249 || cios == 250) { - return fs_type == FS_TYPE_WBFS; - } else { - return fs_type == FS_TYPE_WBFS || fs_type == FS_TYPE_FAT32 || fs_type == FS_TYPE_NTFS; - } -} - /**************************************************************************** * MenuSettings ***************************************************************************/ @@ -1003,9 +995,6 @@ int MenuSettings() if (++Settings.cios >= settings_cios_max) { Settings.cios = 0; } - if ((Settings.cios == 1 && ios222rev!=4) || (Settings.cios == 2 && ios223rev != 4)) { - WindowPrompt(tr("Hermes CIOS"),tr("USB Loader GX will only run with Hermes CIOS rev 4! Please make sure you have revision 4 installed!"),tr("OK")); - } } if (Settings.godmode == 1) options2.SetValue(Idx, "%s", opts_cios[Settings.cios]); @@ -1017,12 +1006,7 @@ int MenuSettings() { if (firstRun) options2.SetName(Idx, "%s", tr("Partition")); if (ret == Idx) { - // Select the next valid partition, even if that's the same one - do - { - Settings.partition = Settings.partition + 1 == partitions.num ? 0 : Settings.partition + 1; - } - while (!IsValidPartition(partitions.pinfo[Settings.partition].fs_type, Settings.cios)); + Settings.partition = Settings.partition + 1 == partitions.num ? 0 : Settings.partition + 1; } PartInfo pInfo = partitions.pinfo[Settings.partition]; @@ -2216,8 +2200,7 @@ int MenuSettings() ResumeGui(); return menu; - } - +} /******************************************************************************** *Game specific settings @@ -2438,9 +2421,8 @@ int GameSettings(struct discHdr * header) mainWindow->Append(&w); - - - if (game_cfg) { //if there are saved settings for this game use them + CFG_set_game_default(); + if (game_cfg) { videoChoice = game_cfg->video; languageChoice = game_cfg->language; ocarinaChoice = game_cfg->ocarina; @@ -2454,35 +2436,11 @@ int GameSettings(struct discHdr * header) reloadblock = game_cfg->iosreloadblock; strlcpy(alternatedname, game_cfg->alternatedolname, sizeof(alternatedname)); } - else - { - videoChoice = Settings.video; - languageChoice = Settings.language; - ocarinaChoice = Settings.ocarina; - viChoice = Settings.vpatch; - if (Settings.cios == ios222) - iosChoice = i222; - else if (Settings.cios == ios250) - iosChoice = i250; - else if (Settings.cios == ios223) - iosChoice = i223; - else - iosChoice = i249; - parentalcontrolChoice = 0; - fix002 = Settings.error002; - countrystrings = Settings.patchcountrystrings; - alternatedol = off; - alternatedoloffset = 0; - reloadblock = off; - strcpy(alternatedname, ""); - } - + ResumeGui(); while (MainButton1.GetEffect() > 0) usleep(50); - - while (menu == MENU_NONE) { VIDEO_WaitVSync (); @@ -2633,7 +2591,7 @@ int GameSettings(struct discHdr * header) if(ret == ++Idx || firstRun) { if(firstRun) options2.SetName(Idx, "IOS"); - if(ret == Idx && ++iosChoice >= settings_ios_max) + if(ret == Idx && ++iosChoice >= settings_cios_max) iosChoice = 0; options2.SetValue(Idx,"%s",opts_cios[iosChoice]); } @@ -2972,25 +2930,7 @@ int GameSettings(struct discHdr * header) int choice1 = WindowPrompt(tr("Are you sure?"),0,tr("Yes"),tr("Cancel")); if (choice1 == 1) { - videoChoice = Settings.video; - viChoice = Settings.vpatch; - languageChoice = Settings.language; - ocarinaChoice = Settings.ocarina; - fix002 = Settings.error002; - countrystrings = Settings.patchcountrystrings; - alternatedol = off; - alternatedoloffset = 0; - reloadblock = off; - if (Settings.cios == ios222) - iosChoice = i222; - else if (Settings.cios == ios250) - iosChoice = i250; - else if (Settings.cios == ios223) - iosChoice = i223; - else - iosChoice = i249; - parentalcontrolChoice = 0; - strcpy(alternatedname, ""); + CFG_set_game_default(); CFG_forget_game_opt(header->id); /* commented because the database language now depends on the main language setting, this could be enabled again if there is a separate language setting for the database // if default language is different than language from main settings, reload titles @@ -3036,8 +2976,6 @@ int GameSettings(struct discHdr * header) w.SetEffect(EFFECT_FADE, -20); while (w.GetEffect()>0) usleep(50); - - HaltGui(); mainWindow->RemoveAll(); diff --git a/source/settings/cfg.c b/source/settings/cfg.c index e66fc208..d054d8cd 100644 --- a/source/settings/cfg.c +++ b/source/settings/cfg.c @@ -1258,7 +1258,6 @@ void cfg_parsearg(int argc, char **argv) // PER-GAME SETTINGS - // return existing or new struct Game_CFG* cfg_get_game(u8 *id) { struct Game_CFG *game = CFG_get_game_opt(id); @@ -1269,6 +1268,22 @@ struct Game_CFG* cfg_get_game(u8 *id) { return game; } +void CFG_set_game_default() +{ + videoChoice = Settings.video; + viChoice = Settings.vpatch; + languageChoice = Settings.language; + ocarinaChoice = Settings.ocarina; + fix002 = Settings.error002; + countrystrings = Settings.patchcountrystrings; + alternatedol = off; + alternatedoloffset = 0; + reloadblock = off; + iosChoice = Settings.cios; + parentalcontrolChoice = 0; + strcpy(alternatedname, ""); +} + // current options to game void cfg_set_game_opt(struct Game_CFG *game, u8 *id) { strncpy((char*)game->id, (char*)id, 6); @@ -1738,6 +1753,7 @@ struct Game_CFG* CFG_get_game_opt(u8 *id) { return &cfg_game[i]; } } + CFG_set_game_default(); return NULL; } @@ -1935,3 +1951,21 @@ void GetLanguageToLangCode(int *langid, char *langcode) { break; } } + +int ciosSetting2Cios(int setting) +{ + switch (setting) { + case ios222: + return 222; + case ios223: + return 223; + case ios224: + return 224; + case ios250: + return 250; + case ios249: + default: + return 249; + } + +} diff --git a/source/settings/cfg.h b/source/settings/cfg.h index 9f01df53..fec6f489 100644 --- a/source/settings/cfg.h +++ b/source/settings/cfg.h @@ -239,6 +239,7 @@ extern "C" { void CFG_Load(void); struct Game_CFG* CFG_get_game_opt(u8 *id); struct Game_NUM* CFG_get_game_num(u8 *id); + void CFG_set_game_default(); bool CFG_save_game_opt(u8 *id); bool CFG_save_game_num(u8 *id); bool CFG_reset_all_playcounters(); @@ -298,18 +299,11 @@ extern "C" { settings_sinfo_max // always the last entry }; - enum { - i249=0, - i222, - i223, - i250, - settings_ios_max // always the last entry - }; - enum { ios249=0, ios222, ios223, + ios224, ios250, settings_cios_max // always the last entry }; @@ -464,6 +458,8 @@ extern "C" { void GetLanguageToLangCode(int *langid, char *langcode); bool OpenXMLDatabase(char* xmlfilepath, char* argdblang, bool argJPtoEN, bool openfile, bool loadtitles, bool freemem); + int ciosSetting2Cios(int setting); + char *get_title(struct discHdr *header); char *cfg_get_title(u8 *id) ; void title_set(char *id, char *title); diff --git a/source/sys.cpp b/source/sys.c similarity index 79% rename from source/sys.cpp rename to source/sys.c index 68abdfc8..59899d14 100644 --- a/source/sys.cpp +++ b/source/sys.c @@ -1,283 +1,323 @@ -#include -#include -#include - -#include "usbloader/wdvd.h" -#include "usbloader/usbstorage2.h" -#include "usbloader/disc.h" -#include "usbloader/wbfs.h" -#include "usbloader/partition_usbloader.h" -#include "mload/mload_modules.h" -#include "video.h" -#include "audio.h" -#include "menu.h" -#include "fatmounter.h" -#include "sys.h" -#include "wpad.h" - -extern char game_partition[6]; -extern u8 load_from_fs; - -//Wiilight stuff -static vu32 *_wiilight_reg = (u32*)0xCD0000C0; -void wiilight(int enable) { // Toggle wiilight (thanks Bool for wiilight source) - u32 val = (*_wiilight_reg&~0x20); - if (enable && Settings.wiilight) val |= 0x20; - *_wiilight_reg=val; -} - -/* Variables */ -u8 shutdown = 0; -u8 reset = 0; - -void __Sys_ResetCallback(void) { - /* Reboot console */ - reset = 1; -} - -void __Sys_PowerCallback(void) { - /* Poweroff console */ - shutdown = 1; -} - -void Sys_Init(void) { - /* Initialize video subsytem */ - //VIDEO_Init(); - - /* Set RESET/POWER button callback */ - SYS_SetResetCallback(__Sys_ResetCallback); - SYS_SetPowerCallback(__Sys_PowerCallback); -} - -static void _ExitApp() { - ExitGUIThreads(); - StopGX(); - ShutdownAudio(); - - UnmountNTFS(); - SDCard_deInit(); - USBDevice_deInit(); - mload_set_ES_ioctlv_vector(NULL); - mload_close(); -} - -void Sys_Reboot(void) { - /* Restart console */ - _ExitApp(); - STM_RebootSystem(); -} - -int Sys_ChangeIos(int ios) { - s32 prevIos = IOS_GetVersion(); - - SDCard_deInit(); - USBDevice_deInit(); - - WPAD_Flush(0); - WPAD_Disconnect(0); - WPAD_Shutdown(); - - WDVD_Close(); - - USBStorage2_Deinit(); - - s32 ret = IOS_ReloadIOSsafe(ios); - if (ret < 0) { - ios = prevIos; - } - - SDCard_Init(); - - if (ios == 222 || ios == 223) { - load_ehc_module(); - } - USBDevice_Init(); - - PAD_Init(); - Wpad_Init(); - WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); - WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight); - - WBFS_Init(WBFS_DEVICE_USB); - Disc_Init(); - - if (Sys_IsHermes()) { - WBFS_OpenNamed((char *) &game_partition); - } else { - WBFS_Open(); - } - - return ret; -} - -int Sys_IosReload(int IOS) { - s32 ret = -1; - - //shutdown SD and USB before IOS Reload in DiscWait - SDCard_deInit(); - USBDevice_deInit(); - - WPAD_Flush(0); - WPAD_Disconnect(0); - WPAD_Shutdown(); - - WDVD_Close(); - - USBStorage2_Deinit(); - - if (IOS == 249 || IOS == 222 || IOS == 223) { - for (int i = 0; i < 10; i++) { - ret = IOS_ReloadIOSsafe(IOS); - if (ret < 0) return ret; - if (IOS == 222 || IOS == 223) load_ehc_module(); - ret = WBFS_Init(WBFS_DEVICE_USB); - if (!(ret < 0)) break; - sleep(1); - USBStorage2_Deinit(); - } - if (ret>=0) { - ret = Disc_Init(); - if (ret>=0) { - ret = WBFS_Open(); - } - } else Sys_BackToLoader(); - } - - PAD_Init(); - Wpad_Init(); - WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); - WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight); - //reinitialize SD and USB - SDCard_Init(); - USBDevice_Init(); - - return ret; -} - -#define ShutdownToDefault 0 -#define ShutdownToIdle 1 -#define ShutdownToStandby 2 - -static void _Sys_Shutdown(int SHUTDOWN_MODE) { - _ExitApp(); - WPAD_Flush(0); - WPAD_Disconnect(0); - WPAD_Shutdown(); - - /* Poweroff console */ - if ((CONF_GetShutdownMode() == CONF_SHUTDOWN_IDLE && SHUTDOWN_MODE != ShutdownToStandby) || SHUTDOWN_MODE == ShutdownToIdle) { - s32 ret; - - /* Set LED mode */ - ret = CONF_GetIdleLedMode(); - if (ret >= 0 && ret <= 2) - STM_SetLedMode(ret); - - /* Shutdown to idle */ - STM_ShutdownToIdle(); - } else { - /* Shutdown to standby */ - STM_ShutdownToStandby(); - } -} -void Sys_Shutdown(void) { - _Sys_Shutdown(ShutdownToDefault); -} -void Sys_ShutdownToIdel(void) { - _Sys_Shutdown(ShutdownToIdle); -} -void Sys_ShutdownToStandby(void) { - _Sys_Shutdown(ShutdownToStandby); -} - -void Sys_LoadMenu(void) { - _ExitApp(); - /* Return to the Wii system menu */ - SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); -} - -void Sys_BackToLoader(void) { - if (*((u32*) 0x80001800)) { - _ExitApp(); - exit(0); - } - // Channel Version - Sys_LoadMenu(); -} - -bool Sys_IsHermes() { - return IOS_GetVersion() == 222 || IOS_GetVersion() == 223; -} - -#include "prompts/PromptWindows.h" - -void ShowMemInfo() { - char buf[255]; - struct mallinfo mymallinfo = mallinfo(); - sprintf((char *) &buf,"Total: %d, Used: %d, Can be freed: %d", mymallinfo.arena/1024, mymallinfo.uordblks/1024, mymallinfo.keepcost/1024); - WindowPrompt("Mem info", (char *) &buf, "OK"); -} - - -#include "wad/title.h" - -s32 ios222rev = -69; -s32 ios223rev = -69; -s32 ios249rev = -69; -s32 ios250rev = -69; - -s32 IOS_ReloadIOSsafe(int ios) -{ - if (ios==222) - { - if (ios222rev == -69) - ios222rev = getIOSrev(0x00000001000000dell); - - if (ios222rev > 0 && (ios222rev != 4 && ios222rev != 5))return -2; - } - else if (ios==223) - { - if (ios223rev == -69) - ios223rev = getIOSrev(0x00000001000000dfll); - - if (ios223rev > 0 && (ios223rev != 4 && ios223rev != 5))return -2; - } - else if (ios==249) - { - if (ios249rev == -69) - ios249rev = getIOSrev(0x00000001000000f9ll); - - if (ios249rev >= 0 && !(ios249rev>=9 && ios249rev<65280))return -2; - } - else if (ios==250) - { - if (ios250rev == -69) - ios250rev = getIOSrev(0x00000001000000fall); - - if (ios250rev >= 0 && !(ios250rev>=9 && ios250rev<65280))return -2; - } - - s32 r = IOS_ReloadIOS(ios); - if (r >= 0) { - WII_Initialize(); - } - return r; -} - -#include - -void ScreenShot() -{ - time_t rawtime; - struct tm * timeinfo; - char buffer [80]; - char buffer2 [80]; - - time ( &rawtime ); - timeinfo = localtime ( &rawtime ); - //USBLoader_GX_ScreenShot-Month_Day_Hour_Minute_Second_Year.png - strftime (buffer,80,"USBLoader_GX_ScreenShot-%b%d%H%M%S%y.png",timeinfo); - sprintf(buffer2, "%s/config/%s", bootDevice, buffer); - - TakeScreenshot(buffer2); -} +#include +#include +#include + +#include "settings/cfg.h" +#include "usbloader/wdvd.h" +#include "usbloader/usbstorage2.h" +#include "usbloader/disc.h" +#include "usbloader/wbfs.h" +#include "usbloader/partition_usbloader.h" +#include "mload/mload_modules.h" +// #include "menu.h" +#include "fatmounter.h" +#include "sys.h" +#include "wpad.h" + +extern char game_partition[6]; +extern u8 load_from_fs; + +extern int screenheight; +extern int screenwidth; + +//Wiilight stuff +static vu32 *_wiilight_reg = (u32*)0xCD0000C0; + +void wiilight(int enable) { // Toggle wiilight (thanks Bool for wiilight source) + u32 val = (*_wiilight_reg&~0x20); + if (enable && Settings.wiilight) val |= 0x20; + *_wiilight_reg=val; +} + +/* Variables */ +u8 shutdown = 0; +u8 reset = 0; + +void __Sys_ResetCallback(void) { + /* Reboot console */ + reset = 1; +} + +void __Sys_PowerCallback(void) { + /* Poweroff console */ + shutdown = 1; +} + +void Sys_Init(void) { + /* Initialize video subsytem */ + //VIDEO_Init(); + + /* Set RESET/POWER button callback */ + SYS_SetResetCallback(__Sys_ResetCallback); + SYS_SetPowerCallback(__Sys_PowerCallback); +} + +void ExitGUIThreads(void); +void StopAudio(); +void StopGX(); + +static void _ExitApp() { + ExitGUIThreads(); + StopGX(); + StopAudio(); + + UnmountNTFS(); + SDCard_deInit(); + USBDevice_deInit(); + mload_set_ES_ioctlv_vector(NULL); + mload_close(); +} + +void Sys_Reboot(void) { + /* Restart console */ + _ExitApp(); + STM_RebootSystem(); +} + +int Sys_ChangeIos(int ios) { + s32 prevIos = IOS_GetVersion(); + + SDCard_deInit(); + USBDevice_deInit(); + + WPAD_Flush(0); + WPAD_Disconnect(0); + WPAD_Shutdown(); + + WDVD_Close(); + + USBStorage2_Deinit(); + + s32 ret = IOS_ReloadIOSsafe(ios); + if (ret < 0) { + ios = prevIos; + } + + load_ehc_module(); + SDCard_Init(); + USBDevice_Init(); + + PAD_Init(); + Wpad_Init(); + WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); + WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight); + + WBFS_Init(WBFS_DEVICE_USB); + Disc_Init(); + + if (ios_supports_frag()) { + WBFS_OpenNamed((char *) &game_partition); + } else { + WBFS_Open(); + } + + return ret; +} + +int Sys_IosReload(int IOS) { + s32 ret = -1; + + //shutdown SD and USB before IOS Reload in DiscWait + SDCard_deInit(); + USBDevice_deInit(); + + WPAD_Flush(0); + WPAD_Disconnect(0); + WPAD_Shutdown(); + + WDVD_Close(); + + USBStorage2_Deinit(); + + if (is_ios_type(IOS_TYPE_HERMES) || is_ios_type(IOS_TYPE_WANIN)) { + int i; + for (i = 0; i < 10; i++) { + ret = IOS_ReloadIOSsafe(IOS); + if (ret < 0) return ret; + load_ehc_module(); + ret = WBFS_Init(WBFS_DEVICE_USB); + if (!(ret < 0)) break; + sleep(1); + USBStorage2_Deinit(); + } + if (ret>=0) { + ret = Disc_Init(); +/* + if (ret>=0) { + if (ios_supports_frag() && game_partition[0] != '\0') { + ret = WBFS_OpenNamed((char *) &game_partition); + } else { + ret = WBFS_Open(); + } + } +*/ + } else Sys_BackToLoader(); + } + + PAD_Init(); + Wpad_Init(); + WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); + WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight); + //reinitialize SD and USB + SDCard_Init(); + USBDevice_Init(); + + return ret; +} + +#define ShutdownToDefault 0 +#define ShutdownToIdle 1 +#define ShutdownToStandby 2 + +static void _Sys_Shutdown(int SHUTDOWN_MODE) { + _ExitApp(); + WPAD_Flush(0); + WPAD_Disconnect(0); + WPAD_Shutdown(); + + /* Poweroff console */ + if ((CONF_GetShutdownMode() == CONF_SHUTDOWN_IDLE && SHUTDOWN_MODE != ShutdownToStandby) || SHUTDOWN_MODE == ShutdownToIdle) { + s32 ret; + + /* Set LED mode */ + ret = CONF_GetIdleLedMode(); + if (ret >= 0 && ret <= 2) + STM_SetLedMode(ret); + + /* Shutdown to idle */ + STM_ShutdownToIdle(); + } else { + /* Shutdown to standby */ + STM_ShutdownToStandby(); + } +} +void Sys_Shutdown(void) { + _Sys_Shutdown(ShutdownToDefault); +} +void Sys_ShutdownToIdel(void) { + _Sys_Shutdown(ShutdownToIdle); +} +void Sys_ShutdownToStandby(void) { + _Sys_Shutdown(ShutdownToStandby); +} + +void Sys_LoadMenu(void) { + _ExitApp(); + /* Return to the Wii system menu */ + SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); +} + +void Sys_BackToLoader(void) { + if (*((u32*) 0x80001800)) { + _ExitApp(); + exit(0); + } + // Channel Version + Sys_LoadMenu(); +} + +bool Sys_IsHermes() { + return IOS_GetVersion() == 222 || IOS_GetVersion() == 223; +} + +// #include "prompts/PromptWindows.h" + +void ShowMemInfo() { + char buf[255]; + struct mallinfo mymallinfo = mallinfo(); + sprintf((char *) &buf,"Total: %d, Used: %d, Can be freed: %d", mymallinfo.arena/1024, mymallinfo.uordblks/1024, mymallinfo.keepcost/1024); +// WindowPrompt("Mem info", (char *) &buf, "OK"); +} + + +#include "wad/title.h" + +s32 ios222rev = -69; +s32 ios223rev = -69; +s32 ios249rev = -69; +s32 ios250rev = -69; + +s32 IOS_ReloadIOSsafe(int ios) +{ + if (ios==222) + { + if (ios222rev == -69) + ios222rev = getIOSrev(0x00000001000000dell); + + if (ios222rev > 0 && (ios222rev != 4 && ios222rev != 5))return -2; + } + else if (ios==223) + { + if (ios223rev == -69) + ios223rev = getIOSrev(0x00000001000000dfll); + + if (ios223rev > 0 && (ios223rev != 4 && ios223rev != 5))return -2; + } + else if (ios==249) + { + if (ios249rev == -69) + ios249rev = getIOSrev(0x00000001000000f9ll); + + if (ios249rev >= 0 && !(ios249rev>=9 && ios249rev<65280))return -2; + } + else if (ios==250) + { + if (ios250rev == -69) + ios250rev = getIOSrev(0x00000001000000fall); + + if (ios250rev >= 0 && !(ios250rev>=9 && ios250rev<65280))return -2; + } + + s32 r = IOS_ReloadIOS(ios); + if (r >= 0) { + WII_Initialize(); + } + return r; +} + +#include + +s32 TakeScreenshot(const char *path); + +void ScreenShot() +{ + time_t rawtime; + struct tm * timeinfo; + char buffer [80]; + char buffer2 [80]; + + time ( &rawtime ); + timeinfo = localtime ( &rawtime ); + //USBLoader_GX_ScreenShot-Month_Day_Hour_Minute_Second_Year.png + strftime (buffer,80,"USBLoader_GX_ScreenShot-%b%d%H%M%S%y.png",timeinfo); + sprintf(buffer2, "%s/config/%s", bootDevice, buffer); + + TakeScreenshot(buffer2); +} + +int get_ios_type() +{ + switch (IOS_GetVersion()) { + case 249: + case 250: + return IOS_TYPE_WANIN; + case 222: + case 223: + if (IOS_GetRevision() == 1) + return IOS_TYPE_KWIIRK; + case 224: + return IOS_TYPE_HERMES; + } + return IOS_TYPE_UNK; +} + +int is_ios_type(int type) +{ + return (get_ios_type() == type); +} + +int ios_supports_frag() +{ + return ((is_ios_type(IOS_TYPE_HERMES) && IOS_GetRevision() >= 4) || + (is_ios_type(IOS_TYPE_WANIN) && IOS_GetRevision() >= 18)); +} diff --git a/source/sys.h b/source/sys.h index 2ee89d1b..7fd68b56 100644 --- a/source/sys.h +++ b/source/sys.h @@ -1,6 +1,10 @@ #ifndef _SYS_H_ #define _SYS_H_ +#ifdef __cplusplus +extern "C" { +#endif + void wiilight(int enable); /* Prototypes */ @@ -23,5 +27,18 @@ extern s32 ios223rev; extern s32 ios249rev; extern s32 ios250rev; +#define IOS_TYPE_UNK 0 +#define IOS_TYPE_WANIN 1 +#define IOS_TYPE_HERMES 2 +#define IOS_TYPE_KWIIRK 3 + +int get_ios_type(); +int is_ios_type(int type); +int ios_supports_frag(); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/usbloader/apploader.c b/source/usbloader/apploader.c index e7c8280c..68b55ceb 100644 --- a/source/usbloader/apploader.c +++ b/source/usbloader/apploader.c @@ -13,6 +13,7 @@ #include "settings/cfg.h" #include "gecko.h" #include "patches/wip.h" +#include "sys.h" extern bool geckoinit; @@ -251,7 +252,7 @@ void PretendThereIsADiscInTheDrive(void *buffer, u32 len) /** Thanks to WiiPower **/ bool NewSuperMarioBrosPatch(void *Address, int Size) { - if (IOS_GetVersion() == 222 || IOS_GetVersion() == 223) return false; // Don't use this when using Hermes, it'll use the BCA fix instead... + if (is_ios_type(IOS_TYPE_HERMES)) return false; // Don't use this when using Hermes, it'll use the BCA fix instead... if (memcmp("SMNE", (char *)0x80000000, 4) == 0) { diff --git a/source/usbloader/disc.c b/source/usbloader/disc.c index 9446b441..876e9e7f 100644 --- a/source/usbloader/disc.c +++ b/source/usbloader/disc.c @@ -8,13 +8,15 @@ #include "patches/fst.h" #include "apploader.h" #include "disc.h" -#include "video.h" #include "wdvd.h" #include "alternatedol.h" #include "memory.h" #include "wbfs.h" -#include "../gecko.h" -#include "../fatmounter.h" +#include "gecko.h" +#include "fatmounter.h" +#include "sys.h" +#include "frag.h" +#include "usbstorage2.h" /* Constants */ #define PTABLE_OFFSET 0x40000 @@ -240,15 +242,36 @@ s32 Disc_Wait(void) { } s32 Disc_SetUSB(const u8 *id) { - u32 part = 0; - if (wbfs_part_fs) { - part = wbfs_part_lba; - } else { - part = wbfs_part_idx ? wbfs_part_idx - 1 : 0; + if (is_ios_type(IOS_TYPE_HERMES)) { + u32 part = 0; + if (wbfs_part_fs) { + part = wbfs_part_lba; + } else { + part = wbfs_part_idx ? wbfs_part_idx - 1 : 0; + } + + int ret; + if (id && *id) { + ret = set_frag_list((u8 *) id); + } else { + ret = USBStorage_WBFS_SetFragList(NULL, 0); + } + + if (ret) { + return ret; + } + + /* Set USB mode */ + return WDVD_SetUSBMode(id, part); + } + + if (WBFS_DEVICE_USB && wbfs_part_fs) { + gprintf("Setting frag list for wanin\n"); + return set_frag_list((u8 *) id); } - /* Set USB mode */ - return WDVD_SetUSBMode(id, part); + gprintf("Setting disc usb thing for wanin\n"); + return WDVD_SetWBFSMode(WBFS_DEVICE_USB, (u8 *) id); } s32 Disc_ReadHeader(void *outbuf) { diff --git a/source/usbloader/frag.c b/source/usbloader/frag.c index c30c009b..c9053482 100644 --- a/source/usbloader/frag.c +++ b/source/usbloader/frag.c @@ -11,6 +11,9 @@ #include "usbstorage2.h" #include "frag.h" #include "utils.h" +#include "sys.h" +#include "wdvd.h" +#include "gecko.h" FragList *frag_list = NULL; @@ -152,27 +155,31 @@ int set_frag_list(u8 *id) { if (wbfs_part_fs == PART_FS_WBFS) return 0; if (frag_list == NULL) { - if (wbfs_part_fs == PART_FS_FAT) { - // fall back to old fat method -// printf("FAT: fallback to old method\n"); - return 0; - } - // ntfs has no fallback, return error return -1; } // (+1 for header which is same size as fragment) int size = sizeof(Fragment) * (frag_list->num + 1); - int ret = USBStorage_WBFS_SetFragList(frag_list, size); + int ret; + DCFlushRange(frag_list, size); + if (is_ios_type(IOS_TYPE_HERMES)) { + ret = USBStorage_WBFS_SetFragList(frag_list, size); + } else { + gprintf("Calling WDVD_SetFragList\n"); + ret = WDVD_SetFragList(wbfsDev, frag_list, size); + } if (ret) { -// printf("set_frag: %d\n", ret); return ret; } // verify id matches char discid[8]; memset(discid, 0, sizeof(discid)); - ret = USBStorage_WBFS_Read(0, 6, discid); - return 0; + if (is_ios_type(IOS_TYPE_HERMES)) { + ret = USBStorage_WBFS_Read(0, 8, discid); + } else { + ret = WDVD_UnencryptedRead(discid, 8, 0); + } + return (memcmp(id, discid, 6) != 0) ? -1 : 0; } diff --git a/source/usbloader/usbstorage2.c b/source/usbloader/usbstorage2.c index 989d9c5a..ba6be032 100644 --- a/source/usbloader/usbstorage2.c +++ b/source/usbloader/usbstorage2.c @@ -50,8 +50,8 @@ distribution. #define USB_IOCTL_WBFS_READ_DISC (WBFS_BASE+0x2) #define USB_IOCTL_WBFS_READ_DIRECT_DISC (WBFS_BASE+0x3) #define USB_IOCTL_WBFS_STS_DISC (WBFS_BASE+0x4) -#define USB_IOCTL_WBFS_SET_DEVICE (WBFS_BASE+0x50) -#define USB_IOCTL_WBFS_SET_FRAGLIST (WBFS_BASE+0x51) +#define USB_IOCTL_WBFS_SET_DEVICE (WBFS_BASE+0x14) +#define USB_IOCTL_WBFS_SET_FRAGLIST (WBFS_BASE+0x15) #define UMS_HEAPSIZE 0x1000 //0x10000 diff --git a/source/usbloader/wbfs.cpp b/source/usbloader/wbfs.cpp index 6d9e58b5..7eb1eb61 100644 --- a/source/usbloader/wbfs.cpp +++ b/source/usbloader/wbfs.cpp @@ -11,7 +11,6 @@ #include "gecko.h" Wbfs *current = NULL; -#define DEBUG_WBFS /* WBFS device */ s32 wbfsDev = WBFS_MIN_DEVICE; @@ -57,20 +56,11 @@ s32 WBFS_OpenPart(u32 part_fs, u32 part_idx, u32 part_lba, u32 part_size, char * if (part_fs == PART_FS_FAT) { current = new Wbfs_Fat(wbfsDev, part_lba, part_size); strcpy(wbfs_fs_drive, "USB:"); -#ifdef DEBUG_WBFS - gprintf("\n\tCreated WBFS_Fat instance at lba: %d of size %d", part_lba, part_size); -#endif } else if (part_fs == PART_FS_NTFS) { current = new Wbfs_Ntfs(wbfsDev, part_lba, part_size); strcpy(wbfs_fs_drive, "NTFS:"); -#ifdef DEBUG_WBFS - gprintf("\n\tCreated WBFS_Ntfs instance at lba: %d of size %d", part_lba, part_size); -#endif } else { current = new Wbfs_Wbfs(wbfsDev, part_lba, part_size); -#ifdef DEBUG_WBFS - gprintf("\n\tCreated WBFS_Wbfs instance at lba: %d of size %d", part_lba, part_size); -#endif } if (current->Open()) { diff --git a/source/usbloader/wbfs/wbfs_fat.cpp b/source/usbloader/wbfs/wbfs_fat.cpp index be539ebe..e3957f64 100644 --- a/source/usbloader/wbfs/wbfs_fat.cpp +++ b/source/usbloader/wbfs/wbfs_fat.cpp @@ -366,9 +366,6 @@ s32 Wbfs_Fat::GetHeadersCount() dir_iter = diropen(path); if (!dir_iter) return 0; - dir_iter = diropen(path); - if (!dir_iter) return 0; - while (dirnext(dir_iter, fname, &st) == 0) { //printf("found: %s\n", fname); Wpad_WaitButtonsCommon(); if ((char)fname[0] == '.') continue; diff --git a/source/usbloader/wdvd.c b/source/usbloader/wdvd.c index 2143ad79..5b0d65aa 100644 --- a/source/usbloader/wdvd.c +++ b/source/usbloader/wdvd.c @@ -17,6 +17,7 @@ #define IOCTL_DI_OFFSET 0xD9 #define IOCTL_DI_DISC_BCA 0xDA #define IOCTL_DI_STOPMOTOR 0xE3 +#define IOCTL_DI_SETWBFSMODE 0xF4 #define IOCTL_DI_SETUSBMODE 0xF4 #define IOCTL_DI_DISABLERESET 0xF6 @@ -24,6 +25,10 @@ #define DI_SETWBFSMODE 0xfe #define DI_SETOFFSETBASE 0xf1 +#define IOCTL_DI_SETFRAG 0xF9 +#define IOCTL_DI_GETMODE 0xFA +#define IOCTL_DI_HELLO 0xFB + /* Variables */ static u32 inbuf[8] ATTRIBUTE_ALIGN(32); static u32 outbuf[8] ATTRIBUTE_ALIGN(32); @@ -306,6 +311,27 @@ s32 WDVD_DisableReset(u8 val) { return (ret == 1) ? 0 : -ret; } +s32 WDVD_SetWBFSMode(u32 mode, u8 *discid) +{ + s32 ret; + + memset(inbuf, 0, sizeof(inbuf)); + + /* Set USB mode */ + inbuf[0] = IOCTL_DI_SETWBFSMODE << 24; + inbuf[1] = mode; + + /* Copy disc ID */ + if (discid) + memcpy(&inbuf[2], discid, 6); + + ret = IOS_Ioctl(di_fd, IOCTL_DI_SETWBFSMODE, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf)); + if (ret < 0) + return ret; + + return (ret == 1) ? 0 : -ret; +} + /** Hermes **/ s32 WDVD_SetUSBMode(const u8 *id, s32 partition) { s32 ret; @@ -319,9 +345,7 @@ s32 WDVD_SetUSBMode(const u8 *id, s32 partition) { /* Copy ID */ if (id) { memcpy(&inbuf[2], id, 6); - if (IOS_GetVersion() != 249) { - inbuf[5] = partition; - } + inbuf[5] = partition; } ret = IOS_Ioctl(di_fd, IOCTL_DI_SETUSBMODE, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf)); @@ -354,3 +378,25 @@ s32 WDVD_Read_Disc_BCA(void *buf) return (ret == 1) ? 0 : -ret; } + +s32 WDVD_SetFragList(int device, void *fraglist, int size) +{ + s32 ret; + + memset(inbuf, 0, sizeof(inbuf)); + memset(outbuf, 0, sizeof(outbuf)); + + /* Set FRAG mode */ + inbuf[0] = IOCTL_DI_SETFRAG << 24; + inbuf[1] = device; + inbuf[2] = (u32)fraglist; + inbuf[3] = size; + + DCFlushRange(fraglist, size); + ret = IOS_Ioctl(di_fd, IOCTL_DI_SETFRAG, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf)); + + if (ret < 0) + return ret; + + return (ret == 1) ? 0 : -ret; +} diff --git a/source/usbloader/wdvd.h b/source/usbloader/wdvd.h index 0f7848ff..43ca0760 100644 --- a/source/usbloader/wdvd.h +++ b/source/usbloader/wdvd.h @@ -22,8 +22,10 @@ extern "C" { s32 WDVD_WaitForDisc(void); s32 WDVD_GetCoverStatus(u32 *); s32 WDVD_DisableReset(u8); + s32 WDVD_SetWBFSMode(u32, u8 *); s32 WDVD_SetUSBMode(const u8 *, s32 partition); s32 WDVD_Read_Disc_BCA(void *buf); + s32 WDVD_SetFragList(int device, void *fraglist, int size); #ifdef __cplusplus } diff --git a/source/video.h b/source/video.h index 205f9950..9679f765 100644 --- a/source/video.h +++ b/source/video.h @@ -13,7 +13,7 @@ void InitVideo (); void InitVideodebug(); -void StopGX(); +extern "C" void StopGX(); void ResetVideo_Menu(); void Menu_Render(); void Menu_DrawImg(f32 xpos, f32 ypos, f32 zpos, f32 width, f32 height, u8 data[], @@ -21,7 +21,7 @@ void Menu_DrawImg(f32 xpos, f32 ypos, f32 zpos, f32 width, f32 height, u8 data[] void Menu_DrawTPLImg(f32 xpos, f32 ypos, f32 zpos, f32 width, f32 height, GXTexObj *texObj, f32 degrees, f32 scaleX, f32 scaleY, u8 alpha, int XX1, int YY1,int XX2, int YY2,int XX3, int YY3,int XX4, int YY4); void Menu_DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color, u8 filled); -s32 TakeScreenshot(const char *path); +extern "C" s32 TakeScreenshot(const char *path); extern int screenheight; extern int screenwidth; diff --git a/source/wad/title.h b/source/wad/title.h index 7086e34a..6685cf3b 100644 --- a/source/wad/title.h +++ b/source/wad/title.h @@ -42,7 +42,7 @@ extern "C" { s32 getNameBN(char *name, u64 id); // Get the name of a title from its 00000000.app in NAND - s32 getName00(char *name, u64 id, int lang = 2); + s32 getName00(char *name, u64 id, int lang); // Get string representation of lower title id char *titleText(u32 kind, u32 title);