From a09abe355f8d51c110f0f8b3188dd7cfbe69ddfd Mon Sep 17 00:00:00 2001 From: "e.bovendeur" Date: Sun, 15 Nov 2009 19:52:58 +0000 Subject: [PATCH] * Added FAT support (Issue 1054) * Fixed issue 1058 * Menus splitted to several smaller files, to reduce compile time This version has FAT support. You can change the used partition in the game load options. Default WBFS will be used, if found. Otherwise the first FAT partition with games will be used. FAT will only work when using Hermes cios (222/223)!!! --- Makefile | 10 +- data/ehcmodule_fat.bin | Bin 0 -> 59469 bytes gui.pnps | 2 +- source/banner/banner.c | 2 +- source/bannersound.cpp | 4 +- source/fatmounter.c | 79 +- source/fatmounter.h | 9 + source/homebrewboot/HomebrewBrowse.cpp | 7 +- source/libwbfs/libwbfs.c | 54 + source/libwbfs/libwbfs.h | 10 + source/libwiigui/gui_gamecarousel.cpp | 63 - source/libwiigui/gui_gamecarousel.h | 1 - source/main.cpp | 30 +- source/menu.cpp | 2007 +----------------------- source/menu/menu_check.cpp | 151 ++ source/menu/menu_disclist.cpp | 1508 ++++++++++++++++++ source/menu/menu_format.cpp | 188 +++ source/menu/menu_install.cpp | 154 ++ source/menu/menus.h | 24 + source/mload/ehcmodule.c | 1171 -------------- source/mload/ehcmodule.h | 3 - source/mload/mload.c | 4 +- source/patches/fst.c | 18 +- source/patches/fst.h | 2 + source/prompts/ProgressWindow.cpp | 15 +- source/prompts/ProgressWindow.h | 4 - source/prompts/TitleBrowser.cpp | 7 +- source/settings/Settings.cpp | 46 +- source/settings/cfg.c | 16 +- source/settings/cfg.h | 1 + source/sys.cpp | 50 + source/sys.h | 2 + source/usbloader/alternatedol.c | 2 +- source/usbloader/disc.c | 12 +- source/usbloader/getentries.cpp | 1 + source/usbloader/partition.c | 142 +- source/usbloader/partition.h | 28 +- source/usbloader/splits.c | 313 ++++ source/usbloader/splits.h | 35 + source/usbloader/utils.h | 8 + source/usbloader/wbfs.c | 279 ++-- source/usbloader/wbfs.h | 20 +- source/usbloader/wbfs_fat.c | 339 ++++ source/usbloader/wbfs_fat.h | 15 + source/usbloader/wdvd.c | 6 +- source/usbloader/wdvd.h | 2 +- source/wad/title.h | 2 +- 47 files changed, 3493 insertions(+), 3353 deletions(-) create mode 100644 data/ehcmodule_fat.bin create mode 100644 source/menu/menu_check.cpp create mode 100644 source/menu/menu_disclist.cpp create mode 100644 source/menu/menu_format.cpp create mode 100644 source/menu/menu_install.cpp create mode 100644 source/menu/menus.h delete mode 100644 source/mload/ehcmodule.c delete mode 100644 source/mload/ehcmodule.h create mode 100644 source/usbloader/splits.c create mode 100644 source/usbloader/splits.h create mode 100644 source/usbloader/wbfs_fat.c create mode 100644 source/usbloader/wbfs_fat.h diff --git a/Makefile b/Makefile index 78e73c7b..d676a032 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ SOURCES := source source/libwiigui source/images source/fonts source/sounds \ source/libwbfs source/unzip source/language source/mload source/patches \ source/usbloader source/xml source/network source/settings source/prompts \ source/ramdisk source/wad source/banner source/cheats source/homebrewboot \ - source/themes + source/themes source/menu DATA := data INCLUDES := source @@ -35,7 +35,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map,--section-start,.init=0x80B00 #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmad -lmxml -ljpeg +LIBS := -lfat -lpngu -lpng -lm -lz -lwiiuse -lbte -lasnd -logc -lfreetype -ltremor -lmad -lmxml -ljpeg #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing # include and lib @@ -191,6 +191,12 @@ language: $(wildcard $(PROJECTDIR)/Languages/*.lang) %.bin.o : %.bin @echo $(notdir $<) $(bin2o) +%.tik.o : %.tik + @echo $(notdir $<) + $(bin2o) +%.tmd.o : %.tmd + @echo $(notdir $<) + $(bin2o) export PATH := $(PROJECTDIR)/gettext-bin:$(PATH) diff --git a/data/ehcmodule_fat.bin b/data/ehcmodule_fat.bin new file mode 100644 index 0000000000000000000000000000000000000000..82cdeb7c586e87d0756d9bb97b961e58a1cf4f67 GIT binary patch literal 59469 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 \ No newline at end of file + \ No newline at end of file diff --git a/source/banner/banner.c b/source/banner/banner.c index ffcea164..5ac1fbcd 100644 --- a/source/banner/banner.c +++ b/source/banner/banner.c @@ -112,7 +112,7 @@ s32 dump_banner(const u8* discid,const char * dest) WDVD_ClosePartition(); //fatInitDefault(); //SDCard_Init(); - WDVD_SetUSBMode(NULL); + WDVD_SetUSBMode(NULL, 0); FILE *fp = fopen(dest, "wb"); if(fp) { diff --git a/source/bannersound.cpp b/source/bannersound.cpp index c7782cc9..fe300992 100644 --- a/source/bannersound.cpp +++ b/source/bannersound.cpp @@ -129,7 +129,7 @@ const u8 *LoadBannerSound(const u8 *discid, u32 *size) return NULL; Disc_SetUSB(NULL); - wbfs_disc_t *disc = wbfs_open_disc(GetHddInfo(), (u8 *) discid); + wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) discid); if(!disc) { WindowPrompt(tr("Can't find disc"), 0, tr("OK")); @@ -150,7 +150,7 @@ const u8 *LoadBannerSound(const u8 *discid, u32 *size) } wd_close_disc(wdisc); - wbfs_close_disc(disc); + WBFS_CloseDisc(disc); const U8Entry *fst; diff --git a/source/fatmounter.c b/source/fatmounter.c index a4e0b104..fc9b4e2f 100644 --- a/source/fatmounter.c +++ b/source/fatmounter.c @@ -10,28 +10,79 @@ #include "usbloader/usbstorage.h" //these are the only stable and speed is good -#define CACHE 8 +#define CACHE 32 #define SECTORS 64 +#define MOUNT_NONE 0 +#define MOUNT_SD 1 +#define MOUNT_SDHC 2 + extern DISC_INTERFACE __io_sdhc; +extern sec_t _FAT_startSector; + +int fat_sd_mount = MOUNT_NONE; +sec_t fat_sd_sec = 0; // u32 + +int fat_usb_mount = 0; +sec_t fat_usb_sec = 0; + +int fat_wbfs_mount = 0; +sec_t fat_wbfs_sec = 0; int USBDevice_Init() { //closing all open Files write back the cache and then shutdown em! fatUnmount("USB:/"); //right now mounts first FAT-partition - if (fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) { - //try first mount with cIOS - return 1; - } else if (fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) { + + //try first mount with cIOS + if (!fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) { //try now mount with libogc - return 1; + if (!fatMount("USB", &__io_usbstorage, 0, CACHE, SECTORS)) { + return -1; + } } - return -1; + + fat_usb_mount = 1; + fat_usb_sec = _FAT_startSector; + return 0; } void USBDevice_deInit() { //closing all open Files write back the cache and then shutdown em! fatUnmount("USB:/"); + + fat_usb_mount = 0; + fat_usb_sec = 0; +} + +int WBFSDevice_Init(u32 sector) { + //closing all open Files write back the cache and then shutdown em! + fatUnmount("WBFS:/"); + //right now mounts first FAT-partition + + //try first mount with cIOS + if (!fatMount("WBFS", &__io_wiiums, 0, CACHE, SECTORS)) { + //try now mount with libogc + if (!fatMount("WBFS", &__io_usbstorage, 0, CACHE, SECTORS)) { + return -1; + } + } + + fat_wbfs_mount = 1; + fat_wbfs_sec = _FAT_startSector; + if (sector && fat_wbfs_sec != sector) { + // This is an error situation...actually, but is ignored in Config loader also + // Should ask Oggzee about it... + } + return 0; +} + +void WBFSDevice_deInit() { + //closing all open Files write back the cache and then shutdown em! + fatUnmount("WBFS:/"); + + fat_wbfs_mount = 0; + fat_wbfs_sec = 0; } int isInserted(const char *path) { @@ -40,18 +91,28 @@ int isInserted(const char *path) { return __io_sdhc.isInserted() || __io_wiisd.isInserted(); } + int SDCard_Init() { //closing all open Files write back the cache and then shutdown em! fatUnmount("SD:/"); //right now mounts first FAT-partition - if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS)) + if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS)) { + fat_sd_mount = MOUNT_SD; + fat_sd_sec = _FAT_startSector; return 1; - else if (fatMount("SD", &__io_sdhc, 0, CACHE, SDHC_SECTOR_SIZE)) + } + else if (fatMount("SD", &__io_sdhc, 0, CACHE, SDHC_SECTOR_SIZE)) { + fat_sd_mount = MOUNT_SDHC; + fat_sd_sec = _FAT_startSector; return 1; + } return -1; } void SDCard_deInit() { //closing all open Files write back the cache and then shutdown em! fatUnmount("SD:/"); + + fat_sd_mount = MOUNT_NONE; + fat_sd_sec = 0; } diff --git a/source/fatmounter.h b/source/fatmounter.h index b53c52a8..ec82bab3 100644 --- a/source/fatmounter.h +++ b/source/fatmounter.h @@ -5,8 +5,17 @@ extern "C" { #endif + extern int fat_sd_mount; + extern sec_t fat_sd_sec; + extern int fat_usb_mount; + extern sec_t fat_usb_sec; + extern int fat_wbfs_mount; + extern sec_t fat_wbfs_sec; + int USBDevice_Init(); void USBDevice_deInit(); + int WBFSDevice_Init(u32 sector); + void WBFSDevice_deInit(); int isInserted(const char *path); int SDCard_Init(); void SDCard_deInit(); diff --git a/source/homebrewboot/HomebrewBrowse.cpp b/source/homebrewboot/HomebrewBrowse.cpp index 66a13b97..74de3c9c 100644 --- a/source/homebrewboot/HomebrewBrowse.cpp +++ b/source/homebrewboot/HomebrewBrowse.cpp @@ -26,6 +26,7 @@ #include "settings/cfg.h" #include "unzip/unzip.h" #include "unzip/miniunz.h" +#include "usbloader/utils.h" /*** Extern functions ***/ extern void ResumeGui(); @@ -785,10 +786,10 @@ int MenuHomebrewBrowse() { char filesizetxt[50]; char temp[50]; - if (infilesize < MBSIZE) - snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fKB"), infilesize/KBSIZE); + if (infilesize < MB_SIZE) + snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fKB"), infilesize/KB_SIZE); else - snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fMB"), infilesize/MBSIZE); + snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fMB"), infilesize/MB_SIZE); snprintf(temp, sizeof(temp), tr("Load file from: %s ?"), GetIncommingIP()); diff --git a/source/libwbfs/libwbfs.c b/source/libwbfs/libwbfs.c index fa3be703..1f922c69 100644 --- a/source/libwbfs/libwbfs.c +++ b/source/libwbfs/libwbfs.c @@ -637,3 +637,57 @@ error: return tot * (((p->wbfs_sec_sz*1.0) / p->hd_sec_sz) * 512); } + +u32 wbfs_size_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc, + void *callback_data,partition_selector_t sel, + u32 *comp_size, u32 *real_size) +{ + int i; + u32 tot = 0, last = 0; + u32 wii_sec_per_wbfs_sect = 1<<(p->wbfs_sec_sz_s-p->wii_sec_sz_s); + wiidisc_t *d = 0; + u8 *used = 0; + used = wbfs_malloc(p->n_wii_sec_per_disc); + if(!used) + ERROR("unable to alloc memory"); + d = wd_open_disc(read_src_wii_disc,callback_data); + if(!d) + ERROR("unable to open wii disc"); + wd_build_disc_usage(d,sel,used); + wd_close_disc(d); + d = 0; + + // count total number to write for spinner + for(i=0; in_wbfs_sec_per_disc;i++) { + if(block_used(used,i,wii_sec_per_wbfs_sect)) { + tot += wii_sec_per_wbfs_sect; + last = i * wii_sec_per_wbfs_sect; + } + } + +error: + if(d) + wd_close_disc(d); + if(used) + wbfs_free(used); + + *comp_size = tot; + *real_size = last; + + return 0; +} + +// trim the file-system to its minimum size +u32 wbfs_trim(wbfs_t*p) +{ + u32 maxbl; + load_freeblocks(p); + maxbl = alloc_block(p); + p->n_hd_sec = maxbl<<(p->wbfs_sec_sz_s-p->hd_sec_sz_s); + p->head->n_hd_sec = wbfs_htonl(p->n_hd_sec); + // make all block full + memset(p->freeblks,0,p->n_wbfs_sec/8); + wbfs_sync(p); + // os layer will truncate the file. + return maxbl; +} diff --git a/source/libwbfs/libwbfs.h b/source/libwbfs/libwbfs.h index 45ec33c7..127bac4e 100644 --- a/source/libwbfs/libwbfs.h +++ b/source/libwbfs/libwbfs.h @@ -219,6 +219,16 @@ float wbfs_estimate_disc( void *callback_data, partition_selector_t sel); +// compressed and real size +u32 wbfs_size_disc(wbfs_t*p,read_wiidisc_callback_t read_src_wii_disc, + void *callback_data,partition_selector_t sel, + u32 *comp_size, u32 *real_size); + +/*! trim the file-system to its minimum size + This allows to use wbfs as a wiidisc container + */ +u32 wbfs_trim(wbfs_t*p); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/source/libwiigui/gui_gamecarousel.cpp b/source/libwiigui/gui_gamecarousel.cpp index 37451248..c32c6107 100644 --- a/source/libwiigui/gui_gamecarousel.cpp +++ b/source/libwiigui/gui_gamecarousel.cpp @@ -115,7 +115,6 @@ noCover(nocover_png) gameIndex = new int[pagesize]; game = new GuiButton * [pagesize]; - titleTT = new GuiTooltip * [pagesize]; coverImg = new GuiImageAsync * [pagesize]; for(int i=0; i < pagesize; i++) @@ -125,11 +124,6 @@ noCover(nocover_png) //------------------------ gameIndex[i] = GetGameIndex(i, listOffset, gameCnt); - //------------------------ - // Tooltip - //------------------------ - titleTT[i] = new GuiTooltip(get_title(&gameList[gameIndex[i]]), THEME.tooltipAlpha); - //------------------------ // Image //------------------------ @@ -152,20 +146,6 @@ noCover(nocover_png) game[i]->SetSoundClick(btnSoundClick); game[i]->SetClickable(true); game[i]->SetEffect(EFFECT_GOROUND, IN_SPEED, 90-(pagesize-2*i-1)*DEG_OFFSET/2, RADIUS, 180, 1, 0, RADIUS); - switch((i*3)/pagesize) - { - case 0: - game[i]->SetToolTip(titleTT[i], 122/2, -244/4, ALIGN_LEFT, ALIGN_MIDDLE); - break; - case 1: - game[i]->SetToolTip(titleTT[i], 0, -244/4, ALIGN_CENTRE, ALIGN_MIDDLE); - break; - case 2: - game[i]->SetToolTip(titleTT[i], -122/2, -244/4, ALIGN_RIGHT, ALIGN_MIDDLE); - break; - default: - break; - } } } @@ -193,7 +173,6 @@ GuiGameCarousel::~GuiGameCarousel() for(int i=0; i 0) // rotate right { GuiButton *tmpButton; - GuiTooltip *tmpTT; listOffset = OFFSETLIMIT(listOffset - 1, gameCnt); // set the new listOffset // Save right Button + TollTip and destroy right Image + Image-Data delete coverImg[pagesize-1]; coverImg[pagesize-1] = NULL;game[pagesize-1]->SetImage(NULL); tmpButton = game[pagesize-1]; - tmpTT = titleTT[pagesize-1]; // Move all Page-Entries one step right for (int i=pagesize-1; i>=1; i--) { - titleTT[i] = titleTT[i-1]; coverImg[i] = coverImg[i-1]; game[i] = game[i-1]; gameIndex[i] = gameIndex[i-1]; } // set saved Button & gameIndex to right gameIndex[0] = listOffset; - titleTT[0] = tmpTT; - titleTT[0] ->SetText(get_title(&gameList[gameIndex[0]])); coverImg[0] = new GuiImageAsync(GameCarouselLoadCoverImage, &gameList[gameIndex[0]], sizeof(struct discHdr), &noCover); coverImg[0] ->SetWidescreen(CFG.widescreen); @@ -439,38 +413,19 @@ void GuiGameCarousel::Update(GuiTrigger * t) game[i]->ResetState(); game[i]->SetEffect(EFFECT_GOROUND, speed, DEG_OFFSET, RADIUS, 270-(pagesize-2*i+1)*DEG_OFFSET/2, 1, 0, RADIUS); game[i]->UpdateEffects(); // rotate one step for liquid scrolling - - // Set Tooltip-Position - switch((i*3)/pagesize) - { - case 0: - game[i]->SetToolTip(titleTT[i], 122/4, -244/4, ALIGN_LEFT, ALIGN_MIDDLE); - break; - case 1: - game[i]->SetToolTip(titleTT[i], 0, -244/4, ALIGN_CENTRE, ALIGN_MIDDLE); - break; - case 2: - game[i]->SetToolTip(titleTT[i], -122/4, -244/4, ALIGN_RIGHT, ALIGN_MIDDLE); - break; - default: - break; - } } } else if(speed < 0) // rotate left { GuiButton *tmpButton; - GuiTooltip *tmpTT; listOffset = OFFSETLIMIT(listOffset + 1, gameCnt); // set the new listOffset // Save left Button + TollTip and destroy left Image + Image-Data delete coverImg[0]; coverImg[0] = NULL;game[0]->SetImage(NULL); tmpButton = game[0]; - tmpTT = titleTT[0]; // Move all Page-Entries one step left for (int i=0; i<(pagesize-1); i++) { - titleTT[i] = titleTT[i+1]; coverImg[i] = coverImg[i+1]; game[i] = game[i+1]; gameIndex[i] = gameIndex[i+1]; @@ -478,8 +433,6 @@ void GuiGameCarousel::Update(GuiTrigger * t) // set saved Button & gameIndex to right int ii = pagesize-1; gameIndex[ii] = OFFSETLIMIT(listOffset + ii, gameCnt); - titleTT[ii] = tmpTT; - titleTT[ii] ->SetText(get_title(&gameList[gameIndex[ii]])); coverImg[ii] = new GuiImageAsync(GameCarouselLoadCoverImage, &gameList[gameIndex[ii]], sizeof(struct discHdr), &noCover); coverImg[ii] ->SetWidescreen(CFG.widescreen); @@ -493,22 +446,6 @@ void GuiGameCarousel::Update(GuiTrigger * t) game[i]->ResetState(); game[i]->SetEffect(EFFECT_GOROUND, speed, DEG_OFFSET, RADIUS, 270-(pagesize-2*i-3)*DEG_OFFSET/2, 1, 0, RADIUS); game[i]->UpdateEffects(); // rotate one step for liquid scrolling - - // Set Tooltip-Position - switch((i*3)/pagesize) - { - case 0: - game[i]->SetToolTip(titleTT[i], 122/4, -244/4, ALIGN_LEFT, ALIGN_MIDDLE); - break; - case 1: - game[i]->SetToolTip(titleTT[i], 0, -244/4, ALIGN_CENTRE, ALIGN_MIDDLE); - break; - case 2: - game[i]->SetToolTip(titleTT[i], -122/4, -244/4, ALIGN_RIGHT, ALIGN_MIDDLE); - break; - default: - break; - } } } diff --git a/source/libwiigui/gui_gamecarousel.h b/source/libwiigui/gui_gamecarousel.h index a272b283..e4906893 100644 --- a/source/libwiigui/gui_gamecarousel.h +++ b/source/libwiigui/gui_gamecarousel.h @@ -33,7 +33,6 @@ class GuiGameCarousel : public GuiElement int * gameIndex; GuiButton ** game; - GuiTooltip ** titleTT; GuiImageAsync ** coverImg; GuiText * gamename; diff --git a/source/main.cpp b/source/main.cpp index d444f204..6d51c940 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -36,6 +36,8 @@ #include "fat.h" #include "gecko.h" #include "svnrev.h" +#include "usbloader/partition.h" +#include "usbloader/usbstorage.h" extern bool geckoinit; @@ -47,6 +49,7 @@ extern bool geckoinit; FreeTypeGX *fontSystem=0; FreeTypeGX *fontClock=0; +PartList partitions; static void BootUpProblems() { @@ -152,27 +155,24 @@ main(int argc, char *argv[]) { USBDevice_Init();// seems enough to wake up some HDDs if they are in sleep mode when the loader starts (tested with WD MyPassport Essential 2.5") - ret = IOS_ReloadIOS(249); - + ret = IOS_ReloadIOS(222); + if (ret < 0) { - ret = IOS_ReloadIOS(222); - SDCard_Init(); - load_ehc_module(); - SDCard_deInit(); - if(ret <0) { + ret = IOS_ReloadIOS(249); + if(ret < 0) { printf("\n\tERROR: cIOS could not be loaded!\n"); sleep(5); SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0); } } + SDCard_Init(); + load_ehc_module(); + SDCard_deInit(); ret = WBFS_Init(WBFS_DEVICE_USB); if (ret < 0) { - ret = IOS_ReloadIOS(222); - SDCard_Init(); - load_ehc_module(); - SDCard_deInit(); + ret = IOS_ReloadIOS(249); if(ret < 0) { InitVideo(); // Initialise video Menu_Render(); @@ -209,10 +209,11 @@ main(int argc, char *argv[]) { CFG_Load(); gprintf("\n\tbootDevice = %s",bootDevice); - /* Load Custom IOS */ + /* Load Custom IOS */ if (Settings.cios == ios222 && IOS_GetVersion() != 222) { SDCard_deInit();// unmount SD for reloading IOS USBDevice_deInit();// unmount USB for reloading IOS + USBStorage_Deinit(); ret = IOS_ReloadIOS(222); SDCard_Init(); load_ehc_module(); @@ -223,9 +224,11 @@ main(int argc, char *argv[]) { } SDCard_Init(); // now mount SD:/ USBDevice_Init(); // and mount USB:/ + WBFS_Init(WBFS_DEVICE_USB); } else if (Settings.cios == ios249 && IOS_GetVersion() != 249) { SDCard_deInit();// unmount SD for reloading IOS USBDevice_deInit();// unmount USB for reloading IOS + USBStorage_Deinit(); ret = IOS_ReloadIOS(249); if (ret < 0) { Settings.cios = ios222; @@ -235,8 +238,11 @@ main(int argc, char *argv[]) { } SDCard_Init(); // now mount SD:/ USBDevice_Init(); // and mount USB:/ + WBFS_Init(WBFS_DEVICE_USB); } +// Partition_GetList(&partitions); + if (ret < 0) { printf("ERROR: cIOS could not be loaded!"); sleep(5); diff --git a/source/menu.cpp b/source/menu.cpp index 4e344189..847a8b6a 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -8,53 +8,26 @@ * Menu flow routines - handles all menu logic ***************************************************************************/ #include -#include -#include //CLOCK -#include #include "libwiigui/gui.h" -#include "libwiigui/gui_gamegrid.h" -#include "libwiigui/gui_gamecarousel.h" -#include "libwiigui/gui_gamebrowser.h" -#include "libwiigui/gui_searchbar.h" -#include "libwiigui/gui_customoptionbrowser.h" -#include "libwiigui/gui_image_async.h" -#include "usbloader/usbstorage.h" -#include "usbloader/wbfs.h" -#include "usbloader/disc.h" -#include "usbloader/getentries.h" -#include "language/gettext.h" -#include "settings/Settings.h" -#include "homebrewboot/HomebrewBrowse.h" #include "homebrewboot/BootHomebrew.h" -#include "prompts/PromptWindows.h" -#include "prompts/filebrowser.h" +#include "homebrewboot/HomebrewBrowse.h" #include "prompts/ProgressWindow.h" -#include "prompts/TitleBrowser.h" -#include "prompts/gameinfo.h" -#include "prompts/DiscBrowser.h" +#include "menu/menus.h" #include "mload/mload.h" -#include "patches/patchcode.h" #include "network/networkops.h" -#include "cheats/cheatmenu.h" -#include "menu.h" +#include "patches/patchcode.h" +#include "settings/Settings.h" +#include "settings/cfg.h" +#include "themes/Theme_Downloader.h" +#include "usbloader/disc.h" +#include "wad/title.h" +#include "xml/xml.h" #include "audio.h" -#include "wad/wad.h" -#include "input.h" -#include "filelist.h" +#include "gecko.h" +#include "menu.h" #include "sys.h" #include "wpad.h" -#include "listfiles.h" -#include "fatmounter.h" -#include "xml/xml.h" -#include "wad/title.h" -#include "gecko.h" - -#include "usbloader/wdvd.h" - -#include "themes/Theme_Downloader.h" - -#define MAX_CHARACTERS 38 /*** Variables that are also used extern ***/ GuiWindow * mainWindow = NULL; @@ -64,35 +37,33 @@ GuiImageData * background = NULL; GuiSound * bgMusic = NULL; GuiSound *btnClick2 = NULL; +struct discHdr *dvdheader = NULL; float gamesize; int currentMenu; -int idiotFlag=-1; -char idiotChar[50]; u8 mountMethod=0; -struct discHdr *dvdheader = NULL; +char game_partition[6]; +bool load_from_fat; + +/*** Variables used only in the menus ***/ +GuiText * GameIDTxt = NULL; +GuiText * GameRegionTxt = NULL; +GuiImage * coverImg = NULL; +GuiImageData * cover = NULL; +bool altdoldefault = true; -/*** Variables used only in menu.cpp ***/ -static GuiImage * coverImg = NULL; -static GuiImageData * cover = NULL; -static GuiText * GameIDTxt = NULL; -static GuiText * GameRegionTxt = NULL; static lwp_t guithread = LWP_THREAD_NULL; static bool guiHalt = true; static int ExitRequested = 0; -static char gameregion[7]; -static bool altdoldefault = true; /*** Extern variables ***/ +extern struct discHdr * gameList; extern FreeTypeGX *fontClock; extern u8 shutdown; extern u8 reset; -extern int cntMissFiles; extern s32 gameSelected, gameStart; -extern const u8 data1; extern u8 boothomebrew; -extern bool updateavailable; /**************************************************************************** * ResumeGui @@ -215,44 +186,6 @@ void ExitGUIThreads() { LWP_JoinThread(guithread, NULL); guithread = LWP_THREAD_NULL; } -void rockout(int f = 0) { - - - HaltGui(); - int num=(f==2?-1:gameSelected); - - char imgPath[100]; -#ifdef HW_RVL - if ((!(strcasestr(get_title(&gameList[num]),"guitar")|| - strcasestr(get_title(&gameList[num]),"band")|| - strcasestr(get_title(&gameList[num]),"rock")|| - f==1))||mountMethod) { - for (int i = 0; i < 4; i++) - delete pointer[i]; - snprintf(imgPath, sizeof(imgPath), "%splayer1_point.png", CFG.theme_path); - pointer[0] = new GuiImageData(imgPath, player1_point_png); - snprintf(imgPath, sizeof(imgPath), "%splayer2_point.png", CFG.theme_path); - pointer[1] = new GuiImageData(imgPath, player2_point_png); - snprintf(imgPath, sizeof(imgPath), "%splayer3_point.png", CFG.theme_path); - pointer[2] = new GuiImageData(imgPath, player3_point_png); - snprintf(imgPath, sizeof(imgPath), "%splayer4_point.png", CFG.theme_path); - pointer[3] = new GuiImageData(imgPath, player4_point_png); - } else { - - for (int i = 0; i < 4; i++) - delete pointer[i]; - snprintf(imgPath, sizeof(imgPath), "%srplayer1_point.png", CFG.theme_path); - pointer[0] = new GuiImageData(imgPath, rplayer1_point_png); - snprintf(imgPath, sizeof(imgPath), "%srplayer2_point.png", CFG.theme_path); - pointer[1] = new GuiImageData(imgPath, rplayer2_point_png); - snprintf(imgPath, sizeof(imgPath), "%srplayer3_point.png", CFG.theme_path); - pointer[2] = new GuiImageData(imgPath, rplayer3_point_png); - snprintf(imgPath, sizeof(imgPath), "%srplayer4_point.png", CFG.theme_path); - pointer[3] = new GuiImageData(imgPath, rplayer4_point_png); - } -#endif - ResumeGui(); -} /**************************************************************************** * LoadCoverImage @@ -305,1830 +238,6 @@ GuiImageData *LoadCoverImage(struct discHdr *header, bool Prefere3D, bool noCove } return Cover; } -/**************************************************************************** - * MenuDiscList - ***************************************************************************/ -GuiButton *Toolbar[8]; -void DiscListWinUpdateCallback(void * e) -{ - GuiWindow *w = (GuiWindow *)e; - for(int i=0; i<8; ++i) - { - if(Toolbar[i]->GetState() == STATE_SELECTED) - { - w->Remove(Toolbar[i]); - w->Append(Toolbar[i]); // draw the selected Icon allways on top - break; - } - } -} - - -int MenuDiscList() { - - gprintf("\nMenuDiscList()");//testing out the gecko stuff. this shouldn't break anything, but we'll see - int startat = 0; - int offset = 0; - int datag = 0; - int datagB =0; - int dataed = -1; - int cosa=0,sina=0; - int selectImg1 = 0; - char ID[4]; - char IDfull[7]; - u32 covert = 0; - char imgPath[100]; - if (!dvdheader) - dvdheader = new struct discHdr; - u8 mountMethodOLD =0; - - WDVD_GetCoverStatus(&covert); - u32 covertOld=covert; - - wchar_t searchChar; - //SCREENSAVER - //WPad_SetIdleTime(300); //needs the time in seconds - int check = 0; //to skip the first cycle when wiimote isn't completely connected - - datagB=0; - int menu = MENU_NONE, dataef=0; - __Menu_GetEntries(); - - f32 freespace, used, size = 0.0; - u32 nolist; - char text[MAX_CHARACTERS + 4]; - int choice = 0, selectedold = 100; - s32 ret; - - //CLOCK - struct tm * timeinfo; - char theTime[80]=""; - time_t lastrawtime=0; - - if (mountMethod!=3) - WBFS_DiskSpace(&used, &freespace); - - if (!gameCnt) { //if there is no list of games to display - nolist = 1; - } - - - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - // because destroy GuiSound must wait while sound playing is finished, we use a global sound - if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); - // GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); - - snprintf(imgPath, sizeof(imgPath), "%sbutton_install.png", CFG.theme_path); - GuiImageData btnInstall(imgPath, button_install_png); - snprintf(imgPath, sizeof(imgPath), "%sbutton_install_over.png", CFG.theme_path); - GuiImageData btnInstallOver(imgPath, button_install_over_png); - - snprintf(imgPath, sizeof(imgPath), "%ssettings_button.png", CFG.theme_path); - GuiImageData btnSettings(imgPath, settings_button_png); - snprintf(imgPath, sizeof(imgPath), "%ssettings_button_over.png", CFG.theme_path); - GuiImageData btnSettingsOver(imgPath, settings_button_over_png); - GuiImageData dataID(&data1); - - snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff.png", CFG.theme_path); - GuiImageData btnpwroff(imgPath, wiimote_poweroff_png); - snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff_over.png", CFG.theme_path); - GuiImageData btnpwroffOver(imgPath, wiimote_poweroff_over_png); - snprintf(imgPath, sizeof(imgPath), "%smenu_button.png", CFG.theme_path); - GuiImageData btnhome(imgPath, menu_button_png); - snprintf(imgPath, sizeof(imgPath), "%smenu_button_over.png", CFG.theme_path); - GuiImageData btnhomeOver(imgPath, menu_button_over_png); - snprintf(imgPath, sizeof(imgPath), "%sSDcard_over.png", CFG.theme_path); - GuiImageData btnsdcardOver(imgPath, sdcard_over_png); - snprintf(imgPath, sizeof(imgPath), "%sSDcard.png", CFG.theme_path); - GuiImageData btnsdcard(imgPath, sdcard_png); - - - snprintf(imgPath, sizeof(imgPath), "%sfavIcon.png", CFG.theme_path); - GuiImageData imgfavIcon(imgPath, favIcon_png); - snprintf(imgPath, sizeof(imgPath), "%sfavIcon_gray.png", CFG.theme_path); - GuiImageData imgfavIcon_gray(imgPath, NULL); - snprintf(imgPath, sizeof(imgPath), "%ssearchIcon.png", CFG.theme_path); - GuiImageData imgsearchIcon(imgPath, searchIcon_png); - snprintf(imgPath, sizeof(imgPath), "%ssearchIcon_gray.png", CFG.theme_path); - GuiImageData imgsearchIcon_gray(imgPath, NULL); - snprintf(imgPath, sizeof(imgPath), "%sabcIcon.png", CFG.theme_path); - GuiImageData imgabcIcon(imgPath, abcIcon_png); - snprintf(imgPath, sizeof(imgPath), "%sabcIcon_gray.png", CFG.theme_path); - GuiImageData imgabcIcon_gray(imgPath, NULL); - snprintf(imgPath, sizeof(imgPath), "%srankIcon.png", CFG.theme_path); - GuiImageData imgrankIcon(imgPath, rankIcon_png); - snprintf(imgPath, sizeof(imgPath), "%srankIcon_gray.png", CFG.theme_path); - GuiImageData imgrankIcon_gray(imgPath, NULL); - snprintf(imgPath, sizeof(imgPath), "%splayCountIcon.png", CFG.theme_path); - GuiImageData imgplayCountIcon(imgPath, playCountIcon_png); - snprintf(imgPath, sizeof(imgPath), "%splayCountIcon_gray.png", CFG.theme_path); - GuiImageData imgplayCountIcon_gray(imgPath, NULL); - snprintf(imgPath, sizeof(imgPath), "%sarrangeGrid.png", CFG.theme_path); - GuiImageData imgarrangeGrid(imgPath, arrangeGrid_png); - snprintf(imgPath, sizeof(imgPath), "%sarrangeGrid_gray.png", CFG.theme_path); - GuiImageData imgarrangeGrid_gray(imgPath, NULL); - snprintf(imgPath, sizeof(imgPath), "%sarrangeList.png", CFG.theme_path); - GuiImageData imgarrangeList(imgPath, arrangeList_png); - snprintf(imgPath, sizeof(imgPath), "%sarrangeList_gray.png", CFG.theme_path); - GuiImageData imgarrangeList_gray(imgPath, NULL); - snprintf(imgPath, sizeof(imgPath), "%sarrangeCarousel.png", CFG.theme_path); - GuiImageData imgarrangeCarousel(imgPath, arrangeCarousel_png); - snprintf(imgPath, sizeof(imgPath), "%sarrangeCarousel_gray.png", CFG.theme_path); - GuiImageData imgarrangeCarousel_gray(imgPath, NULL); - snprintf(imgPath, sizeof(imgPath), "%sdvd.png", CFG.theme_path); - GuiImageData imgdvd(imgPath, dvd_png); - snprintf(imgPath, sizeof(imgPath), "%sdvd_gray.png", CFG.theme_path); - GuiImageData imgdvd_gray(imgPath, NULL); - - snprintf(imgPath, sizeof(imgPath), "%sbrowser.png", CFG.theme_path); - GuiImageData homebrewImgData(imgPath, browser_png); - snprintf(imgPath, sizeof(imgPath), "%sbrowser_over.png", CFG.theme_path); - GuiImageData homebrewImgDataOver(imgPath, browser_over_png); - - - GuiTrigger trigA; - trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); - GuiTrigger trigHome; - trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0); - GuiTrigger trig2; - trig2.SetButtonOnlyTrigger(-1, WPAD_BUTTON_2 | WPAD_CLASSIC_BUTTON_X, 0); - GuiTrigger trig1; - trig1.SetButtonOnlyTrigger(-1, WPAD_BUTTON_1 | WPAD_CLASSIC_BUTTON_Y, 0); - - - char spaceinfo[30]; - if (!strcmp(Settings.db_language,"JA")) { - // needs to be "total...used" for Japanese - sprintf(spaceinfo,(mountMethod!=3?"%.2fGB %s %.2fGB %s":" "),(freespace+used),tr("of"),freespace,tr("free")); - } else { - sprintf(spaceinfo,(mountMethod!=3?"%.2fGB %s %.2fGB %s":" "),freespace,tr("of"),(freespace+used),tr("free")); - } - GuiText usedSpaceTxt(spaceinfo, 18, THEME.info); - usedSpaceTxt.SetAlignment(THEME.hddinfo_align, ALIGN_TOP); - usedSpaceTxt.SetPosition(THEME.hddinfo_x, THEME.hddinfo_y); - - char GamesCnt[15]; - sprintf(GamesCnt,"%s: %i",(mountMethod!=3?tr("Games"):tr("Channels")), gameCnt); - GuiText gamecntTxt(GamesCnt, 18, THEME.info); - - GuiButton gamecntBtn(100,18); - gamecntBtn.SetAlignment(THEME.gamecount_align, ALIGN_TOP); - gamecntBtn.SetPosition(THEME.gamecount_x,THEME.gamecount_y); - gamecntBtn.SetLabel(&gamecntTxt); - gamecntBtn.SetEffectGrow(); - gamecntBtn.SetTrigger(&trigA); - - - - GuiTooltip installBtnTT(tr("Install a game")); - if (Settings.wsprompt == yes) - installBtnTT.SetWidescreen(CFG.widescreen); - installBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage installBtnImg(&btnInstall); - GuiImage installBtnImgOver(&btnInstallOver); - installBtnImg.SetWidescreen(CFG.widescreen); - installBtnImgOver.SetWidescreen(CFG.widescreen); - - GuiButton installBtn(&installBtnImg, &installBtnImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.install_x, THEME.install_y, &trigA, &btnSoundOver, btnClick2, 1, &installBtnTT,24,-30, 0,5); - - - GuiTooltip settingsBtnTT(tr("Settings")); - if (Settings.wsprompt == yes) - settingsBtnTT.SetWidescreen(CFG.widescreen); - settingsBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage settingsBtnImg(&btnSettings); - settingsBtnImg.SetWidescreen(CFG.widescreen); - GuiImage settingsBtnImgOver(&btnSettingsOver); - settingsBtnImgOver.SetWidescreen(CFG.widescreen); - GuiButton settingsBtn(&settingsBtnImg,&settingsBtnImgOver, 0, 3, THEME.setting_x, THEME.setting_y, &trigA, &btnSoundOver, btnClick2,1,&settingsBtnTT,65,-30,0,5); - - GuiTooltip homeBtnTT(tr("Back to HBC or Wii Menu")); - if (Settings.wsprompt == yes) - homeBtnTT.SetWidescreen(CFG.widescreen); - settingsBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage homeBtnImg(&btnhome); - homeBtnImg.SetWidescreen(CFG.widescreen); - GuiImage homeBtnImgOver(&btnhomeOver); - homeBtnImgOver.SetWidescreen(CFG.widescreen); - GuiButton homeBtn(&homeBtnImg,&homeBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, btnClick2,1,&homeBtnTT,15,-30,1,5); - homeBtn.RemoveSoundClick(); - homeBtn.SetTrigger(&trigHome); - - GuiTooltip poweroffBtnTT(tr("Power off the Wii")); - if (Settings.wsprompt == yes) - poweroffBtnTT.SetWidescreen(CFG.widescreen); - poweroffBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage poweroffBtnImg(&btnpwroff); - GuiImage poweroffBtnImgOver(&btnpwroffOver); - poweroffBtnImg.SetWidescreen(CFG.widescreen); - poweroffBtnImgOver.SetWidescreen(CFG.widescreen); - GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, btnClick2,1,&poweroffBtnTT,-10,-30,1,5); - - - GuiTooltip sdcardBtnTT(tr("Reload SD")); - if (Settings.wsprompt == yes) - sdcardBtnTT.SetWidescreen(CFG.widescreen); - sdcardBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage sdcardImg(&btnsdcard); - GuiImage sdcardImgOver(&btnsdcardOver); - sdcardImg.SetWidescreen(CFG.widescreen); - sdcardImgOver.SetWidescreen(CFG.widescreen); - GuiButton sdcardBtn(&sdcardImg,&sdcardImgOver, 0, 3, THEME.sdcard_x, THEME.sdcard_y, &trigA, &btnSoundOver, btnClick2,1,&sdcardBtnTT,15,-30,0,5); - - GuiButton gameInfo(0,0); - gameInfo.SetTrigger(&trig2); - gameInfo.SetSoundClick(btnClick2); - - - GuiImage wiiBtnImg(&dataID); - wiiBtnImg.SetWidescreen(CFG.widescreen); - GuiButton wiiBtn(&wiiBtnImg,&wiiBtnImg, 0, 4, 0, -10, &trigA, &btnSoundOver, btnClick2,0); - - GuiTooltip favoriteBtnTT(tr("Display favorites")); - if (Settings.wsprompt == yes) - favoriteBtnTT.SetWidescreen(CFG.widescreen); - favoriteBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage favoriteBtnImg(&imgfavIcon); - favoriteBtnImg.SetWidescreen(CFG.widescreen); -// GuiImage favoriteBtnImg_g(favoriteBtnImg);favoriteBtnImg_g.SetGrayscale(); - GuiImage favoriteBtnImg_g(&imgfavIcon_gray); - if(favoriteBtnImg_g.GetImage() == NULL) { favoriteBtnImg_g = favoriteBtnImg; favoriteBtnImg_g.SetGrayscale();} - favoriteBtnImg_g.SetWidescreen(CFG.widescreen); - GuiButton favoriteBtn(&favoriteBtnImg_g,&favoriteBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_favorite_x, THEME.gamelist_favorite_y, &trigA, &btnSoundOver, btnClick2,1, &favoriteBtnTT, -15, 52, 0, 3); - favoriteBtn.SetAlpha(180); - - GuiTooltip searchBtnTT(tr("Set Search-Filter")); - if (Settings.wsprompt == yes) - searchBtnTT.SetWidescreen(CFG.widescreen); - searchBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage searchBtnImg(&imgsearchIcon); - searchBtnImg.SetWidescreen(CFG.widescreen); -// GuiImage searchBtnImg_g(searchBtnImg); searchBtnImg_g.SetGrayscale(); - GuiImage searchBtnImg_g(&imgsearchIcon_gray); - if(searchBtnImg_g.GetImage() == NULL) { searchBtnImg_g = searchBtnImg; searchBtnImg_g.SetGrayscale();} - searchBtnImg_g.SetWidescreen(CFG.widescreen); - GuiButton searchBtn(&searchBtnImg_g,&searchBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_search_x, THEME.gamelist_search_y, &trigA, &btnSoundOver, btnClick2,1, &searchBtnTT, -15, 52, 0, 3); - searchBtn.SetAlpha(180); - - GuiTooltip abcBtnTT(Settings.fave ? tr("Sort by rank") : tr("Sort alphabetically")); - if (Settings.wsprompt == yes) - abcBtnTT.SetWidescreen(CFG.widescreen); - abcBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage abcBtnImg(Settings.fave ? &imgrankIcon : &imgabcIcon); - abcBtnImg.SetWidescreen(CFG.widescreen); -// GuiImage abcBtnImg_g(abcBtnImg); abcBtnImg_g.SetGrayscale(); - GuiImage abcBtnImg_g(Settings.fave ? &imgrankIcon_gray : &imgabcIcon_gray); - if(abcBtnImg_g.GetImage() == NULL) { abcBtnImg_g = abcBtnImg; abcBtnImg_g.SetGrayscale();} - abcBtnImg_g.SetWidescreen(CFG.widescreen); - GuiButton abcBtn(&abcBtnImg_g,&abcBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_abc_x, THEME.gamelist_abc_y, &trigA, &btnSoundOver, btnClick2,1,&abcBtnTT, -15, 52, 0, 3); - abcBtn.SetAlpha(180); - - GuiTooltip countBtnTT(tr("Sort order by most played")); - if (Settings.wsprompt == yes) - countBtnTT.SetWidescreen(CFG.widescreen); - countBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage countBtnImg(&imgplayCountIcon); - countBtnImg.SetWidescreen(CFG.widescreen); -// GuiImage countBtnImg_g(countBtnImg); countBtnImg_g.SetGrayscale(); - GuiImage countBtnImg_g(&imgplayCountIcon_gray); - if(countBtnImg_g.GetImage() == NULL) { countBtnImg_g = countBtnImg; countBtnImg_g.SetGrayscale();} - countBtnImg_g.SetWidescreen(CFG.widescreen); - GuiButton countBtn(&countBtnImg_g,&countBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_count_x, THEME.gamelist_count_y, &trigA, &btnSoundOver, btnClick2,1, &countBtnTT, -15, 52, 0, 3); - countBtn.SetAlpha(180); - - GuiTooltip listBtnTT(tr("Display as a list")); - if (Settings.wsprompt == yes) - listBtnTT.SetWidescreen(CFG.widescreen); - listBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage listBtnImg(&imgarrangeList); - listBtnImg.SetWidescreen(CFG.widescreen); -// GuiImage listBtnImg_g(listBtnImg); listBtnImg_g.SetGrayscale(); - GuiImage listBtnImg_g(&imgarrangeList_gray); - if(listBtnImg_g.GetImage() == NULL) { listBtnImg_g = listBtnImg; listBtnImg_g.SetGrayscale();} - listBtnImg_g.SetWidescreen(CFG.widescreen); - GuiButton listBtn(&listBtnImg_g,&listBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_list_x, THEME.gamelist_list_y, &trigA, &btnSoundOver, btnClick2,1, &listBtnTT, 15, 52, 1, 3); - listBtn.SetAlpha(180); - - GuiTooltip gridBtnTT(tr("Display as a grid")); - if (Settings.wsprompt == yes) - gridBtnTT.SetWidescreen(CFG.widescreen); - gridBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage gridBtnImg(&imgarrangeGrid); - gridBtnImg.SetWidescreen(CFG.widescreen); -// GuiImage gridBtnImg_g(gridBtnImg); gridBtnImg_g.SetGrayscale(); - GuiImage gridBtnImg_g(&imgarrangeGrid_gray); - if(gridBtnImg_g.GetImage() == NULL) { gridBtnImg_g = gridBtnImg; gridBtnImg_g.SetGrayscale();} - gridBtnImg_g.SetWidescreen(CFG.widescreen); - GuiButton gridBtn(&gridBtnImg_g,&gridBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_grid_x, THEME.gamelist_grid_y, &trigA, &btnSoundOver, btnClick2,1, &gridBtnTT, 15, 52, 1, 3); - gridBtn.SetAlpha(180); - - GuiTooltip carouselBtnTT(tr("Display as a carousel")); - if (Settings.wsprompt == yes) - carouselBtnTT.SetWidescreen(CFG.widescreen); - carouselBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage carouselBtnImg(&imgarrangeCarousel); - carouselBtnImg.SetWidescreen(CFG.widescreen); -// GuiImage carouselBtnImg_g(carouselBtnImg); carouselBtnImg_g.SetGrayscale(); - GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray); - if(carouselBtnImg_g.GetImage() == NULL) { carouselBtnImg_g = carouselBtnImg; carouselBtnImg_g.SetGrayscale();} - carouselBtnImg_g.SetWidescreen(CFG.widescreen); - GuiButton carouselBtn(&carouselBtnImg_g,&carouselBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_carousel_x, THEME.gamelist_carousel_y, &trigA, &btnSoundOver, btnClick2,1, &carouselBtnTT, 15, 52, 1, 3); - carouselBtn.SetAlpha(180); - - GuiTooltip dvdBtnTT(tr("Mount DVD drive")); - if (Settings.wsprompt == yes) - dvdBtnTT.SetWidescreen(CFG.widescreen); - dvdBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage dvdBtnImg(&imgdvd); - dvdBtnImg.SetWidescreen(CFG.widescreen); - GuiImage dvdBtnImg_g(dvdBtnImg); //dvdBtnImg_g.SetGrayscale(); -// GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray); - dvdBtnImg_g.SetWidescreen(CFG.widescreen); - GuiButton dvdBtn(&dvdBtnImg_g,&dvdBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_dvd_x, THEME.gamelist_dvd_y, &trigA, &btnSoundOver, btnClick2,1, &dvdBtnTT, 15, 52, 1, 3); - dvdBtn.SetAlpha(180); - - GuiTooltip homebrewBtnTT(tr("Homebrew Launcher")); - if (Settings.wsprompt == yes) - homebrewBtnTT.SetWidescreen(CFG.widescreen); - homebrewBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiImage homebrewImg(&homebrewImgData); - GuiImage homebrewImgOver(&homebrewImgDataOver); - homebrewImg.SetWidescreen(CFG.widescreen); - homebrewImgOver.SetWidescreen(CFG.widescreen); - GuiButton homebrewBtn(&homebrewImg,&homebrewImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.homebrew_x, THEME.homebrew_y, &trigA, &btnSoundOver, btnClick2,1,&homebrewBtnTT,15,-30,1,5); - - if (Settings.fave) { - favoriteBtn.SetImage(&favoriteBtnImg); - favoriteBtn.SetImageOver(&favoriteBtnImg); - favoriteBtn.SetAlpha(255); - } - static bool show_searchwindow = false; - if(gameFilter && *gameFilter) - { - if(show_searchwindow && gameCnt==1) - show_searchwindow = false; - if(!show_searchwindow) - searchBtn.SetEffect(EFFECT_PULSE, 10, 105); - searchBtn.SetImage(&searchBtnImg); - searchBtn.SetImageOver(&searchBtnImg); - searchBtn.SetAlpha(255); - } - if (Settings.sort==all) { - abcBtn.SetImage(&abcBtnImg); - abcBtn.SetImageOver(&abcBtnImg); - abcBtn.SetAlpha(255); - } else if (Settings.sort==pcount) { - countBtn.SetImage(&countBtnImg); - countBtn.SetImageOver(&countBtnImg); - countBtn.SetAlpha(255); - } - if (Settings.gameDisplay==list) { - listBtn.SetImage(&listBtnImg); - listBtn.SetImageOver(&listBtnImg); - listBtn.SetAlpha(255); - } else if (Settings.gameDisplay==grid) { - gridBtn.SetImage(&gridBtnImg); - gridBtn.SetImageOver(&gridBtnImg); - gridBtn.SetAlpha(255); - } else if (Settings.gameDisplay==carousel) { - carouselBtn.SetImage(&carouselBtnImg); - carouselBtn.SetImageOver(&carouselBtnImg); - carouselBtn.SetAlpha(255); - } - if (Settings.gameDisplay==list) { - favoriteBtn.SetPosition(THEME.gamelist_favorite_x, THEME.gamelist_favorite_y); - searchBtn.SetPosition(THEME.gamelist_search_x, THEME.gamelist_search_y); - abcBtn.SetPosition(THEME.gamelist_abc_x, THEME.gamelist_abc_y); - countBtn.SetPosition(THEME.gamelist_count_x, THEME.gamelist_count_y); - listBtn.SetPosition(THEME.gamelist_list_x, THEME.gamelist_list_y); - gridBtn.SetPosition(THEME.gamelist_grid_x, THEME.gamelist_grid_y); - carouselBtn.SetPosition(THEME.gamelist_carousel_x, THEME.gamelist_carousel_y); - dvdBtn.SetPosition(THEME.gamelist_dvd_x, THEME.gamelist_dvd_y); - } else if(Settings.gameDisplay==grid) { - favoriteBtn.SetPosition(THEME.gamegrid_favorite_x, THEME.gamegrid_favorite_y); - searchBtn.SetPosition(THEME.gamegrid_search_x, THEME.gamegrid_search_y); - abcBtn.SetPosition(THEME.gamegrid_abc_x, THEME.gamegrid_abc_y); - countBtn.SetPosition(THEME.gamegrid_count_x, THEME.gamegrid_count_y); - listBtn.SetPosition(THEME.gamegrid_list_x, THEME.gamegrid_list_y); - gridBtn.SetPosition(THEME.gamegrid_grid_x, THEME.gamegrid_grid_y); - carouselBtn.SetPosition(THEME.gamegrid_carousel_x, THEME.gamegrid_carousel_y); - dvdBtn.SetPosition(THEME.gamegrid_dvd_x, THEME.gamegrid_dvd_y); - } else if(Settings.gameDisplay==carousel) { - favoriteBtn.SetPosition(THEME.gamecarousel_favorite_x, THEME.gamecarousel_favorite_y); - searchBtn.SetPosition(THEME.gamecarousel_search_x, THEME.gamecarousel_favorite_y); - abcBtn.SetPosition(THEME.gamecarousel_abc_x, THEME.gamecarousel_abc_y); - countBtn.SetPosition(THEME.gamecarousel_count_x, THEME.gamecarousel_count_y); - listBtn.SetPosition(THEME.gamecarousel_list_x, THEME.gamecarousel_list_y); - gridBtn.SetPosition(THEME.gamecarousel_grid_x, THEME.gamecarousel_grid_y); - carouselBtn.SetPosition(THEME.gamecarousel_carousel_x, THEME.gamecarousel_carousel_y); - dvdBtn.SetPosition(THEME.gamecarousel_dvd_x, THEME.gamecarousel_dvd_y); - } - - - //Downloading Covers - GuiTooltip DownloadBtnTT(tr("Click to Download Covers")); - if (Settings.wsprompt == yes) - DownloadBtnTT.SetWidescreen(CFG.widescreen); - DownloadBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiButton DownloadBtn(0,0); - DownloadBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP); - DownloadBtn.SetPosition(THEME.covers_x,THEME.covers_y); - - GuiTooltip IDBtnTT(tr("Click to change game ID")); - if (Settings.wsprompt == yes) - IDBtnTT.SetWidescreen(CFG.widescreen); - IDBtnTT.SetAlpha(THEME.tooltipAlpha); - GuiButton idBtn(0,0); - idBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP); - idBtn.SetPosition(THEME.id_x,THEME.id_y); - - - - if (Settings.godmode == 1 && mountMethod!=3) {//only make the button have trigger & tooltip if in godmode - DownloadBtn.SetSoundOver(&btnSoundOver); - DownloadBtn.SetTrigger(&trigA); - DownloadBtn.SetTrigger(&trig1); - DownloadBtn.SetToolTip(&DownloadBtnTT,205,-30); - - idBtn.SetSoundOver(&btnSoundOver); - idBtn.SetTrigger(&trigA); - idBtn.SetToolTip(&IDBtnTT,205,-30); - - } else - { - DownloadBtn.SetRumble(false); - idBtn.SetRumble(false); - } - - GuiGameBrowser * gameBrowser = NULL; - GuiGameGrid * gameGrid = NULL; - GuiGameCarousel * gameCarousel = NULL; - if (Settings.gameDisplay==list) { - gameBrowser = new GuiGameBrowser(THEME.gamelist_w, THEME.gamelist_h, gameList, gameCnt, CFG.theme_path, bg_options_png, startat, offset); - gameBrowser->SetPosition(THEME.gamelist_x, THEME.gamelist_y); - gameBrowser->SetAlignment(ALIGN_LEFT, ALIGN_CENTRE); - } else if (Settings.gameDisplay==grid) { - gameGrid = new GuiGameGrid(THEME.gamegrid_w,THEME.gamegrid_h, gameList, gameCnt, CFG.theme_path, bg_options_png, 0, 0); - gameGrid->SetPosition(THEME.gamegrid_x,THEME.gamegrid_y); - gameGrid->SetAlignment(ALIGN_LEFT, ALIGN_CENTRE); - } else if (Settings.gameDisplay==carousel) { - //GuiGameCarousel gameCarousel(THEME.gamecarousel_w, THEME.gamecarousel_h, gameList, gameCnt, CFG.theme_path, bg_options_png, startat, offset); - gameCarousel = new GuiGameCarousel(640, 400, gameList, gameCnt, CFG.theme_path, bg_options_png, startat, offset); - gameCarousel->SetPosition(THEME.gamecarousel_x,THEME.gamecarousel_y); - gameCarousel->SetAlignment(ALIGN_LEFT, ALIGN_CENTRE); - } - - GuiText clockTimeBack("88:88", 40, (GXColor) {THEME.clock.r, THEME.clock.g, THEME.clock.b, THEME.clock.a/6}); - clockTimeBack.SetAlignment(THEME.clock_align, ALIGN_TOP); - clockTimeBack.SetPosition(THEME.clock_x, THEME.clock_y); - clockTimeBack.SetFont(fontClock); - GuiText clockTime(theTime, 40, THEME.clock); - clockTime.SetAlignment(THEME.clock_align, ALIGN_TOP); - clockTime.SetPosition(THEME.clock_x, THEME.clock_y); - clockTime.SetFont(fontClock); - - HaltGui(); - GuiWindow w(screenwidth, screenheight); - - if (THEME.show_hddinfo == -1 || THEME.show_hddinfo == 1) { //force show hdd info - w.Append(&usedSpaceTxt); - } - if (THEME.show_gamecount == -1 || THEME.show_gamecount == 1) { //force show game cnt info - w.Append(&gamecntBtn); - } - w.Append(&sdcardBtn); - w.Append(&poweroffBtn); - w.Append(&gameInfo); - if (Settings.godmode) - w.Append(&installBtn); - w.Append(&homeBtn); - w.Append(&settingsBtn); - w.Append(&DownloadBtn); - w.Append(&idBtn); - - // Begin Toolbar - w.Append(&favoriteBtn); - Toolbar[0] = &favoriteBtn; - w.Append(&searchBtn); - Toolbar[1] = &searchBtn; - w.Append(&abcBtn); - Toolbar[2] = &abcBtn; - w.Append(&countBtn); - Toolbar[3] = &countBtn; - w.Append(&listBtn); - Toolbar[4] = &listBtn; - w.Append(&gridBtn); - Toolbar[5] = &gridBtn; - w.Append(&carouselBtn); - Toolbar[6] = &carouselBtn; - w.Append(&dvdBtn); - Toolbar[7] = &dvdBtn; - w.SetUpdateCallback(DiscListWinUpdateCallback); - // End Toolbar - - - - if (Settings.godmode == 1) - w.Append(&homebrewBtn); - - if ((Settings.hddinfo == hr12)||(Settings.hddinfo == hr24)) { - w.Append(&clockTimeBack); - w.Append(&clockTime); - } - - if (Settings.gameDisplay==list) { - mainWindow->Append(gameBrowser); - } - if (Settings.gameDisplay==grid) { - mainWindow->Append(gameGrid); - } - if (Settings.gameDisplay==carousel) { - mainWindow->Append(gameCarousel); - } - mainWindow->Append(&w); - - GuiSearchBar *searchBar=NULL; - if(show_searchwindow) { - searchBar = new GuiSearchBar(gameFilterNextList); - if(searchBar) - mainWindow->Append(searchBar); - } - - ResumeGui(); - - - while (menu == MENU_NONE) { - - if (idiotFlag==1) { - gprintf("\n\tIdiot flag"); - char idiotBuffer[200]; - snprintf(idiotBuffer, sizeof(idiotBuffer), "%s (%s). %s",tr("You have attempted to load a bad image"), - idiotChar,tr("Most likely it has dimensions that are not evenly divisible by 4.")); - - int deleteImg = WindowPrompt(0,idiotBuffer,tr("OK"),tr("Delete")); - if (deleteImg==0) { - snprintf(idiotBuffer, sizeof(idiotBuffer), "%s %s.",tr("You are about to delete "), idiotChar); - deleteImg = WindowPrompt(tr("Confirm"),idiotBuffer,tr("Delete"),tr("Cancel")); - if (deleteImg==1) { - remove(idiotChar); - } - } - idiotFlag=-1; - } - - WDVD_GetCoverStatus(&covert);//for detecting if i disc has been inserted - - // if the idiot is showing favorites and don't have any - if (Settings.fave && !gameCnt) { - WindowPrompt(tr("No Favorites"),tr("You are choosing to display favorites and you do not have any selected."),tr("Back")); - Settings.fave=!Settings.fave; - if (isInserted(bootDevice)) { - cfg_save_global(); - } - __Menu_GetEntries(); - menu = MENU_DISCLIST; - break; - } - - //CLOCK - time_t rawtime = time(0); //this fixes code dump caused by the clock - if (((Settings.hddinfo == hr12)||(Settings.hddinfo == hr24)) && rawtime != lastrawtime) { - lastrawtime = rawtime; - timeinfo = localtime (&rawtime); - if (dataed < 1) { - if (Settings.hddinfo == hr12) { - if (rawtime & 1) - strftime(theTime, sizeof(theTime), "%I:%M", timeinfo); - else - strftime(theTime, sizeof(theTime), "%I %M", timeinfo); - } - if (Settings.hddinfo == hr24) { - if (rawtime & 1) - strftime(theTime, sizeof(theTime), "%H:%M", timeinfo); - else - strftime(theTime, sizeof(theTime), "%H %M", timeinfo); - } - clockTime.SetText(theTime); - - } else if (dataed > 0) { - - clockTime.SetTextf("%i", (dataed-1)); - } - - } - if ((datagB<1)&&(Settings.cios==1)&&(Settings.video == ntsc)&&(Settings.hddinfo == hr12)&&(Settings.qboot==1)&&(Settings.wsprompt==0)&&(Settings.language==ger)&&(Settings.tooltips==0)){dataed=1;dataef=1;}if (dataef==1){if (cosa>7){cosa=1;}datag++;if (sina==3){wiiBtn.SetAlignment(ALIGN_LEFT,ALIGN_BOTTOM);wiiBtnImg.SetAngle(0);if(datag>163){datag=1;}else if (datag<62){wiiBtn.SetPosition(((cosa)*70),(-2*(datag)+120));}else if(62<=datag){wiiBtn.SetPosition(((cosa)*70),((datag*2)-130));}if (datag>162){wiiBtn.SetPosition(700,700);w.Remove(&wiiBtn);datagB=2;cosa++;sina=lastrawtime%4;}w.Append(&wiiBtn);}if (sina==2){wiiBtn.SetAlignment(ALIGN_RIGHT,ALIGN_TOP);wiiBtnImg.SetAngle(270);if(datag>163){datag=1;}else if (datag<62){wiiBtn.SetPosition(((-2*(datag)+130)),((cosa)*50));}else if(62<=datag){wiiBtn.SetPosition((2*(datag)-120),((cosa)*50));}if (datag>162){wiiBtn.SetPosition(700,700);w.Remove(&wiiBtn);datagB=2;cosa++;sina=lastrawtime%4;}w.Append(&wiiBtn);}if (sina==1){wiiBtn.SetAlignment(ALIGN_TOP,ALIGN_LEFT);wiiBtnImg.SetAngle(180);if(datag>163){datag=1;}else if (datag<62){wiiBtn.SetPosition(((cosa)*70),(2*(datag)-120));}else if(62<=datag){wiiBtn.SetPosition(((cosa)*70),(-2*(datag)+130));}if (datag>162){wiiBtn.SetPosition(700,700);w.Remove(&wiiBtn);datagB=2;cosa++;sina=lastrawtime%4;}w.Append(&wiiBtn);}if (sina==0){wiiBtn.SetAlignment(ALIGN_TOP,ALIGN_LEFT);wiiBtnImg.SetAngle(90);if(datag>163){datag=1;}else if (datag<62){wiiBtn.SetPosition(((2*(datag)-130)),((cosa)*50));}else if(62<=datag){wiiBtn.SetPosition((-2*(datag)+120),((cosa)*50));}if (datag>162){wiiBtn.SetPosition(700,700);w.Remove(&wiiBtn);datagB=2;cosa++;sina=lastrawtime%4;}w.Append(&wiiBtn);}} - // respond to button presses - if (shutdown == 1) { - gprintf("\n\tshutdown"); - Sys_Shutdown(); - } - if (reset == 1) - Sys_Reboot(); - - if (updateavailable == true) { - gprintf("\n\tUpdate Available"); - HaltGui(); - GuiWindow ww(640,480); - w.SetState(STATE_DISABLED); - mainWindow->Append(&ww); - ResumeGui(); - ProgressUpdateWindow(); - updateavailable = false; - mainWindow->Remove(&ww); - w.SetState(STATE_DEFAULT); - menu = MENU_DISCLIST; - } - - if (poweroffBtn.GetState() == STATE_CLICKED) { - - - gprintf("\n\tpoweroffBtn clicked"); - choice = WindowPrompt(tr("How to Shutdown?"),0,tr("Full Shutdown"), tr("Shutdown to Idle"), tr("Cancel")); - if (choice == 2) { - Sys_ShutdownToIdel(); - } else if (choice == 1) { - Sys_ShutdownToStandby(); - } else { - poweroffBtn.ResetState(); - if (Settings.gameDisplay==list) { - gameBrowser->SetFocus(1); - } else if (Settings.gameDisplay==grid) { - gameGrid->SetFocus(1); - } else if (Settings.gameDisplay==carousel) { - gameCarousel->SetFocus(1); - } - } - - } else if (gamecntBtn.GetState() == STATE_CLICKED && mountMethod!=3) { - gprintf("\n\tgameCntBtn clicked"); - gamecntBtn.ResetState(); - char linebuf[150]; - snprintf(linebuf, sizeof(linebuf), "%s %sGameList ?",tr("Save Game List to"), Settings.update_path); - choice = WindowPrompt(0,linebuf,"TXT","CSV",tr("Back")); - if (choice) { - if (save_gamelist(choice-1)) - WindowPrompt(0,tr("Saved"),tr("OK")); - else - WindowPrompt(tr("Error"),tr("Could not save."),tr("OK")); - } - menu = MENU_DISCLIST; - break; - - } else if (homeBtn.GetState() == STATE_CLICKED) { - gprintf("\n\thomeBtn clicked"); - bgMusic->Pause(); - choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); - bgMusic->Resume(); - - if (choice == 3) { - Sys_LoadMenu(); // Back to System Menu - } else if (choice == 2) { - Sys_BackToLoader(); - } else { - homeBtn.ResetState(); - if (Settings.gameDisplay==list) { - gameBrowser->SetFocus(1); - } else if (Settings.gameDisplay==grid) { - gameGrid->SetFocus(1); - } else if (Settings.gameDisplay==carousel) { - gameCarousel->SetFocus(1); - } - } - - } else if (wiiBtn.GetState() == STATE_CLICKED) { - gprintf("\n\twiiBtn clicked"); - - dataed++; - wiiBtn.ResetState(); - if (Settings.gameDisplay==list) { - gameBrowser->SetFocus(1); - } else if (Settings.gameDisplay==grid) { - gameGrid->SetFocus(1); - } else if (Settings.gameDisplay==carousel) { - gameCarousel->SetFocus(1); - } - } else if (installBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tinstallBtn clicked"); - choice = WindowPrompt(tr("Install a game"),0,tr("Yes"),tr("No")); - if (choice == 1) { - menu = MENU_INSTALL; - break; - } else { - installBtn.ResetState(); - if (Settings.gameDisplay==list) { - gameBrowser->SetFocus(1); - } else if (Settings.gameDisplay==grid) { - gameGrid->SetFocus(1); - } else if (Settings.gameDisplay==carousel) { - gameCarousel->SetFocus(1); - } - } - }else if ((covert & 0x2)&&(covert!=covertOld)) { - gprintf("\n\tNew Disc Detected"); - choice = WindowPrompt(tr("New Disc Detected"),0,tr("Install"),tr("Mount DVD drive"),tr("Cancel")); - if (choice == 1) { - menu = MENU_INSTALL; - break; - } - else if (choice ==2) - { - dvdBtn.SetState(STATE_CLICKED); - }else { - if (Settings.gameDisplay==list) { - gameBrowser->SetFocus(1); - } else if (Settings.gameDisplay==grid) { - gameGrid->SetFocus(1); - } else if (Settings.gameDisplay==carousel) { - gameCarousel->SetFocus(1); - } - } - } - - else if (sdcardBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tsdCardBtn Clicked"); - SDCard_deInit(); - SDCard_Init(); - if (Settings.gameDisplay==list) { - startat = gameBrowser->GetSelectedOption(); - offset = gameBrowser->GetOffset(); - } else if (Settings.gameDisplay==grid) { - startat = gameGrid->GetSelectedOption(); - offset = gameGrid->GetOffset(); - } else if (Settings.gameDisplay==carousel) { - startat = gameCarousel->GetSelectedOption(); - offset = gameCarousel->GetOffset(); - } - if (isInserted(bootDevice)) { - HaltGui(); // to fix endless rumble when clicking on the SD icon when rumble is disabled because rumble is set to on in Global_Default() - CFG_Load(); - ResumeGui(); - } - sdcardBtn.ResetState(); - menu = MENU_DISCLIST; - break; - } - - else if (DownloadBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tDownloadBtn Clicked"); - if (isInserted(bootDevice)) { - choice = WindowPrompt(tr("Cover Download"), 0, tr("Normal Covers"), tr("3D Covers"), tr("Disc Images"), tr("Back")); // ask for download choice - if (choice != 0) { - int choice2 = choice; - bool missing; - missing = SearchMissingImages(choice2); - if (IsNetworkInit() == false && missing == true) { - WindowPrompt(tr("Network init error"), 0, tr("OK")); - } else { - if (GetMissingFiles() != NULL && cntMissFiles > 0) { - char tempCnt[40]; - sprintf(tempCnt,"%i %s",cntMissFiles,tr("Missing files")); - if (choice!=3)choice = WindowPrompt(tr("Download Boxart image?"),tempCnt,tr("Yes"),tr("No")); - else if (choice==3)choice = WindowPrompt(tr("Download Discart image?"),tempCnt,tr("Yes"),tr("No")); - if (choice == 1) { - ret = ProgressDownloadWindow(choice2); - if (ret == 0) { - WindowPrompt(tr("Download finished"),0,tr("OK")); - } else { - sprintf(tempCnt,"%i %s",ret,tr("files not found on the server!")); - WindowPrompt(tr("Download finished"),tempCnt,tr("OK")); - } - } - } - } - } - } else { - WindowPrompt(tr("No SD-Card inserted!"), tr("Insert an SD-Card to download images."), tr("OK")); - } - menu = MENU_DISCLIST; - DownloadBtn.ResetState(); - if (Settings.gameDisplay==list) { - gameBrowser->SetFocus(1); - } else if (Settings.gameDisplay==grid) { - gameGrid->SetFocus(1); - } else if (Settings.gameDisplay==carousel) { - gameCarousel->SetFocus(1); - } - }//end download - - else if (settingsBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tsettingsBtn Clicked"); - if (Settings.gameDisplay==list) { - startat = gameBrowser->GetSelectedOption(); - offset = gameBrowser->GetOffset(); - } else if (Settings.gameDisplay==grid) { - startat = gameGrid->GetSelectedOption(); - offset = gameGrid->GetOffset(); - } else if (Settings.gameDisplay==carousel) { - startat = gameCarousel->GetSelectedOption(); - offset = gameCarousel->GetOffset(); - } - menu = MENU_SETTINGS; - break; - - } - - else if (favoriteBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tfavoriteBtn Clicked"); - Settings.fave=!Settings.fave; - if (isInserted(bootDevice)) { - cfg_save_global(); - } - __Menu_GetEntries(); - menu = MENU_DISCLIST; - break; - - } - - else if (searchBtn.GetState() == STATE_CLICKED && mountMethod!=3) { - - gprintf("\n\tsearchBtn Clicked"); - show_searchwindow=!show_searchwindow; - HaltGui(); - if(searchBar) - { - mainWindow->Remove(searchBar); - delete searchBar; - searchBar = NULL; - } - if(show_searchwindow) - { - if(gameFilter && *gameFilter) - { - searchBtn.StopEffect(); - searchBtn.SetEffectGrow(); - } - searchBar = new GuiSearchBar(gameFilterNextList); - if(searchBar) - mainWindow->Append(searchBar); - } - else - { - if(gameFilter && *gameFilter) - searchBtn.SetEffect(EFFECT_PULSE, 10, 105); - } - searchBtn.ResetState(); - ResumeGui(); - } - - else if (searchBar && (searchChar=searchBar->GetClicked())) { - if(searchChar > 27) - { - int len = gameFilter ? wcslen(gameFilter) : 0; - wchar_t newFilter[len+2]; - if(gameFilter) - wcscpy(newFilter, gameFilter); - newFilter[len] = searchChar; - newFilter[len+1] = 0; - - - __Menu_GetEntries(0, newFilter); - menu = MENU_DISCLIST; - break; - } - else if(searchChar == 7) // Close - { - show_searchwindow=false; - HaltGui(); - if(searchBar) - { - mainWindow->Remove(searchBar); - delete searchBar; - searchBar = NULL; - } - if(gameFilter && *gameFilter) - { - searchBtn.SetEffect(EFFECT_PULSE, 10, 105); - searchBtn.SetImage(&searchBtnImg); - searchBtn.SetImageOver(&searchBtnImg); - searchBtn.SetAlpha(255); - } - else - { - searchBtn.StopEffect(); - searchBtn.SetEffectGrow(); - searchBtn.SetImage(&searchBtnImg_g); - searchBtn.SetImageOver(&searchBtnImg_g); - searchBtn.SetAlpha(180); - } - - ResumeGui(); - } - else if(searchChar == 8) // Backspace - { - __Menu_GetEntries(0, gameFilterPrev); - menu = MENU_DISCLIST; - break; - } - - } - - else if (abcBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tabcBtn clicked"); - if (Settings.sort != all) { - Settings.sort=all; - if (isInserted(bootDevice)) { - cfg_save_global(); - } - __Menu_GetEntries(); - - menu = MENU_DISCLIST; - break; - } - abcBtn.ResetState(); - } - - else if (countBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tcountBtn Clicked"); - if (Settings.sort != pcount) { - Settings.sort=pcount; - //if(isSdInserted()) { - if (isInserted(bootDevice)) { - cfg_save_global(); - } - __Menu_GetEntries(); - - menu = MENU_DISCLIST; - break; - } - countBtn.ResetState(); - - } - - else if (listBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tlistBtn Clicked"); - if (Settings.gameDisplay!=list) { - Settings.gameDisplay=list; - menu = MENU_DISCLIST; - if (isInserted(bootDevice)) { - cfg_save_global(); - } - listBtn.ResetState(); - break; - } else { - listBtn.ResetState(); - } - } - - - else if (gridBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tgridBtn Clicked"); - if (Settings.gameDisplay!=grid) { - - Settings.gameDisplay=grid; - menu = MENU_DISCLIST; - if (isInserted(bootDevice)) { - cfg_save_global(); - } - gridBtn.ResetState(); - break; - } else { - gridBtn.ResetState(); - } - } - - else if (carouselBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tcarouselBtn Clicked"); - if (Settings.gameDisplay!=carousel) { - Settings.gameDisplay=carousel; - menu = MENU_DISCLIST; - if (isInserted(bootDevice)) { - cfg_save_global(); - } - carouselBtn.ResetState(); - break; - } else { - carouselBtn.ResetState(); - } - } else if (homebrewBtn.GetState() == STATE_CLICKED) { - gprintf("\n\thomebrewBtn Clicked"); - menu = MENU_HOMEBREWBROWSE; - break; - } else if (gameInfo.GetState() == STATE_CLICKED && mountMethod!=3) { - gprintf("\n\tgameinfo Clicked"); - gameInfo.ResetState(); - if(selectImg1>=0 && selectImg1<(s32)gameCnt) { - gameSelected = selectImg1; - rockout(); - struct discHdr *header = &gameList[selectImg1]; - snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]); - choice = showGameInfo(IDfull); - rockout(2); - if (choice==2) - homeBtn.SetState(STATE_CLICKED); - if (choice==3) { - menu = MENU_DISCLIST; - break; - } - } - } - else if (dvdBtn.GetState() == STATE_CLICKED) { - gprintf("\n\tdvdBtn Clicked"); - mountMethodOLD = (mountMethod==3?mountMethod:0); - - mountMethod=DiscMount(dvdheader); - dvdBtn.ResetState(); - - rockout(); - //break; - } - if (Settings.gameDisplay==grid) { - int selectimg; - DownloadBtn.SetSize(0,0); - selectimg = gameGrid->GetSelectedOption(); - gameSelected = gameGrid->GetClickedOption(); - selectImg1=selectimg; - } - - if (Settings.gameDisplay==carousel) { - int selectimg; - DownloadBtn.SetSize(0,0); - selectimg = gameCarousel->GetSelectedOption(); - gameSelected = gameCarousel->GetClickedOption(); - selectImg1=selectimg; - } - if (Settings.gameDisplay==list) { - //Get selected game under cursor - int selectimg; - DownloadBtn.SetSize(160,224); - idBtn.SetSize(100,40); - - selectimg = gameBrowser->GetSelectedOption(); - gameSelected = gameBrowser->GetClickedOption(); - selectImg1=selectimg; - - if (gameSelected > 0) //if click occured - selectimg = gameSelected; - - if ((selectimg >= 0) && (selectimg < (s32) gameCnt)) { - if (selectimg != selectedold) { - selectedold = selectimg;//update displayed cover, game ID, and region if the selected game changes - struct discHdr *header = &gameList[selectimg]; - snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]); - snprintf (IDfull,sizeof(IDfull),"%s%c%c%c", ID, header->id[3], header->id[4], header->id[5]); - w.Remove(&DownloadBtn); - - if (GameIDTxt) { - w.Remove(&idBtn); - delete GameIDTxt; - GameIDTxt = NULL; - } - if (GameRegionTxt) { - w.Remove(GameRegionTxt); - delete GameRegionTxt; - GameRegionTxt = NULL; - } - - switch (header->id[3]) { - case 'E': - sprintf(gameregion,"NTSC U"); - break; - case 'J': - sprintf(gameregion,"NTSC J"); - break; - case 'W': - sprintf(gameregion,"NTSC T"); - break; - case 'K': - sprintf(gameregion,"NTSC K"); - break; - case 'P': - case 'D': - case 'F': - case 'I': - case 'S': - case 'H': - case 'U': - case 'X': - case 'Y': - case 'Z': - sprintf(gameregion," PAL "); - break; - } - - //load game cover - if (cover) { - delete cover; - cover = NULL; - } - - cover = LoadCoverImage(header); - - if (coverImg) { - delete coverImg; - coverImg = NULL; - } - coverImg = new GuiImage(cover); - coverImg->SetWidescreen(CFG.widescreen); - - DownloadBtn.SetImage(coverImg);// put the new image on the download button - w.Append(&DownloadBtn); - - if ((Settings.sinfo == GameID) || (Settings.sinfo == Both)) { - GameIDTxt = new GuiText(IDfull, 22, THEME.info); - GameIDTxt->SetAlignment(ALIGN_LEFT, ALIGN_TOP); - //GameIDTxt->SetPosition(THEME.id_x,THEME.id_y); - idBtn.SetEffect(EFFECT_FADE, 20); - idBtn.SetLabel(GameIDTxt); - w.Append(&idBtn); - } - //don't try to show region for channels because all the custom channels wont follow the rules - if (((Settings.sinfo == GameRegion) || (Settings.sinfo == Both))&&mountMethod!=3) { - GameRegionTxt = new GuiText(gameregion, 22, THEME.info); - GameRegionTxt->SetAlignment(ALIGN_LEFT, ALIGN_TOP); - GameRegionTxt->SetPosition(THEME.region_x, THEME.region_y); - GameRegionTxt->SetEffect(EFFECT_FADE, 20); - w.Append(GameRegionTxt); - } - } - } - - if (idBtn.GetState() == STATE_CLICKED && mountMethod!=3) { - gprintf("\n\tidBtn Clicked"); - struct discHdr * header = &gameList[gameBrowser->GetSelectedOption()]; - //enter new game ID - char entered[10]; - snprintf(entered, sizeof(entered), "%s", IDfull); - //entered[9] = '\0'; - int result = OnScreenKeyboard(entered, 7,0); - if (result == 1) { - WBFS_ReIDGame(header->id, entered); - //__Menu_GetEntries(); - menu = MENU_DISCLIST; - } - - idBtn.ResetState(); - } - } - - if (((gameSelected >= 0) && (gameSelected < (s32)gameCnt)) - || mountMethod==1 - || mountMethod==2) { - if(searchBar) - { - HaltGui(); - mainWindow->Remove(searchBar); - ResumeGui(); - } - rockout(); - struct discHdr *header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); - // struct discHdr *header = dvdheader:&gameList[gameSelected]); - if (!mountMethod)//only get this stuff it we are booting a game from USB - { - WBFS_GameSize(header->id, &size); - if (strlen(get_title(header)) < (MAX_CHARACTERS + 3)) { - sprintf(text, "%s", get_title(header)); - } else { - strncpy(text, get_title(header), MAX_CHARACTERS); - text[MAX_CHARACTERS] = '\0'; - strncat(text, "...", 3); - } - } - - //check if alt Dol and gct file is present - FILE *exeFile = NULL; - char nipple[100]; - header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); //reset header - snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]); - struct Game_CFG* game_cfg = CFG_get_game_opt(header->id); - - if (game_cfg) { - alternatedol = game_cfg->loadalternatedol; - ocarinaChoice = game_cfg->ocarina; - } else { - alternatedol = off; - ocarinaChoice = Settings.ocarina; - } - - - if (Settings.qboot == yes) { //quickboot game - if (alternatedol == on) { - /* Open dol File and check exist */ - sprintf(nipple, "%s%s.dol",Settings.dolpath,IDfull); - exeFile = fopen (nipple ,"rb"); - if (exeFile==NULL) { - sprintf(nipple, "%s %s",nipple,tr("does not exist!")); - WindowPrompt(tr("Error"),nipple,tr("OK")); - menu = MENU_CHECK; - wiilight(0); - break; - } else { - fclose(exeFile); - } - } - if (ocarinaChoice != off) { - /* Open gct File and check exist */ - sprintf(nipple, "%s%s.gct",Settings.Cheatcodespath,IDfull); - exeFile = fopen (nipple ,"rb"); - if (exeFile==NULL) { - gprintf("\n\ttried to load missing gct."); - sprintf(nipple, "%s %s",nipple,tr("does not exist! Loading game without cheats.")); - WindowPrompt(tr("Error"),nipple,NULL,NULL,NULL,NULL,170); - } else { - fseek (exeFile, 0, SEEK_END); - long size=ftell (exeFile); - rewind (exeFile); - fclose(exeFile); - if (size>2056) { - gprintf("\n\tgct is too big"); - sprintf(nipple, "%s %s",nipple,tr("contains over 255 lines of code. It will produce unexpected results.")); - WindowPrompt(tr("Error"),nipple,NULL,NULL,NULL,NULL,170); - } - } - - } - - wiilight(0); - if (isInserted(bootDevice)) { - //////////save game play count//////////////// - struct Game_NUM* game_num = CFG_get_game_num(header->id); - - if (game_num) { - favoritevar = game_num->favorite; - playcount = game_num->count; - } else { - favoritevar = 0; - playcount = 0; - } - playcount += 1; - - CFG_save_game_num(header->id); - gprintf("\n\tplaycount for %c%c%c%c%c%c raised to %i",header->id[0],header->id[1],header->id[2],header->id[3],header->id[4],header->id[5],playcount); - - } - menu = MENU_EXIT; - break; - - } - bool returnHere = true;// prompt to start game - while (returnHere) { - returnHere = false; - if (Settings.wiilight != wiilight_forInstall) wiilight(1); - choice = GameWindowPrompt(); - // header = &gameList[gameSelected]; //reset header - - if (choice == 1) { - if (alternatedol == on) { - /* Open dol File and check exist */ - sprintf(nipple, "%s%s.dol",Settings.dolpath,IDfull); - exeFile = fopen (nipple ,"rb"); - if (exeFile==NULL) { - gprintf("\n\tTried to load alt dol that isn't there"); - sprintf(nipple, "%s %s",nipple,tr("does not exist! You Messed something up, Idiot.")); - WindowPrompt(tr("Error"),nipple,tr("OK")); - menu = MENU_CHECK; - wiilight(0); - break; - } else { - fclose(exeFile); - } - } - if (ocarinaChoice != off) { - /* Open gct File and check exist */ - sprintf(nipple, "%s%s.gct",Settings.Cheatcodespath,IDfull); - exeFile = fopen (nipple ,"rb"); - if (exeFile==NULL) { - gprintf("\n\ttried to load gct file that isn't there"); - sprintf(nipple, "%s %s",nipple,tr("does not exist! Loading game without cheats.")); - WindowPrompt(tr("Error"),nipple,NULL,NULL,NULL,NULL,170); - } else { - fseek (exeFile, 0, SEEK_END); - long size=ftell (exeFile); - rewind (exeFile); - fclose(exeFile); - if (size>2056) { - gprintf("\n\tgct file is too big"); - sprintf(nipple, "%s %s",nipple,tr("contains over 255 lines of code. It will produce unexpected results.")); - WindowPrompt(tr("Error"),nipple,NULL,NULL,NULL,NULL,170); - } - } - - } - wiilight(0); - returnHere = false; - menu = MENU_EXIT; - - } else if (choice == 2) { - wiilight(0); - HaltGui(); - if (Settings.gameDisplay==list) mainWindow->Remove(gameBrowser); - else if (Settings.gameDisplay==grid) mainWindow->Remove(gameGrid); - else if (Settings.gameDisplay==carousel) mainWindow->Remove(gameCarousel); - mainWindow->Remove(&w); - ResumeGui(); - - //re-evaluate header now in case they changed games while on the game prompt - header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); - int settret = GameSettings(header); - /* unneeded for now, kept in case database gets a separate language setting - //menu = MENU_DISCLIST; // refresh titles (needed if the language setting has changed) - */ - HaltGui(); - if (Settings.gameDisplay==list) mainWindow->Append(gameBrowser); - else if (Settings.gameDisplay==grid) mainWindow->Append(gameGrid); - else if (Settings.gameDisplay==carousel) mainWindow->Append(gameCarousel); - mainWindow->Append(&w); - ResumeGui(); - if (settret == 1) { //if deleted - menu = MENU_DISCLIST; - break; - } - returnHere = true; - rockout(2); - } - - else if (choice == 3 && !mountMethod) { //WBFS renaming - wiilight(0); - //re-evaluate header now in case they changed games while on the game prompt - header = &gameList[gameSelected]; - - //enter new game title - char entered[60]; - snprintf(entered, sizeof(entered), "%s", get_title(header)); - entered[59] = '\0'; - int result = OnScreenKeyboard(entered, 60,0); - if (result == 1) { - WBFS_RenameGame(header->id, entered); - __Menu_GetEntries(); - menu = MENU_DISCLIST; - } - } else if (choice == 0) { - rockout(2); - if (mountMethod==1||mountMethod==2)mountMethod = mountMethodOLD; - if (Settings.gameDisplay==list) { - gameBrowser->SetFocus(1); - } else if (Settings.gameDisplay==grid) { - gameGrid->SetFocus(1); - } else if (Settings.gameDisplay==carousel) { - gameCarousel->SetFocus(1); - } - } - - - } - if(searchBar) - { - HaltGui(); - mainWindow->Append(searchBar); - ResumeGui(); - } - } - // to skip the first call of windowScreensaver at startup when wiimote is not connected - if (IsWpadConnected()) { - check = 1; - } - - // screensaver is called when wiimote shuts down, depending on the wiimotet idletime - if (!IsWpadConnected() && check !=0 && Settings.screensaver!=0) { - check++; - int screensaverIsOn=0; - if (check==11500) { //to allow time for the wii to turn off and not show the screensaver - screensaverIsOn=WindowScreensaver(); - } - if (screensaverIsOn==1)check=0; - } - covertOld=covert; - } - - // set alt dol default - if (menu == MENU_EXIT && altdoldefault) { - struct discHdr *header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); - struct Game_CFG* game_cfg = CFG_get_game_opt(header->id); - // use default only if no alt dol was selected manually - if (game_cfg) { - if (game_cfg->alternatedolstart != 0) - altdoldefault = false; - } - if (altdoldefault) { - int autodol = autoSelectDol((char*)header->id, true); - if (autodol>0) { - alternatedol = 2; - alternatedoloffset = autodol; - char temp[20]; - sprintf(temp,"%d",autodol); - } else { - // alt dol menu for games that require more than a single alt dol - int autodol = autoSelectDolMenu((char*)header->id, true); - if (autodol>0) { - alternatedol = 2; - alternatedoloffset = autodol; - } - } - } - } - - if (menu == MENU_EXIT) { - SDCard_deInit(); - } - - HaltGui(); - mainWindow->RemoveAll(); - mainWindow->Append(bgImg); - delete searchBar; - searchBar = NULL; - delete gameBrowser; - gameBrowser = NULL; - delete gameGrid; - gameGrid = NULL; - delete gameCarousel; - gameCarousel = NULL; - ResumeGui(); - return menu; -} - - - -/**************************************************************************** - * MenuInstall - ***************************************************************************/ - -static int MenuInstall() { - gprintf("\nMenuInstall()"); - - int menu = MENU_NONE; - static struct discHdr headerdisc ATTRIBUTE_ALIGN(32); - - Disc_SetUSB(NULL); - - int ret, choice = 0; - char name[200]; - - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - - char imgPath[100]; - - snprintf(imgPath, sizeof(imgPath), "%sbattery.png", CFG.theme_path); - GuiImageData battery(imgPath, battery_png); - snprintf(imgPath, sizeof(imgPath), "%sbattery_bar.png", CFG.theme_path); - GuiImageData batteryBar(imgPath, battery_bar_png); - snprintf(imgPath, sizeof(imgPath), "%sbattery_red.png", CFG.theme_path); - GuiImageData batteryRed(imgPath, battery_red_png); - snprintf(imgPath, sizeof(imgPath), "%sbattery_bar_red.png", CFG.theme_path); - GuiImageData batteryBarRed(imgPath, battery_bar_red_png); - - HaltGui(); - GuiWindow w(screenwidth, screenheight); - - mainWindow->Append(&w); - - ResumeGui(); - - while (menu == MENU_NONE) { - VIDEO_WaitVSync (); - - ret = DiscWait(tr("Insert Disk"),tr("Waiting..."),tr("Cancel"),0,0); - if (ret < 0) { - WindowPrompt (tr("Error reading Disc"),0,tr("Back")); - menu = MENU_DISCLIST; - break; - } - ret = Disc_Open(); - if (ret < 0) { - WindowPrompt (tr("Could not open Disc"),0,tr("Back")); - menu = MENU_DISCLIST; - break; - } - - ret = Disc_IsWii(); - if (ret < 0) { - choice = WindowPrompt (tr("Not a Wii Disc"),tr("Insert a Wii Disc!"),tr("OK"),tr("Back")); - - if (choice == 1) { - menu = MENU_INSTALL; - break; - } else - menu = MENU_DISCLIST; - break; - } - - Disc_ReadHeader(&headerdisc); - snprintf(name, sizeof(name), "%s", headerdisc.title); - - ret = WBFS_CheckGame(headerdisc.id); - if (ret) { - WindowPrompt (tr("Game is already installed:"),name,tr("Back")); - menu = MENU_DISCLIST; - break; - } - - f32 freespace, used; - - WBFS_DiskSpace(&used, &freespace); - gamesize = WBFS_EstimeGameSize()/GBSIZE; - - char gametxt[50]; - - sprintf(gametxt, "%s : %.2fGB", name, gamesize); - - wiilight(1); - choice = WindowPrompt(tr("Continue to install game?"),gametxt,tr("OK"),tr("Cancel")); - - if (choice == 1) { - - sprintf(gametxt, "%s", tr("Installing game:")); - - if (gamesize > freespace) { - char errortxt[50]; - sprintf(errortxt, "%s: %.2fGB, %s: %.2fGB",tr("Game Size"), gamesize, tr("Free Space"), freespace); - WindowPrompt(tr("Not enough free space!"),errortxt,tr("OK")); - menu = MENU_DISCLIST; - break; - } else { - USBStorage_Watchdog(0); - SetupGameInstallProgress(gametxt, name); - ret = WBFS_AddGame(); - ProgressStop(); - USBStorage_Watchdog(1); - wiilight(0); - if (ret != 0) { - WindowPrompt(tr("Install Error!"),0,tr("Back")); - menu = MENU_DISCLIST; - break; - } else { - __Menu_GetEntries(); //get the entries again - GuiSound * instsuccess = NULL; - bgMusic->Pause(); - instsuccess = new GuiSound(success_ogg, success_ogg_size, Settings.sfxvolume); - instsuccess->SetVolume(Settings.sfxvolume); - instsuccess->SetLoop(0); - instsuccess->Play(); - WindowPrompt (tr("Successfully installed:"),name,tr("OK")); - instsuccess->Stop(); - delete instsuccess; - bgMusic->Resume(); - menu = MENU_DISCLIST; - break; - } - } - } else { - menu = MENU_DISCLIST; - break; - } - - if (shutdown == 1) { - wiilight(0); - Sys_Shutdown(); - } - if (reset == 1) { - wiilight(0); - Sys_Reboot(); - } - } - - //Turn off the WiiLight - wiilight(0); - - HaltGui(); - - mainWindow->Remove(&w); - ResumeGui(); - return menu; -} -/**************************************************************************** - * MenuFormat - ***************************************************************************/ - -static int MenuFormat() { - - USBDevice_deInit(); - sleep(1); - - USBStorage_Init(); - - int menu = MENU_NONE; - char imgPath[100]; - - customOptionList options(MAX_PARTITIONS); - partitionEntry partitions[MAX_PARTITIONS]; - - u32 cnt, sector_size; - int choice, ret; - char text[ISFS_MAXPATH]; - - s32 ret2; - ret2 = Partition_GetEntries(partitions, §or_size); - - //create the partitionlist - for (cnt = 0; cnt < MAX_PARTITIONS; cnt++) { - partitionEntry *entry = &partitions[cnt]; - - /* Calculate size in gigabytes */ - f32 size = entry->size * (sector_size / GBSIZE); - - if (size) { - options.SetName(cnt, "%s %d:",tr("Partition"), cnt+1); - options.SetValue(cnt,"%.2fGB", size); - } else { - options.SetName(cnt, "%s %d:",tr("Partition"), cnt+1); - options.SetValue(cnt,tr("Can't be formatted")); - } - } - - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); - // because destroy GuiSound must wait while sound playing is finished, we use a global sound - if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); - // GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); - snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff.png", CFG.theme_path); - GuiImageData btnpwroff(imgPath, wiimote_poweroff_png); - snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff_over.png", CFG.theme_path); - GuiImageData btnpwroffOver(imgPath, wiimote_poweroff_over_png); - snprintf(imgPath, sizeof(imgPath), "%smenu_button.png", CFG.theme_path); - GuiImageData btnhome(imgPath, menu_button_png); - snprintf(imgPath, sizeof(imgPath), "%smenu_button_over.png", CFG.theme_path); - GuiImageData btnhomeOver(imgPath, menu_button_over_png); - GuiImageData battery(battery_png); - GuiImageData batteryBar(battery_bar_png); - GuiImageData batteryRed(battery_red_png); - GuiImageData batteryBarRed(battery_bar_red_png); - - - GuiTrigger trigA; - trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); - GuiTrigger trigHome; - trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0); - - GuiImage poweroffBtnImg(&btnpwroff); - GuiImage poweroffBtnImgOver(&btnpwroffOver); - poweroffBtnImg.SetWidescreen(CFG.widescreen); - poweroffBtnImgOver.SetWidescreen(CFG.widescreen); - GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, btnClick2,1); - GuiImage exitBtnImg(&btnhome); - GuiImage exitBtnImgOver(&btnhomeOver); - exitBtnImg.SetWidescreen(CFG.widescreen); - exitBtnImgOver.SetWidescreen(CFG.widescreen); - GuiButton exitBtn(&exitBtnImg,&exitBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, btnClick2,1); - exitBtn.SetTrigger(&trigHome); - - GuiCustomOptionBrowser optionBrowser(396, 280, &options, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, 0, 10); - optionBrowser.SetPosition(0, 40); - optionBrowser.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); - - HaltGui(); - GuiWindow w(screenwidth, screenheight); - w.Append(&poweroffBtn); - w.Append(&exitBtn); - - mainWindow->Append(&w); - mainWindow->Append(&optionBrowser); - - ResumeGui(); - - while (menu == MENU_NONE) { - - VIDEO_WaitVSync (); - - ret = optionBrowser.GetClickedOption(); - - if(ret >= 0) { - if(Settings.godmode == 1) { - partitionEntry *entry = &partitions[ret]; - if (entry->size) { - sprintf(text, "%s %d : %.2fGB",tr("Partition"), ret+1, entry->size * (sector_size / GBSIZE)); - choice = WindowPrompt( tr("Do you want to format:"), text,tr("Yes"),tr("No")); - if (choice == 1) { - ret = FormatingPartition(tr("Formatting, please wait..."), entry); - if (ret < 0) { - WindowPrompt(tr("Error !"),tr("Failed formating"),tr("Return")); - menu = MENU_SETTINGS; - } else { - sleep(1); - ret = WBFS_Open(); - sprintf(text, "%s %s", text,tr("formatted!")); - WindowPrompt(tr("Success:"),text,tr("OK")); - if(ret < 0) { - WindowPrompt(tr("ERROR"), tr("Failed to open partition"), tr("OK")); - Sys_LoadMenu(); - } - menu = MENU_DISCLIST; - } - } - } else if(Settings.godmode == 0) { - mainWindow->Remove(&optionBrowser); - char entered[20] = ""; - int result = OnScreenKeyboard(entered, 20,0); - mainWindow->Append(&optionBrowser); - if ( result == 1 ) { - if (!strcmp(entered, Settings.unlockCode)) { //if password correct - if (Settings.godmode == 0) { - WindowPrompt(tr("Correct Password"),tr("All the features of USB Loader GX are unlocked."),tr("OK")); - Settings.godmode = 1; - } - } else { - WindowPrompt(tr("Wrong Password"),tr("USB Loader GX is protected"),tr("OK")); - } - } - } - } - } - - if (shutdown == 1) - Sys_Shutdown(); - if (reset == 1) - Sys_Reboot(); - - if (poweroffBtn.GetState() == STATE_CLICKED) { - choice = WindowPrompt (tr("Shutdown System"),tr("Are you sure?"),tr("Yes"),tr("No")); - if (choice == 1) { - Sys_Shutdown(); - } - - } else if (exitBtn.GetState() == STATE_CLICKED) { - choice = WindowPrompt (tr("Return to Wii Menu"),tr("Are you sure?"),tr("Yes"),tr("No")); - if (choice == 1) { - Sys_LoadMenu(); - } - } - } - - - HaltGui(); - - mainWindow->Remove(&optionBrowser); - mainWindow->Remove(&w); - ResumeGui(); - - return menu; -} - -/**************************************************************************** - * MenuCheck - ***************************************************************************/ -static int MenuCheck() { - gprintf("\nMenuCheck()"); - int menu = MENU_NONE; - int i = 0; - int choice; - s32 ret2, wbfsinit; - OptionList options; - options.length = i; - - VIDEO_WaitVSync (); - - wbfsinit = WBFS_Init(WBFS_DEVICE_USB); - if (wbfsinit < 0) { - ret2 = WindowPrompt(tr("No USB Device found."), tr("Do you want to retry for 30 secs?"), "cIOS249", "cIOS222", tr("Back to Wii Menu")); - SDCard_deInit(); - USBDevice_deInit(); - WPAD_Flush(0); - WPAD_Disconnect(0); - WPAD_Shutdown(); - if (ret2 == 1) { - Settings.cios = ios249; - } else if (ret2 == 2) { - Settings.cios = ios222; - } else { - Sys_LoadMenu(); - } - ret2 = DiscWait(tr("No USB Device"), tr("Waiting for USB Device"), 0, 0, 1); - //reinitialize SD and USB - Wpad_Init(); - WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); - WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight); - if (ret2 < 0) { - WindowPrompt (tr("Error !"),tr("USB Device not found"), tr("OK")); - Sys_LoadMenu(); - } - } - - ret2 = Disc_Init(); - if (ret2 < 0) { - WindowPrompt (tr("Error !"),tr("Could not initialize DIP module!"),tr("OK")); - Sys_LoadMenu(); - } - - ret2 = WBFS_Open(); - if (ret2 < 0) { - choice = WindowPrompt(tr("No WBFS partition found"),tr("You need to format a partition"), tr("Format"),tr("Return")); - if (choice == 0) { - Sys_LoadMenu(); - } else { - menu = MENU_FORMAT; - } - } - - if (shutdown == 1) - Sys_Shutdown(); - if (reset == 1) - Sys_Reboot(); - - if (wbfsinit < 0) { - sleep(1); - } - - //Spieleliste laden - __Menu_GetEntries(0); - - if (menu == MENU_NONE) - menu = MENU_DISCLIST; - - //for HDDs with issues - if (wbfsinit < 0) { - sleep(1); - USBDevice_Init(); - SDCard_Init(); - } - - return menu; -} /**************************************************************************** * MainMenu @@ -2202,7 +311,7 @@ int MainMenu(int menu) { } } - //MemInfoPrompt(); + // MemInfoPrompt(); //for testing /*if (mountMethod) { @@ -2212,7 +321,8 @@ int MainMenu(int menu) { } */ gprintf("\nExiting main GUI"); - CloseXMLDatabase(); + + CloseXMLDatabase(); ExitGUIThreads(); bgMusic->Stop(); delete bgMusic; @@ -2230,6 +340,7 @@ int MainMenu(int menu) { ShutdownAudio(); StopGX(); gettextCleanUp(); + if (mountMethod==3) { struct discHdr *header = &gameList[gameSelected]; @@ -2255,12 +366,11 @@ int MainMenu(int menu) { gprintf("\nBootHomebrewFromMenu"); BootHomebrewFromMem(); } else { - int ret = 0; struct discHdr *header = (mountMethod?dvdheader:&gameList[gameSelected]); struct Game_CFG* game_cfg = CFG_get_game_opt(header->id); - + if (game_cfg) { videoChoice = game_cfg->video; languageChoice = game_cfg->language; @@ -2292,31 +402,37 @@ int MainMenu(int menu) { } reloadblock = off; } - int ios2; - switch (iosChoice) { - case i249: - ios2 = 249; - break; - case i222: - ios2 = 222; - break; + switch (iosChoice) { + case i249: + ios2 = 249; + break; - case i223: - ios2 = 223; - break; + case i222: + ios2 = 222; + break; - default: - ios2 = 249; - break; - } + case i223: + ios2 = 223; + break; - bool onlinefix = ShutdownWC24(); - if (IOS_GetVersion() != ios2 || onlinefix == true) { - ret = Sys_IosReload(ios2); + default: + ios2 = 249; + break; + } + + // When the selected ios is 249, and you're loading from FAT, reset ios to 222 + if (load_from_fat && ios2 == 249) { + ios2 = 222; + } + bool onlinefix = !load_from_fat && ShutdownWC24(); + + // You cannot reload ios when loading from fat + if (IOS_GetVersion() != ios2 || onlinefix) { + ret = Sys_ChangeIos(ios2); if (ret < 0) { - Sys_IosReload(249); + Sys_ChangeIos(249); } } if (!mountMethod) @@ -2324,15 +440,13 @@ int MainMenu(int menu) { ret = Disc_SetUSB(header->id); if (ret < 0) Sys_BackToLoader(); gprintf("\n\tUSB set to game"); - } - else gprintf("\n\tUSB not set, loading DVD"); + else { + gprintf("\n\tUSB not set, loading DVD"); + } ret = Disc_Open(); - if (ret < 0) Sys_BackToLoader(); - SDCard_deInit(); - USBDevice_deInit(); - gprintf("\n\tSD and USB DeInit"); + if (ret < 0) Sys_BackToLoader(); if (gameList){ free(gameList); @@ -2340,9 +454,11 @@ int MainMenu(int menu) { if(dvdheader) delete dvdheader; - if (reloadblock == on && (IOS_GetVersion() == 222 || IOS_GetVersion() == 223)) { + if (reloadblock == on && Sys_IsHermes()) { patch_cios_data(); - mload_close(); + if (!load_from_fat) { + mload_close(); + } } u8 errorfixer002 = 0; @@ -2470,10 +586,13 @@ int MainMenu(int menu) { break; } gprintf("\n\tDisc_wiiBoot"); + ret = Disc_WiiBoot(videoselected, cheat, vipatch, countrystrings, errorfixer002, alternatedol, alternatedoloffset); if (ret < 0) { Sys_LoadMenu(); } + + printf("Returning entry point: 0x%0x\n", ret); } return 0; diff --git a/source/menu/menu_check.cpp b/source/menu/menu_check.cpp new file mode 100644 index 00000000..a5b6ac67 --- /dev/null +++ b/source/menu/menu_check.cpp @@ -0,0 +1,151 @@ +#include +#include + +#include "menus.h" +#include "wpad.h" +#include "fatmounter.h" +#include "usbloader/getentries.h" +#include "usbloader/wbfs.h" + +extern bool load_from_fat; +extern char game_partition[6]; + +/**************************************************************************** + * MenuCheck + ***************************************************************************/ +int MenuCheck() { + gprintf("\nMenuCheck()"); + int menu = MENU_NONE; + int i = 0; + int choice; + s32 ret2, wbfsinit; + OptionList options; + options.length = i; + + VIDEO_WaitVSync (); + + wbfsinit = WBFS_Init(WBFS_DEVICE_USB); + if (wbfsinit < 0) { + ret2 = WindowPrompt(tr("No USB Device found."), tr("Do you want to retry for 30 secs?"), "cIOS249", "cIOS222", tr("Back to Wii Menu")); + SDCard_deInit(); + USBDevice_deInit(); + WPAD_Flush(0); + WPAD_Disconnect(0); + WPAD_Shutdown(); + if (ret2 == 1) { + Settings.cios = ios249; + } else if (ret2 == 2) { + Settings.cios = ios222; + } else { + Sys_LoadMenu(); + } + ret2 = DiscWait(tr("No USB Device"), tr("Waiting for USB Device"), 0, 0, 1); + //reinitialize SD and USB + Wpad_Init(); + WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); + WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight); + if (ret2 < 0) { + WindowPrompt (tr("Error !"),tr("USB Device not found"), tr("OK")); + Sys_LoadMenu(); + } + } + + ret2 = -1; + memset(game_partition, 0, 6); + load_from_fat = false; + + extern PartList partitions; + // Added for slow HDD + for (int runs = 0; runs < 10; runs++) { + if (Partition_GetList(&partitions) != 0) { + sleep(1); + continue; + } + + if (Settings.partition != -1 && partitions.num > Settings.partition) { + PartInfo pinfo = partitions.pinfo[Settings.partition]; + ret2 = WBFS_OpenPart(pinfo.fs_type == FS_TYPE_FAT32, pinfo.fat_i, partitions.pentry[Settings.partition].sector, partitions.pentry[Settings.partition].size, (char *) &game_partition); + + if (ret2 == 0) + { + load_from_fat = pinfo.fs_type == FS_TYPE_FAT32; + break; + } + } + + if (partitions.wbfs_n != 0) { + ret2 = WBFS_Open(); + for (int p = 0; p < partitions.num; p++) { + if (partitions.pinfo[p].fs_type == FS_TYPE_WBFS) { + Settings.partition = p; + break; + } + } + } else if (Sys_IsHermes() && partitions.fat_n != 0) { + // Loop through FAT partitions, and find the first partition with games on it (if there is one) + u32 count; + for (int i = 0; i < partitions.num; i++) { + if (partitions.pinfo[i].fs_type == FS_TYPE_FAT32) { + if (!WBFS_OpenPart(1, partitions.pinfo[i].fat_i, partitions.pentry[i].sector, partitions.pentry[i].size, (char *) &game_partition)) { + // Get the game count... + WBFS_GetCount(&count); + + if (count > 0) { + load_from_fat = true; + Settings.partition = i; + break; + } else { + WBFS_Close(); + } + } + } + } + } + + if (ret2 >= 0 || load_from_fat) { + cfg_save_global(); + break; + } + sleep(1); + } + + if (ret2 < 0 && !load_from_fat) { + choice = WindowPrompt(tr("No WBFS or FAT game partition found"),tr("You need to select or format a partition"), tr("Select"), tr("Format"), tr("Return")); + if (choice == 0) { + Sys_LoadMenu(); + } else { + load_from_fat = choice == 1; + menu = MENU_FORMAT; + } + } + + ret2 = Disc_Init(); + if (ret2 < 0) { + WindowPrompt (tr("Error !"),tr("Could not initialize DIP module!"),tr("OK")); + Sys_LoadMenu(); + } + + if (shutdown == 1) + Sys_Shutdown(); + if (reset == 1) + Sys_Reboot(); + + if (wbfsinit < 0) { + sleep(1); + } + + //Spieleliste laden + __Menu_GetEntries(0); + + if (menu == MENU_NONE) + menu = MENU_DISCLIST; + + //for HDDs with issues + if (wbfsinit < 0) { + sleep(1); + USBDevice_Init(); + SDCard_Init(); + } + + return menu; +} diff --git a/source/menu/menu_disclist.cpp b/source/menu/menu_disclist.cpp new file mode 100644 index 00000000..a00a1d9f --- /dev/null +++ b/source/menu/menu_disclist.cpp @@ -0,0 +1,1508 @@ +#include "menus.h" +#include "fatmounter.h" +#include "usbloader/wdvd.h" +#include "usbloader/getentries.h" +#include "usbloader/wbfs.h" +#include "patches/fst.h" +#include "network/networkops.h" +#include "prompts/gameinfo.h" +#include "prompts/DiscBrowser.h" +#include "settings/Settings.h" +#include "wpad.h" + +#include "libwiigui/gui_gamebrowser.h" +#include "libwiigui/gui_gamegrid.h" +#include "libwiigui/gui_gamecarousel.h" +#include "libwiigui/gui_searchbar.h" + +#define MAX_CHARACTERS 38 + +extern struct discHdr *dvdheader; +extern u8 mountMethod; +extern bool load_from_fat; +extern s32 gameSelected; +extern GuiText * GameIDTxt; +extern GuiText * GameRegionTxt; +extern const u8 data1; +extern FreeTypeGX *fontClock; +extern bool updateavailable; +extern int cntMissFiles; +extern GuiImageData * cover; +extern GuiImage * coverImg; +extern GuiImageData * pointer[4]; +extern bool altdoldefault; +extern GuiImage * bgImg; + +GuiButton *Toolbar[8]; +int idiotFlag=-1; +char idiotChar[50]; + +void DiscListWinUpdateCallback(void * e); +void rockout(int f = 0); + +/**************************************************************************** + * MenuDiscList + ***************************************************************************/ +int MenuDiscList() { + + gprintf("\nMenuDiscList()");//testing out the gecko stuff. this shouldn't break anything, but we'll see + int startat = 0; + int offset = 0; + int datag = 0; + int datagB =0; + int dataed = -1; + int cosa=0,sina=0; + int selectImg1 = 0; + char ID[4]; + char IDfull[7]; + u32 covert = 0; + char imgPath[100]; + if (!dvdheader) + dvdheader = new struct discHdr; + u8 mountMethodOLD =0; + + WDVD_GetCoverStatus(&covert); + u32 covertOld=covert; + + f32 freespace, used, size = 0.0; + wchar_t searchChar; + //SCREENSAVER + //WPad_SetIdleTime(300); //needs the time in seconds + int check = 0; //to skip the first cycle when wiimote isn't completely connected + + datagB=0; + int menu = MENU_NONE, dataef=0; + __Menu_GetEntries(); + + u32 nolist; + char text[MAX_CHARACTERS + 4]; + int choice = 0, selectedold = 100; + s32 ret; + + //CLOCK + struct tm * timeinfo; + char theTime[80]=""; + time_t lastrawtime=0; + + if (mountMethod != 3 && !load_from_fat) { + WBFS_DiskSpace(&used, &freespace); + } + + if (!gameCnt) { //if there is no list of games to display + nolist = 1; + } + + GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); + // because destroy GuiSound must wait while sound playing is finished, we use a global sound + if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); + // GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); + + snprintf(imgPath, sizeof(imgPath), "%sbutton_install.png", CFG.theme_path); + GuiImageData btnInstall(imgPath, button_install_png); + snprintf(imgPath, sizeof(imgPath), "%sbutton_install_over.png", CFG.theme_path); + GuiImageData btnInstallOver(imgPath, button_install_over_png); + + snprintf(imgPath, sizeof(imgPath), "%ssettings_button.png", CFG.theme_path); + GuiImageData btnSettings(imgPath, settings_button_png); + snprintf(imgPath, sizeof(imgPath), "%ssettings_button_over.png", CFG.theme_path); + GuiImageData btnSettingsOver(imgPath, settings_button_over_png); + GuiImageData dataID(&data1); + + snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff.png", CFG.theme_path); + GuiImageData btnpwroff(imgPath, wiimote_poweroff_png); + snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff_over.png", CFG.theme_path); + GuiImageData btnpwroffOver(imgPath, wiimote_poweroff_over_png); + snprintf(imgPath, sizeof(imgPath), "%smenu_button.png", CFG.theme_path); + GuiImageData btnhome(imgPath, menu_button_png); + snprintf(imgPath, sizeof(imgPath), "%smenu_button_over.png", CFG.theme_path); + GuiImageData btnhomeOver(imgPath, menu_button_over_png); + snprintf(imgPath, sizeof(imgPath), "%sSDcard_over.png", CFG.theme_path); + GuiImageData btnsdcardOver(imgPath, sdcard_over_png); + snprintf(imgPath, sizeof(imgPath), "%sSDcard.png", CFG.theme_path); + GuiImageData btnsdcard(imgPath, sdcard_png); + + + snprintf(imgPath, sizeof(imgPath), "%sfavIcon.png", CFG.theme_path); + GuiImageData imgfavIcon(imgPath, favIcon_png); + snprintf(imgPath, sizeof(imgPath), "%sfavIcon_gray.png", CFG.theme_path); + GuiImageData imgfavIcon_gray(imgPath, NULL); + snprintf(imgPath, sizeof(imgPath), "%ssearchIcon.png", CFG.theme_path); + GuiImageData imgsearchIcon(imgPath, searchIcon_png); + snprintf(imgPath, sizeof(imgPath), "%ssearchIcon_gray.png", CFG.theme_path); + GuiImageData imgsearchIcon_gray(imgPath, NULL); + snprintf(imgPath, sizeof(imgPath), "%sabcIcon.png", CFG.theme_path); + GuiImageData imgabcIcon(imgPath, abcIcon_png); + snprintf(imgPath, sizeof(imgPath), "%sabcIcon_gray.png", CFG.theme_path); + GuiImageData imgabcIcon_gray(imgPath, NULL); + snprintf(imgPath, sizeof(imgPath), "%srankIcon.png", CFG.theme_path); + GuiImageData imgrankIcon(imgPath, rankIcon_png); + snprintf(imgPath, sizeof(imgPath), "%srankIcon_gray.png", CFG.theme_path); + GuiImageData imgrankIcon_gray(imgPath, NULL); + snprintf(imgPath, sizeof(imgPath), "%splayCountIcon.png", CFG.theme_path); + GuiImageData imgplayCountIcon(imgPath, playCountIcon_png); + snprintf(imgPath, sizeof(imgPath), "%splayCountIcon_gray.png", CFG.theme_path); + GuiImageData imgplayCountIcon_gray(imgPath, NULL); + snprintf(imgPath, sizeof(imgPath), "%sarrangeGrid.png", CFG.theme_path); + GuiImageData imgarrangeGrid(imgPath, arrangeGrid_png); + snprintf(imgPath, sizeof(imgPath), "%sarrangeGrid_gray.png", CFG.theme_path); + GuiImageData imgarrangeGrid_gray(imgPath, NULL); + snprintf(imgPath, sizeof(imgPath), "%sarrangeList.png", CFG.theme_path); + GuiImageData imgarrangeList(imgPath, arrangeList_png); + snprintf(imgPath, sizeof(imgPath), "%sarrangeList_gray.png", CFG.theme_path); + GuiImageData imgarrangeList_gray(imgPath, NULL); + snprintf(imgPath, sizeof(imgPath), "%sarrangeCarousel.png", CFG.theme_path); + GuiImageData imgarrangeCarousel(imgPath, arrangeCarousel_png); + snprintf(imgPath, sizeof(imgPath), "%sarrangeCarousel_gray.png", CFG.theme_path); + GuiImageData imgarrangeCarousel_gray(imgPath, NULL); + snprintf(imgPath, sizeof(imgPath), "%sdvd.png", CFG.theme_path); + GuiImageData imgdvd(imgPath, dvd_png); + snprintf(imgPath, sizeof(imgPath), "%sdvd_gray.png", CFG.theme_path); + GuiImageData imgdvd_gray(imgPath, NULL); + + snprintf(imgPath, sizeof(imgPath), "%sbrowser.png", CFG.theme_path); + GuiImageData homebrewImgData(imgPath, browser_png); + snprintf(imgPath, sizeof(imgPath), "%sbrowser_over.png", CFG.theme_path); + GuiImageData homebrewImgDataOver(imgPath, browser_over_png); + + + GuiTrigger trigA; + trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + GuiTrigger trigHome; + trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0); + GuiTrigger trig2; + trig2.SetButtonOnlyTrigger(-1, WPAD_BUTTON_2 | WPAD_CLASSIC_BUTTON_X, 0); + GuiTrigger trig1; + trig1.SetButtonOnlyTrigger(-1, WPAD_BUTTON_1 | WPAD_CLASSIC_BUTTON_Y, 0); + + char spaceinfo[30]; + if (load_from_fat) { + memset(spaceinfo, 0, 30); + } else { + if (!strcmp(Settings.db_language,"JA")) { + // needs to be "total...used" for Japanese + sprintf(spaceinfo,(mountMethod!=3?"%.2fGB %s %.2fGB %s":" "),(freespace+used),tr("of"),freespace,tr("free")); + } else { + sprintf(spaceinfo,(mountMethod!=3?"%.2fGB %s %.2fGB %s":" "),freespace,tr("of"),(freespace+used),tr("free")); + } + } + GuiText usedSpaceTxt(spaceinfo, 18, THEME.info); + usedSpaceTxt.SetAlignment(THEME.hddinfo_align, ALIGN_TOP); + usedSpaceTxt.SetPosition(THEME.hddinfo_x, THEME.hddinfo_y); + + char GamesCnt[15]; + sprintf(GamesCnt,"%s: %i",(mountMethod!=3?tr("Games"):tr("Channels")), gameCnt); + GuiText gamecntTxt(GamesCnt, 18, THEME.info); + + GuiButton gamecntBtn(100,18); + gamecntBtn.SetAlignment(THEME.gamecount_align, ALIGN_TOP); + gamecntBtn.SetPosition(THEME.gamecount_x,THEME.gamecount_y); + gamecntBtn.SetLabel(&gamecntTxt); + gamecntBtn.SetEffectGrow(); + gamecntBtn.SetTrigger(&trigA); + + GuiTooltip installBtnTT(tr("Install a game")); + if (Settings.wsprompt == yes) + installBtnTT.SetWidescreen(CFG.widescreen); + installBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage installBtnImg(&btnInstall); + GuiImage installBtnImgOver(&btnInstallOver); + installBtnImg.SetWidescreen(CFG.widescreen); + installBtnImgOver.SetWidescreen(CFG.widescreen); + + GuiButton installBtn(&installBtnImg, &installBtnImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.install_x, THEME.install_y, &trigA, &btnSoundOver, btnClick2, 1, &installBtnTT,24,-30, 0,5); + + + GuiTooltip settingsBtnTT(tr("Settings")); + if (Settings.wsprompt == yes) + settingsBtnTT.SetWidescreen(CFG.widescreen); + settingsBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage settingsBtnImg(&btnSettings); + settingsBtnImg.SetWidescreen(CFG.widescreen); + GuiImage settingsBtnImgOver(&btnSettingsOver); + settingsBtnImgOver.SetWidescreen(CFG.widescreen); + GuiButton settingsBtn(&settingsBtnImg,&settingsBtnImgOver, 0, 3, THEME.setting_x, THEME.setting_y, &trigA, &btnSoundOver, btnClick2,1,&settingsBtnTT,65,-30,0,5); + + GuiTooltip homeBtnTT(tr("Back to HBC or Wii Menu")); + if (Settings.wsprompt == yes) + homeBtnTT.SetWidescreen(CFG.widescreen); + settingsBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage homeBtnImg(&btnhome); + homeBtnImg.SetWidescreen(CFG.widescreen); + GuiImage homeBtnImgOver(&btnhomeOver); + homeBtnImgOver.SetWidescreen(CFG.widescreen); + GuiButton homeBtn(&homeBtnImg,&homeBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, btnClick2,1,&homeBtnTT,15,-30,1,5); + homeBtn.RemoveSoundClick(); + homeBtn.SetTrigger(&trigHome); + + GuiTooltip poweroffBtnTT(tr("Power off the Wii")); + if (Settings.wsprompt == yes) + poweroffBtnTT.SetWidescreen(CFG.widescreen); + poweroffBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage poweroffBtnImg(&btnpwroff); + GuiImage poweroffBtnImgOver(&btnpwroffOver); + poweroffBtnImg.SetWidescreen(CFG.widescreen); + poweroffBtnImgOver.SetWidescreen(CFG.widescreen); + GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, btnClick2,1,&poweroffBtnTT,-10,-30,1,5); + + GuiTooltip sdcardBtnTT(tr("Reload SD")); + if (Settings.wsprompt == yes) + sdcardBtnTT.SetWidescreen(CFG.widescreen); + sdcardBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage sdcardImg(&btnsdcard); + GuiImage sdcardImgOver(&btnsdcardOver); + sdcardImg.SetWidescreen(CFG.widescreen); + sdcardImgOver.SetWidescreen(CFG.widescreen); + GuiButton sdcardBtn(&sdcardImg,&sdcardImgOver, 0, 3, THEME.sdcard_x, THEME.sdcard_y, &trigA, &btnSoundOver, btnClick2,1,&sdcardBtnTT,15,-30,0,5); + + GuiButton gameInfo(0,0); + gameInfo.SetTrigger(&trig2); + gameInfo.SetSoundClick(btnClick2); + + + GuiImage wiiBtnImg(&dataID); + wiiBtnImg.SetWidescreen(CFG.widescreen); + GuiButton wiiBtn(&wiiBtnImg,&wiiBtnImg, 0, 4, 0, -10, &trigA, &btnSoundOver, btnClick2,0); + + GuiTooltip favoriteBtnTT(tr("Display favorites")); + if (Settings.wsprompt == yes) + favoriteBtnTT.SetWidescreen(CFG.widescreen); + favoriteBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage favoriteBtnImg(&imgfavIcon); + favoriteBtnImg.SetWidescreen(CFG.widescreen); +// GuiImage favoriteBtnImg_g(favoriteBtnImg);favoriteBtnImg_g.SetGrayscale(); + GuiImage favoriteBtnImg_g(&imgfavIcon_gray); + if(favoriteBtnImg_g.GetImage() == NULL) { favoriteBtnImg_g = favoriteBtnImg; favoriteBtnImg_g.SetGrayscale();} + favoriteBtnImg_g.SetWidescreen(CFG.widescreen); + GuiButton favoriteBtn(&favoriteBtnImg_g,&favoriteBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_favorite_x, THEME.gamelist_favorite_y, &trigA, &btnSoundOver, btnClick2,1, &favoriteBtnTT, -15, 52, 0, 3); + favoriteBtn.SetAlpha(180); + + GuiTooltip searchBtnTT(tr("Set Search-Filter")); + if (Settings.wsprompt == yes) + searchBtnTT.SetWidescreen(CFG.widescreen); + searchBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage searchBtnImg(&imgsearchIcon); + searchBtnImg.SetWidescreen(CFG.widescreen); +// GuiImage searchBtnImg_g(searchBtnImg); searchBtnImg_g.SetGrayscale(); + GuiImage searchBtnImg_g(&imgsearchIcon_gray); + if(searchBtnImg_g.GetImage() == NULL) { searchBtnImg_g = searchBtnImg; searchBtnImg_g.SetGrayscale();} + searchBtnImg_g.SetWidescreen(CFG.widescreen); + GuiButton searchBtn(&searchBtnImg_g,&searchBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_search_x, THEME.gamelist_search_y, &trigA, &btnSoundOver, btnClick2,1, &searchBtnTT, -15, 52, 0, 3); + searchBtn.SetAlpha(180); + + GuiTooltip abcBtnTT(Settings.fave ? tr("Sort by rank") : tr("Sort alphabetically")); + if (Settings.wsprompt == yes) + abcBtnTT.SetWidescreen(CFG.widescreen); + abcBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage abcBtnImg(Settings.fave ? &imgrankIcon : &imgabcIcon); + abcBtnImg.SetWidescreen(CFG.widescreen); +// GuiImage abcBtnImg_g(abcBtnImg); abcBtnImg_g.SetGrayscale(); + GuiImage abcBtnImg_g(Settings.fave ? &imgrankIcon_gray : &imgabcIcon_gray); + if(abcBtnImg_g.GetImage() == NULL) { abcBtnImg_g = abcBtnImg; abcBtnImg_g.SetGrayscale();} + abcBtnImg_g.SetWidescreen(CFG.widescreen); + GuiButton abcBtn(&abcBtnImg_g,&abcBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_abc_x, THEME.gamelist_abc_y, &trigA, &btnSoundOver, btnClick2,1,&abcBtnTT, -15, 52, 0, 3); + abcBtn.SetAlpha(180); + + GuiTooltip countBtnTT(tr("Sort order by most played")); + if (Settings.wsprompt == yes) + countBtnTT.SetWidescreen(CFG.widescreen); + countBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage countBtnImg(&imgplayCountIcon); + countBtnImg.SetWidescreen(CFG.widescreen); +// GuiImage countBtnImg_g(countBtnImg); countBtnImg_g.SetGrayscale(); + GuiImage countBtnImg_g(&imgplayCountIcon_gray); + if(countBtnImg_g.GetImage() == NULL) { countBtnImg_g = countBtnImg; countBtnImg_g.SetGrayscale();} + countBtnImg_g.SetWidescreen(CFG.widescreen); + GuiButton countBtn(&countBtnImg_g,&countBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_count_x, THEME.gamelist_count_y, &trigA, &btnSoundOver, btnClick2,1, &countBtnTT, -15, 52, 0, 3); + countBtn.SetAlpha(180); + + GuiTooltip listBtnTT(tr("Display as a list")); + if (Settings.wsprompt == yes) + listBtnTT.SetWidescreen(CFG.widescreen); + listBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage listBtnImg(&imgarrangeList); + listBtnImg.SetWidescreen(CFG.widescreen); +// GuiImage listBtnImg_g(listBtnImg); listBtnImg_g.SetGrayscale(); + GuiImage listBtnImg_g(&imgarrangeList_gray); + if(listBtnImg_g.GetImage() == NULL) { listBtnImg_g = listBtnImg; listBtnImg_g.SetGrayscale();} + listBtnImg_g.SetWidescreen(CFG.widescreen); + GuiButton listBtn(&listBtnImg_g,&listBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_list_x, THEME.gamelist_list_y, &trigA, &btnSoundOver, btnClick2,1, &listBtnTT, 15, 52, 1, 3); + listBtn.SetAlpha(180); + + GuiTooltip gridBtnTT(tr("Display as a grid")); + if (Settings.wsprompt == yes) + gridBtnTT.SetWidescreen(CFG.widescreen); + gridBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage gridBtnImg(&imgarrangeGrid); + gridBtnImg.SetWidescreen(CFG.widescreen); +// GuiImage gridBtnImg_g(gridBtnImg); gridBtnImg_g.SetGrayscale(); + GuiImage gridBtnImg_g(&imgarrangeGrid_gray); + if(gridBtnImg_g.GetImage() == NULL) { gridBtnImg_g = gridBtnImg; gridBtnImg_g.SetGrayscale();} + gridBtnImg_g.SetWidescreen(CFG.widescreen); + GuiButton gridBtn(&gridBtnImg_g,&gridBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_grid_x, THEME.gamelist_grid_y, &trigA, &btnSoundOver, btnClick2,1, &gridBtnTT, 15, 52, 1, 3); + gridBtn.SetAlpha(180); + + GuiTooltip carouselBtnTT(tr("Display as a carousel")); + if (Settings.wsprompt == yes) + carouselBtnTT.SetWidescreen(CFG.widescreen); + carouselBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage carouselBtnImg(&imgarrangeCarousel); + carouselBtnImg.SetWidescreen(CFG.widescreen); +// GuiImage carouselBtnImg_g(carouselBtnImg); carouselBtnImg_g.SetGrayscale(); + GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray); + if(carouselBtnImg_g.GetImage() == NULL) { carouselBtnImg_g = carouselBtnImg; carouselBtnImg_g.SetGrayscale();} + carouselBtnImg_g.SetWidescreen(CFG.widescreen); + GuiButton carouselBtn(&carouselBtnImg_g,&carouselBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_carousel_x, THEME.gamelist_carousel_y, &trigA, &btnSoundOver, btnClick2,1, &carouselBtnTT, 15, 52, 1, 3); + carouselBtn.SetAlpha(180); + + GuiTooltip dvdBtnTT(tr("Mount DVD drive")); + if (Settings.wsprompt == yes) + dvdBtnTT.SetWidescreen(CFG.widescreen); + dvdBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage dvdBtnImg(&imgdvd); + dvdBtnImg.SetWidescreen(CFG.widescreen); + GuiImage dvdBtnImg_g(dvdBtnImg); //dvdBtnImg_g.SetGrayscale(); +// GuiImage carouselBtnImg_g(&imgarrangeCarousel_gray); + dvdBtnImg_g.SetWidescreen(CFG.widescreen); + GuiButton dvdBtn(&dvdBtnImg_g,&dvdBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_dvd_x, THEME.gamelist_dvd_y, &trigA, &btnSoundOver, btnClick2,1, &dvdBtnTT, 15, 52, 1, 3); + dvdBtn.SetAlpha(180); + + GuiTooltip homebrewBtnTT(tr("Homebrew Launcher")); + if (Settings.wsprompt == yes) + homebrewBtnTT.SetWidescreen(CFG.widescreen); + homebrewBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage homebrewImg(&homebrewImgData); + GuiImage homebrewImgOver(&homebrewImgDataOver); + homebrewImg.SetWidescreen(CFG.widescreen); + homebrewImgOver.SetWidescreen(CFG.widescreen); + GuiButton homebrewBtn(&homebrewImg,&homebrewImgOver, ALIGN_LEFT, ALIGN_TOP, THEME.homebrew_x, THEME.homebrew_y, &trigA, &btnSoundOver, btnClick2,1,&homebrewBtnTT,15,-30,1,5); + + if (Settings.fave) { + favoriteBtn.SetImage(&favoriteBtnImg); + favoriteBtn.SetImageOver(&favoriteBtnImg); + favoriteBtn.SetAlpha(255); + } + static bool show_searchwindow = false; + if(gameFilter && *gameFilter) + { + if(show_searchwindow && gameCnt==1) + show_searchwindow = false; + if(!show_searchwindow) + searchBtn.SetEffect(EFFECT_PULSE, 10, 105); + searchBtn.SetImage(&searchBtnImg); + searchBtn.SetImageOver(&searchBtnImg); + searchBtn.SetAlpha(255); + } + if (Settings.sort==all) { + abcBtn.SetImage(&abcBtnImg); + abcBtn.SetImageOver(&abcBtnImg); + abcBtn.SetAlpha(255); + } else if (Settings.sort==pcount) { + countBtn.SetImage(&countBtnImg); + countBtn.SetImageOver(&countBtnImg); + countBtn.SetAlpha(255); + } + if (Settings.gameDisplay==list) { + listBtn.SetImage(&listBtnImg); + listBtn.SetImageOver(&listBtnImg); + listBtn.SetAlpha(255); + } else if (Settings.gameDisplay==grid) { + gridBtn.SetImage(&gridBtnImg); + gridBtn.SetImageOver(&gridBtnImg); + gridBtn.SetAlpha(255); + } else if (Settings.gameDisplay==carousel) { + carouselBtn.SetImage(&carouselBtnImg); + carouselBtn.SetImageOver(&carouselBtnImg); + carouselBtn.SetAlpha(255); + } + if (Settings.gameDisplay==list) { + favoriteBtn.SetPosition(THEME.gamelist_favorite_x, THEME.gamelist_favorite_y); + searchBtn.SetPosition(THEME.gamelist_search_x, THEME.gamelist_search_y); + abcBtn.SetPosition(THEME.gamelist_abc_x, THEME.gamelist_abc_y); + countBtn.SetPosition(THEME.gamelist_count_x, THEME.gamelist_count_y); + listBtn.SetPosition(THEME.gamelist_list_x, THEME.gamelist_list_y); + gridBtn.SetPosition(THEME.gamelist_grid_x, THEME.gamelist_grid_y); + carouselBtn.SetPosition(THEME.gamelist_carousel_x, THEME.gamelist_carousel_y); + dvdBtn.SetPosition(THEME.gamelist_dvd_x, THEME.gamelist_dvd_y); + } else if(Settings.gameDisplay==grid) { + favoriteBtn.SetPosition(THEME.gamegrid_favorite_x, THEME.gamegrid_favorite_y); + searchBtn.SetPosition(THEME.gamegrid_search_x, THEME.gamegrid_search_y); + abcBtn.SetPosition(THEME.gamegrid_abc_x, THEME.gamegrid_abc_y); + countBtn.SetPosition(THEME.gamegrid_count_x, THEME.gamegrid_count_y); + listBtn.SetPosition(THEME.gamegrid_list_x, THEME.gamegrid_list_y); + gridBtn.SetPosition(THEME.gamegrid_grid_x, THEME.gamegrid_grid_y); + carouselBtn.SetPosition(THEME.gamegrid_carousel_x, THEME.gamegrid_carousel_y); + dvdBtn.SetPosition(THEME.gamegrid_dvd_x, THEME.gamegrid_dvd_y); + } else if(Settings.gameDisplay==carousel) { + favoriteBtn.SetPosition(THEME.gamecarousel_favorite_x, THEME.gamecarousel_favorite_y); + searchBtn.SetPosition(THEME.gamecarousel_search_x, THEME.gamecarousel_favorite_y); + abcBtn.SetPosition(THEME.gamecarousel_abc_x, THEME.gamecarousel_abc_y); + countBtn.SetPosition(THEME.gamecarousel_count_x, THEME.gamecarousel_count_y); + listBtn.SetPosition(THEME.gamecarousel_list_x, THEME.gamecarousel_list_y); + gridBtn.SetPosition(THEME.gamecarousel_grid_x, THEME.gamecarousel_grid_y); + carouselBtn.SetPosition(THEME.gamecarousel_carousel_x, THEME.gamecarousel_carousel_y); + dvdBtn.SetPosition(THEME.gamecarousel_dvd_x, THEME.gamecarousel_dvd_y); + } + + + //Downloading Covers + GuiTooltip DownloadBtnTT(tr("Click to Download Covers")); + if (Settings.wsprompt == yes) + DownloadBtnTT.SetWidescreen(CFG.widescreen); + DownloadBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiButton DownloadBtn(0,0); + DownloadBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP); + DownloadBtn.SetPosition(THEME.covers_x,THEME.covers_y); + + GuiTooltip IDBtnTT(tr("Click to change game ID")); + if (Settings.wsprompt == yes) + IDBtnTT.SetWidescreen(CFG.widescreen); + IDBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiButton idBtn(0,0); + idBtn.SetAlignment(ALIGN_LEFT, ALIGN_TOP); + idBtn.SetPosition(THEME.id_x,THEME.id_y); + + + + if (Settings.godmode == 1 && mountMethod!=3) {//only make the button have trigger & tooltip if in godmode + DownloadBtn.SetSoundOver(&btnSoundOver); + DownloadBtn.SetTrigger(&trigA); + DownloadBtn.SetTrigger(&trig1); + DownloadBtn.SetToolTip(&DownloadBtnTT,205,-30); + + idBtn.SetSoundOver(&btnSoundOver); + idBtn.SetTrigger(&trigA); + idBtn.SetToolTip(&IDBtnTT,205,-30); + + } else + { + DownloadBtn.SetRumble(false); + idBtn.SetRumble(false); + } + + GuiGameBrowser * gameBrowser = NULL; + GuiGameGrid * gameGrid = NULL; + GuiGameCarousel * gameCarousel = NULL; + if (Settings.gameDisplay==list) { + gameBrowser = new GuiGameBrowser(THEME.gamelist_w, THEME.gamelist_h, gameList, gameCnt, CFG.theme_path, bg_options_png, startat, offset); + gameBrowser->SetPosition(THEME.gamelist_x, THEME.gamelist_y); + gameBrowser->SetAlignment(ALIGN_LEFT, ALIGN_CENTRE); + } else if (Settings.gameDisplay==grid) { + gameGrid = new GuiGameGrid(THEME.gamegrid_w,THEME.gamegrid_h, gameList, gameCnt, CFG.theme_path, bg_options_png, 0, 0); + gameGrid->SetPosition(THEME.gamegrid_x,THEME.gamegrid_y); + gameGrid->SetAlignment(ALIGN_LEFT, ALIGN_CENTRE); + } else if (Settings.gameDisplay==carousel) { + //GuiGameCarousel gameCarousel(THEME.gamecarousel_w, THEME.gamecarousel_h, gameList, gameCnt, CFG.theme_path, bg_options_png, startat, offset); + gameCarousel = new GuiGameCarousel(640, 400, gameList, gameCnt, CFG.theme_path, bg_options_png, startat, offset); + gameCarousel->SetPosition(THEME.gamecarousel_x,THEME.gamecarousel_y); + gameCarousel->SetAlignment(ALIGN_LEFT, ALIGN_CENTRE); + } + + GuiText clockTimeBack("88:88", 40, (GXColor) {THEME.clock.r, THEME.clock.g, THEME.clock.b, THEME.clock.a/6}); + clockTimeBack.SetAlignment(THEME.clock_align, ALIGN_TOP); + clockTimeBack.SetPosition(THEME.clock_x, THEME.clock_y); + clockTimeBack.SetFont(fontClock); + GuiText clockTime(theTime, 40, THEME.clock); + clockTime.SetAlignment(THEME.clock_align, ALIGN_TOP); + clockTime.SetPosition(THEME.clock_x, THEME.clock_y); + clockTime.SetFont(fontClock); + + HaltGui(); + GuiWindow w(screenwidth, screenheight); + + if (THEME.show_hddinfo == -1 || THEME.show_hddinfo == 1) { //force show hdd info + w.Append(&usedSpaceTxt); + } + if (THEME.show_gamecount == -1 || THEME.show_gamecount == 1) { //force show game cnt info + w.Append(&gamecntBtn); + } + w.Append(&sdcardBtn); + w.Append(&poweroffBtn); + w.Append(&gameInfo); + if (Settings.godmode) + w.Append(&installBtn); + w.Append(&homeBtn); + w.Append(&settingsBtn); + w.Append(&DownloadBtn); + w.Append(&idBtn); + + // Begin Toolbar + w.Append(&favoriteBtn); + Toolbar[0] = &favoriteBtn; + w.Append(&searchBtn); + Toolbar[1] = &searchBtn; + w.Append(&abcBtn); + Toolbar[2] = &abcBtn; + w.Append(&countBtn); + Toolbar[3] = &countBtn; + w.Append(&listBtn); + Toolbar[4] = &listBtn; + w.Append(&gridBtn); + Toolbar[5] = &gridBtn; + w.Append(&carouselBtn); + Toolbar[6] = &carouselBtn; + w.Append(&dvdBtn); + Toolbar[7] = &dvdBtn; + w.SetUpdateCallback(DiscListWinUpdateCallback); + // End Toolbar + + + + if (Settings.godmode == 1) + w.Append(&homebrewBtn); + + if ((Settings.hddinfo == hr12)||(Settings.hddinfo == hr24)) { + w.Append(&clockTimeBack); + w.Append(&clockTime); + } + + if (Settings.gameDisplay==list) { + mainWindow->Append(gameBrowser); + } + if (Settings.gameDisplay==grid) { + mainWindow->Append(gameGrid); + } + if (Settings.gameDisplay==carousel) { + mainWindow->Append(gameCarousel); + } + mainWindow->Append(&w); + + GuiSearchBar *searchBar=NULL; + if(show_searchwindow) { + searchBar = new GuiSearchBar(gameFilterNextList); + if(searchBar) + mainWindow->Append(searchBar); + } + + ResumeGui(); + + while (menu == MENU_NONE) { + + if (idiotFlag==1) { + gprintf("\n\tIdiot flag"); + char idiotBuffer[200]; + snprintf(idiotBuffer, sizeof(idiotBuffer), "%s (%s). %s",tr("You have attempted to load a bad image"), + idiotChar,tr("Most likely it has dimensions that are not evenly divisible by 4.")); + + int deleteImg = WindowPrompt(0,idiotBuffer,tr("OK"),tr("Delete")); + if (deleteImg==0) { + snprintf(idiotBuffer, sizeof(idiotBuffer), "%s %s.",tr("You are about to delete "), idiotChar); + deleteImg = WindowPrompt(tr("Confirm"),idiotBuffer,tr("Delete"),tr("Cancel")); + if (deleteImg==1) { + remove(idiotChar); + } + } + idiotFlag=-1; + } + + WDVD_GetCoverStatus(&covert);//for detecting if i disc has been inserted + + // if the idiot is showing favorites and don't have any + if (Settings.fave && !gameCnt) { + WindowPrompt(tr("No Favorites"),tr("You are choosing to display favorites and you do not have any selected."),tr("Back")); + Settings.fave=!Settings.fave; + if (isInserted(bootDevice)) { + cfg_save_global(); + } + __Menu_GetEntries(); + menu = MENU_DISCLIST; + break; + } + + //CLOCK + time_t rawtime = time(0); //this fixes code dump caused by the clock + if (((Settings.hddinfo == hr12)||(Settings.hddinfo == hr24)) && rawtime != lastrawtime) { + lastrawtime = rawtime; + timeinfo = localtime (&rawtime); + if (dataed < 1) { + if (Settings.hddinfo == hr12) { + if (rawtime & 1) + strftime(theTime, sizeof(theTime), "%I:%M", timeinfo); + else + strftime(theTime, sizeof(theTime), "%I %M", timeinfo); + } + if (Settings.hddinfo == hr24) { + if (rawtime & 1) + strftime(theTime, sizeof(theTime), "%H:%M", timeinfo); + else + strftime(theTime, sizeof(theTime), "%H %M", timeinfo); + } + clockTime.SetText(theTime); + + } else if (dataed > 0) { + + clockTime.SetTextf("%i", (dataed-1)); + } + + } + if ((datagB<1)&&(Settings.cios==1)&&(Settings.video == ntsc)&&(Settings.hddinfo == hr12)&&(Settings.qboot==1)&&(Settings.wsprompt==0)&&(Settings.language==ger)&&(Settings.tooltips==0)){dataed=1;dataef=1;}if (dataef==1){if (cosa>7){cosa=1;}datag++;if (sina==3){wiiBtn.SetAlignment(ALIGN_LEFT,ALIGN_BOTTOM);wiiBtnImg.SetAngle(0);if(datag>163){datag=1;}else if (datag<62){wiiBtn.SetPosition(((cosa)*70),(-2*(datag)+120));}else if(62<=datag){wiiBtn.SetPosition(((cosa)*70),((datag*2)-130));}if (datag>162){wiiBtn.SetPosition(700,700);w.Remove(&wiiBtn);datagB=2;cosa++;sina=lastrawtime%4;}w.Append(&wiiBtn);}if (sina==2){wiiBtn.SetAlignment(ALIGN_RIGHT,ALIGN_TOP);wiiBtnImg.SetAngle(270);if(datag>163){datag=1;}else if (datag<62){wiiBtn.SetPosition(((-2*(datag)+130)),((cosa)*50));}else if(62<=datag){wiiBtn.SetPosition((2*(datag)-120),((cosa)*50));}if (datag>162){wiiBtn.SetPosition(700,700);w.Remove(&wiiBtn);datagB=2;cosa++;sina=lastrawtime%4;}w.Append(&wiiBtn);}if (sina==1){wiiBtn.SetAlignment(ALIGN_TOP,ALIGN_LEFT);wiiBtnImg.SetAngle(180);if(datag>163){datag=1;}else if (datag<62){wiiBtn.SetPosition(((cosa)*70),(2*(datag)-120));}else if(62<=datag){wiiBtn.SetPosition(((cosa)*70),(-2*(datag)+130));}if (datag>162){wiiBtn.SetPosition(700,700);w.Remove(&wiiBtn);datagB=2;cosa++;sina=lastrawtime%4;}w.Append(&wiiBtn);}if (sina==0){wiiBtn.SetAlignment(ALIGN_TOP,ALIGN_LEFT);wiiBtnImg.SetAngle(90);if(datag>163){datag=1;}else if (datag<62){wiiBtn.SetPosition(((2*(datag)-130)),((cosa)*50));}else if(62<=datag){wiiBtn.SetPosition((-2*(datag)+120),((cosa)*50));}if (datag>162){wiiBtn.SetPosition(700,700);w.Remove(&wiiBtn);datagB=2;cosa++;sina=lastrawtime%4;}w.Append(&wiiBtn);}} + // respond to button presses + if (shutdown == 1) { + gprintf("\n\tshutdown"); + Sys_Shutdown(); + } + if (reset == 1) + Sys_Reboot(); + + if (updateavailable == true) { + gprintf("\n\tUpdate Available"); + HaltGui(); + GuiWindow ww(640,480); + w.SetState(STATE_DISABLED); + mainWindow->Append(&ww); + ResumeGui(); + ProgressUpdateWindow(); + updateavailable = false; + mainWindow->Remove(&ww); + w.SetState(STATE_DEFAULT); + menu = MENU_DISCLIST; + } + + if (poweroffBtn.GetState() == STATE_CLICKED) { + + + gprintf("\n\tpoweroffBtn clicked"); + choice = WindowPrompt(tr("How to Shutdown?"),0,tr("Full Shutdown"), tr("Shutdown to Idle"), tr("Cancel")); + if (choice == 2) { + Sys_ShutdownToIdel(); + } else if (choice == 1) { + Sys_ShutdownToStandby(); + } else { + poweroffBtn.ResetState(); + if (Settings.gameDisplay==list) { + gameBrowser->SetFocus(1); + } else if (Settings.gameDisplay==grid) { + gameGrid->SetFocus(1); + } else if (Settings.gameDisplay==carousel) { + gameCarousel->SetFocus(1); + } + } + + } else if (gamecntBtn.GetState() == STATE_CLICKED && mountMethod!=3) { + gprintf("\n\tgameCntBtn clicked"); + gamecntBtn.ResetState(); + char linebuf[150]; + snprintf(linebuf, sizeof(linebuf), "%s %sGameList ?",tr("Save Game List to"), Settings.update_path); + choice = WindowPrompt(0,linebuf,"TXT","CSV",tr("Back")); + if (choice) { + if (save_gamelist(choice-1)) + WindowPrompt(0,tr("Saved"),tr("OK")); + else + WindowPrompt(tr("Error"),tr("Could not save."),tr("OK")); + } + menu = MENU_DISCLIST; + break; + + } else if (homeBtn.GetState() == STATE_CLICKED) { + gprintf("\n\thomeBtn clicked"); + bgMusic->Pause(); + choice = WindowExitPrompt(tr("Exit USB Loader GX?"),0, tr("Back to Loader"),tr("Wii Menu"),tr("Back"),0); + bgMusic->Resume(); + + if (choice == 3) { + Sys_LoadMenu(); // Back to System Menu + } else if (choice == 2) { + Sys_BackToLoader(); + } else { + homeBtn.ResetState(); + if (Settings.gameDisplay==list) { + gameBrowser->SetFocus(1); + } else if (Settings.gameDisplay==grid) { + gameGrid->SetFocus(1); + } else if (Settings.gameDisplay==carousel) { + gameCarousel->SetFocus(1); + } + } + + } else if (wiiBtn.GetState() == STATE_CLICKED) { + gprintf("\n\twiiBtn clicked"); + + dataed++; + wiiBtn.ResetState(); + if (Settings.gameDisplay==list) { + gameBrowser->SetFocus(1); + } else if (Settings.gameDisplay==grid) { + gameGrid->SetFocus(1); + } else if (Settings.gameDisplay==carousel) { + gameCarousel->SetFocus(1); + } + } else if (installBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tinstallBtn clicked"); + choice = WindowPrompt(tr("Install a game"),0,tr("Yes"),tr("No")); + if (choice == 1) { + menu = MENU_INSTALL; + break; + } else { + installBtn.ResetState(); + if (Settings.gameDisplay==list) { + gameBrowser->SetFocus(1); + } else if (Settings.gameDisplay==grid) { + gameGrid->SetFocus(1); + } else if (Settings.gameDisplay==carousel) { + gameCarousel->SetFocus(1); + } + } + }else if ((covert & 0x2)&&(covert!=covertOld)) { + gprintf("\n\tNew Disc Detected"); + choice = WindowPrompt(tr("New Disc Detected"),0,tr("Install"),tr("Mount DVD drive"),tr("Cancel")); + if (choice == 1) { + menu = MENU_INSTALL; + break; + } + else if (choice ==2) + { + dvdBtn.SetState(STATE_CLICKED); + }else { + if (Settings.gameDisplay==list) { + gameBrowser->SetFocus(1); + } else if (Settings.gameDisplay==grid) { + gameGrid->SetFocus(1); + } else if (Settings.gameDisplay==carousel) { + gameCarousel->SetFocus(1); + } + } + } + + else if (sdcardBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tsdCardBtn Clicked"); + SDCard_deInit(); + SDCard_Init(); + if (Settings.gameDisplay==list) { + startat = gameBrowser->GetSelectedOption(); + offset = gameBrowser->GetOffset(); + } else if (Settings.gameDisplay==grid) { + startat = gameGrid->GetSelectedOption(); + offset = gameGrid->GetOffset(); + } else if (Settings.gameDisplay==carousel) { + startat = gameCarousel->GetSelectedOption(); + offset = gameCarousel->GetOffset(); + } + if (isInserted(bootDevice)) { + HaltGui(); // to fix endless rumble when clicking on the SD icon when rumble is disabled because rumble is set to on in Global_Default() + CFG_Load(); + ResumeGui(); + } + sdcardBtn.ResetState(); + menu = MENU_DISCLIST; + break; + } + + else if (DownloadBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tDownloadBtn Clicked"); + if (isInserted(bootDevice)) { + choice = WindowPrompt(tr("Cover Download"), 0, tr("Normal Covers"), tr("3D Covers"), tr("Disc Images"), tr("Back")); // ask for download choice + if (choice != 0) { + int choice2 = choice; + bool missing; + missing = SearchMissingImages(choice2); + if (IsNetworkInit() == false && missing == true) { + WindowPrompt(tr("Network init error"), 0, tr("OK")); + } else { + if (GetMissingFiles() != NULL && cntMissFiles > 0) { + char tempCnt[40]; + sprintf(tempCnt,"%i %s",cntMissFiles,tr("Missing files")); + if (choice!=3)choice = WindowPrompt(tr("Download Boxart image?"),tempCnt,tr("Yes"),tr("No")); + else if (choice==3)choice = WindowPrompt(tr("Download Discart image?"),tempCnt,tr("Yes"),tr("No")); + if (choice == 1) { + ret = ProgressDownloadWindow(choice2); + if (ret == 0) { + WindowPrompt(tr("Download finished"),0,tr("OK")); + } else { + sprintf(tempCnt,"%i %s",ret,tr("files not found on the server!")); + WindowPrompt(tr("Download finished"),tempCnt,tr("OK")); + } + } + } + } + } + } else { + WindowPrompt(tr("No SD-Card inserted!"), tr("Insert an SD-Card to download images."), tr("OK")); + } + menu = MENU_DISCLIST; + DownloadBtn.ResetState(); + if (Settings.gameDisplay==list) { + gameBrowser->SetFocus(1); + } else if (Settings.gameDisplay==grid) { + gameGrid->SetFocus(1); + } else if (Settings.gameDisplay==carousel) { + gameCarousel->SetFocus(1); + } + }//end download + + else if (settingsBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tsettingsBtn Clicked"); + if (Settings.gameDisplay==list) { + startat = gameBrowser->GetSelectedOption(); + offset = gameBrowser->GetOffset(); + } else if (Settings.gameDisplay==grid) { + startat = gameGrid->GetSelectedOption(); + offset = gameGrid->GetOffset(); + } else if (Settings.gameDisplay==carousel) { + startat = gameCarousel->GetSelectedOption(); + offset = gameCarousel->GetOffset(); + } + menu = MENU_SETTINGS; + break; + + } + + else if (favoriteBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tfavoriteBtn Clicked"); + Settings.fave=!Settings.fave; + if (isInserted(bootDevice)) { + cfg_save_global(); + } + __Menu_GetEntries(); + menu = MENU_DISCLIST; + break; + + } + + else if (searchBtn.GetState() == STATE_CLICKED && mountMethod!=3) { + + gprintf("\n\tsearchBtn Clicked"); + show_searchwindow=!show_searchwindow; + HaltGui(); + if(searchBar) + { + mainWindow->Remove(searchBar); + delete searchBar; + searchBar = NULL; + } + if(show_searchwindow) + { + if(gameFilter && *gameFilter) + { + searchBtn.StopEffect(); + searchBtn.SetEffectGrow(); + } + searchBar = new GuiSearchBar(gameFilterNextList); + if(searchBar) + mainWindow->Append(searchBar); + } + else + { + if(gameFilter && *gameFilter) + searchBtn.SetEffect(EFFECT_PULSE, 10, 105); + } + searchBtn.ResetState(); + ResumeGui(); + } + + else if (searchBar && (searchChar=searchBar->GetClicked())) { + if(searchChar > 27) + { + int len = gameFilter ? wcslen(gameFilter) : 0; + wchar_t newFilter[len+2]; + if(gameFilter) + wcscpy(newFilter, gameFilter); + newFilter[len] = searchChar; + newFilter[len+1] = 0; + + + __Menu_GetEntries(0, newFilter); + menu = MENU_DISCLIST; + break; + } + else if(searchChar == 7) // Close + { + show_searchwindow=false; + HaltGui(); + if(searchBar) + { + mainWindow->Remove(searchBar); + delete searchBar; + searchBar = NULL; + } + if(gameFilter && *gameFilter) + { + searchBtn.SetEffect(EFFECT_PULSE, 10, 105); + searchBtn.SetImage(&searchBtnImg); + searchBtn.SetImageOver(&searchBtnImg); + searchBtn.SetAlpha(255); + } + else + { + searchBtn.StopEffect(); + searchBtn.SetEffectGrow(); + searchBtn.SetImage(&searchBtnImg_g); + searchBtn.SetImageOver(&searchBtnImg_g); + searchBtn.SetAlpha(180); + } + + ResumeGui(); + } + else if(searchChar == 8) // Backspace + { + __Menu_GetEntries(0, gameFilterPrev); + menu = MENU_DISCLIST; + break; + } + + } + + else if (abcBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tabcBtn clicked"); + if (Settings.sort != all) { + Settings.sort=all; + if (isInserted(bootDevice)) { + cfg_save_global(); + } + __Menu_GetEntries(); + + menu = MENU_DISCLIST; + break; + } + abcBtn.ResetState(); + } + + else if (countBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tcountBtn Clicked"); + if (Settings.sort != pcount) { + Settings.sort=pcount; + //if(isSdInserted()) { + if (isInserted(bootDevice)) { + cfg_save_global(); + } + __Menu_GetEntries(); + + menu = MENU_DISCLIST; + break; + } + countBtn.ResetState(); + + } + + else if (listBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tlistBtn Clicked"); + if (Settings.gameDisplay!=list) { + Settings.gameDisplay=list; + menu = MENU_DISCLIST; + if (isInserted(bootDevice)) { + cfg_save_global(); + } + listBtn.ResetState(); + break; + } else { + listBtn.ResetState(); + } + } + + + else if (gridBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tgridBtn Clicked"); + if (Settings.gameDisplay!=grid) { + + Settings.gameDisplay=grid; + menu = MENU_DISCLIST; + if (isInserted(bootDevice)) { + cfg_save_global(); + } + gridBtn.ResetState(); + break; + } else { + gridBtn.ResetState(); + } + } + + else if (carouselBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tcarouselBtn Clicked"); + if (Settings.gameDisplay!=carousel) { + Settings.gameDisplay=carousel; + menu = MENU_DISCLIST; + if (isInserted(bootDevice)) { + cfg_save_global(); + } + carouselBtn.ResetState(); + break; + } else { + carouselBtn.ResetState(); + } + } else if (homebrewBtn.GetState() == STATE_CLICKED) { + gprintf("\n\thomebrewBtn Clicked"); + menu = MENU_HOMEBREWBROWSE; + break; + } else if (gameInfo.GetState() == STATE_CLICKED && mountMethod!=3) { + gprintf("\n\tgameinfo Clicked"); + gameInfo.ResetState(); + if(selectImg1>=0 && selectImg1<(s32)gameCnt) { + gameSelected = selectImg1; + rockout(); + struct discHdr *header = &gameList[selectImg1]; + snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]); + choice = showGameInfo(IDfull); + rockout(2); + if (choice==2) + homeBtn.SetState(STATE_CLICKED); + if (choice==3) { + menu = MENU_DISCLIST; + break; + } + } + } + else if (dvdBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tdvdBtn Clicked"); + mountMethodOLD = (mountMethod==3?mountMethod:0); + + mountMethod=DiscMount(dvdheader); + dvdBtn.ResetState(); + + rockout(); + //break; + } + if (Settings.gameDisplay==grid) { + int selectimg; + DownloadBtn.SetSize(0,0); + selectimg = gameGrid->GetSelectedOption(); + gameSelected = gameGrid->GetClickedOption(); + selectImg1=selectimg; + } + + if (Settings.gameDisplay==carousel) { + int selectimg; + DownloadBtn.SetSize(0,0); + selectimg = gameCarousel->GetSelectedOption(); + gameSelected = gameCarousel->GetClickedOption(); + selectImg1=selectimg; + } + if (Settings.gameDisplay==list) { + //Get selected game under cursor + int selectimg; + DownloadBtn.SetSize(160,224); + idBtn.SetSize(100,40); + + selectimg = gameBrowser->GetSelectedOption(); + gameSelected = gameBrowser->GetClickedOption(); + selectImg1=selectimg; + + if (gameSelected > 0) //if click occured + selectimg = gameSelected; + + char gameregion[7]; + if ((selectimg >= 0) && (selectimg < (s32) gameCnt)) { + if (selectimg != selectedold) { + selectedold = selectimg;//update displayed cover, game ID, and region if the selected game changes + struct discHdr *header = &gameList[selectimg]; + snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]); + snprintf (IDfull,sizeof(IDfull),"%s%c%c%c", ID, header->id[3], header->id[4], header->id[5]); + w.Remove(&DownloadBtn); + + if (GameIDTxt) { + w.Remove(&idBtn); + delete GameIDTxt; + GameIDTxt = NULL; + } + if (GameRegionTxt) { + w.Remove(GameRegionTxt); + delete GameRegionTxt; + GameRegionTxt = NULL; + } + + switch (header->id[3]) { + case 'E': + sprintf(gameregion,"NTSC U"); + break; + case 'J': + sprintf(gameregion,"NTSC J"); + break; + case 'W': + sprintf(gameregion,"NTSC T"); + break; + case 'K': + sprintf(gameregion,"NTSC K"); + break; + case 'P': + case 'D': + case 'F': + case 'I': + case 'S': + case 'H': + case 'U': + case 'X': + case 'Y': + case 'Z': + sprintf(gameregion," PAL "); + break; + } + + //load game cover + if (cover) { + delete cover; + cover = NULL; + } + + cover = LoadCoverImage(header); + + if (coverImg) { + delete coverImg; + coverImg = NULL; + } + coverImg = new GuiImage(cover); + coverImg->SetWidescreen(CFG.widescreen); + + DownloadBtn.SetImage(coverImg);// put the new image on the download button + w.Append(&DownloadBtn); + + if ((Settings.sinfo == GameID) || (Settings.sinfo == Both)) { + GameIDTxt = new GuiText(IDfull, 22, THEME.info); + GameIDTxt->SetAlignment(ALIGN_LEFT, ALIGN_TOP); + //GameIDTxt->SetPosition(THEME.id_x,THEME.id_y); + idBtn.SetEffect(EFFECT_FADE, 20); + idBtn.SetLabel(GameIDTxt); + w.Append(&idBtn); + } + //don't try to show region for channels because all the custom channels wont follow the rules + if (((Settings.sinfo == GameRegion) || (Settings.sinfo == Both))&&mountMethod!=3) { + GameRegionTxt = new GuiText(gameregion, 22, THEME.info); + GameRegionTxt->SetAlignment(ALIGN_LEFT, ALIGN_TOP); + GameRegionTxt->SetPosition(THEME.region_x, THEME.region_y); + GameRegionTxt->SetEffect(EFFECT_FADE, 20); + w.Append(GameRegionTxt); + } + } + } + + if (idBtn.GetState() == STATE_CLICKED && mountMethod!=3) { + gprintf("\n\tidBtn Clicked"); + struct discHdr * header = &gameList[gameBrowser->GetSelectedOption()]; + //enter new game ID + char entered[10]; + snprintf(entered, sizeof(entered), "%s", IDfull); + //entered[9] = '\0'; + int result = OnScreenKeyboard(entered, 7,0); + if (result == 1) { + WBFS_ReIDGame(header->id, entered); + //__Menu_GetEntries(); + menu = MENU_DISCLIST; + } + + idBtn.ResetState(); + } + } + + if (((gameSelected >= 0) && (gameSelected < (s32)gameCnt)) + || mountMethod==1 + || mountMethod==2) { + if(searchBar) + { + HaltGui(); + mainWindow->Remove(searchBar); + ResumeGui(); + } + rockout(); + struct discHdr *header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); + // struct discHdr *header = dvdheader:&gameList[gameSelected]); + if (!mountMethod)//only get this stuff it we are booting a game from USB + { + WBFS_GameSize(header->id, &size); + if (strlen(get_title(header)) < (MAX_CHARACTERS + 3)) { + sprintf(text, "%s", get_title(header)); + } else { + strncpy(text, get_title(header), MAX_CHARACTERS); + text[MAX_CHARACTERS] = '\0'; + strncat(text, "...", 3); + } + } + + //check if alt Dol and gct file is present + FILE *exeFile = NULL; + char nipple[100]; + header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); //reset header + snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]); + struct Game_CFG* game_cfg = CFG_get_game_opt(header->id); + + if (game_cfg) { + alternatedol = game_cfg->loadalternatedol; + ocarinaChoice = game_cfg->ocarina; + } else { + alternatedol = off; + ocarinaChoice = Settings.ocarina; + } + + + if (Settings.qboot == yes) { //quickboot game + if (alternatedol == on) { + /* Open dol File and check exist */ + sprintf(nipple, "%s%s.dol",Settings.dolpath,IDfull); + exeFile = fopen (nipple ,"rb"); + if (exeFile==NULL) { + sprintf(nipple, "%s %s",nipple,tr("does not exist!")); + WindowPrompt(tr("Error"),nipple,tr("OK")); + menu = MENU_CHECK; + wiilight(0); + break; + } else { + fclose(exeFile); + } + } + if (ocarinaChoice != off) { + /* Open gct File and check exist */ + sprintf(nipple, "%s%s.gct",Settings.Cheatcodespath,IDfull); + exeFile = fopen (nipple ,"rb"); + if (exeFile==NULL) { + gprintf("\n\ttried to load missing gct."); + sprintf(nipple, "%s %s",nipple,tr("does not exist! Loading game without cheats.")); + WindowPrompt(tr("Error"),nipple,NULL,NULL,NULL,NULL,170); + } else { + fseek (exeFile, 0, SEEK_END); + long size=ftell (exeFile); + rewind (exeFile); + fclose(exeFile); + if (size>MAX_GCT_SIZE) { + gprintf("\n\tgct is too big"); + sprintf(nipple, "%s %s",nipple,tr("contains over 255 lines of code. It will produce unexpected results.")); + WindowPrompt(tr("Error"),nipple,NULL,NULL,NULL,NULL,170); + } + } + + } + + wiilight(0); + if (isInserted(bootDevice)) { + //////////save game play count//////////////// + struct Game_NUM* game_num = CFG_get_game_num(header->id); + + if (game_num) { + favoritevar = game_num->favorite; + playcount = game_num->count; + } else { + favoritevar = 0; + playcount = 0; + } + playcount += 1; + + CFG_save_game_num(header->id); + gprintf("\n\tplaycount for %c%c%c%c%c%c raised to %i",header->id[0],header->id[1],header->id[2],header->id[3],header->id[4],header->id[5],playcount); + + } + menu = MENU_EXIT; + break; + + } + bool returnHere = true;// prompt to start game + while (returnHere) { + returnHere = false; + if (Settings.wiilight != wiilight_forInstall) wiilight(1); + choice = GameWindowPrompt(); + // header = &gameList[gameSelected]; //reset header + + if (choice == 1) { + if (alternatedol == on) { + /* Open dol File and check exist */ + sprintf(nipple, "%s%s.dol",Settings.dolpath,IDfull); + exeFile = fopen (nipple ,"rb"); + if (exeFile==NULL) { + gprintf("\n\tTried to load alt dol that isn't there"); + sprintf(nipple, "%s %s",nipple,tr("does not exist! You Messed something up, Idiot.")); + WindowPrompt(tr("Error"),nipple,tr("OK")); + menu = MENU_CHECK; + wiilight(0); + break; + } else { + fclose(exeFile); + } + } + if (ocarinaChoice != off) { + /* Open gct File and check exist */ + sprintf(nipple, "%s%s.gct",Settings.Cheatcodespath,IDfull); + exeFile = fopen (nipple ,"rb"); + if (exeFile==NULL) { + gprintf("\n\ttried to load gct file that isn't there"); + sprintf(nipple, "%s %s",nipple,tr("does not exist! Loading game without cheats.")); + WindowPrompt(tr("Error"),nipple,NULL,NULL,NULL,NULL,170); + } else { + fseek (exeFile, 0, SEEK_END); + long size=ftell (exeFile); + rewind (exeFile); + fclose(exeFile); + if (size>MAX_GCT_SIZE) { + gprintf("\n\tgct file is too big"); + sprintf(nipple, "%s %s",nipple,tr("contains over 255 lines of code. It will produce unexpected results.")); + WindowPrompt(tr("Error"),nipple,NULL,NULL,NULL,NULL,170); + } + } + + } + wiilight(0); + returnHere = false; + menu = MENU_EXIT; + + } else if (choice == 2) { + wiilight(0); + HaltGui(); + if (Settings.gameDisplay==list) mainWindow->Remove(gameBrowser); + else if (Settings.gameDisplay==grid) mainWindow->Remove(gameGrid); + else if (Settings.gameDisplay==carousel) mainWindow->Remove(gameCarousel); + mainWindow->Remove(&w); + ResumeGui(); + + //re-evaluate header now in case they changed games while on the game prompt + header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); + int settret = GameSettings(header); + /* unneeded for now, kept in case database gets a separate language setting + //menu = MENU_DISCLIST; // refresh titles (needed if the language setting has changed) + */ + HaltGui(); + if (Settings.gameDisplay==list) mainWindow->Append(gameBrowser); + else if (Settings.gameDisplay==grid) mainWindow->Append(gameGrid); + else if (Settings.gameDisplay==carousel) mainWindow->Append(gameCarousel); + mainWindow->Append(&w); + ResumeGui(); + if (settret == 1) { //if deleted + menu = MENU_DISCLIST; + break; + } + returnHere = true; + rockout(2); + } + + else if (choice == 3 && !mountMethod) { //WBFS renaming + wiilight(0); + //re-evaluate header now in case they changed games while on the game prompt + header = &gameList[gameSelected]; + + //enter new game title + char entered[60]; + snprintf(entered, sizeof(entered), "%s", get_title(header)); + entered[59] = '\0'; + int result = OnScreenKeyboard(entered, 60,0); + if (result == 1) { + WBFS_RenameGame(header->id, entered); + __Menu_GetEntries(); + menu = MENU_DISCLIST; + } + } else if (choice == 0) { + rockout(2); + if (mountMethod==1||mountMethod==2)mountMethod = mountMethodOLD; + if (Settings.gameDisplay==list) { + gameBrowser->SetFocus(1); + } else if (Settings.gameDisplay==grid) { + gameGrid->SetFocus(1); + } else if (Settings.gameDisplay==carousel) { + gameCarousel->SetFocus(1); + } + } + + + } + if(searchBar) + { + HaltGui(); + mainWindow->Append(searchBar); + ResumeGui(); + } + } + // to skip the first call of windowScreensaver at startup when wiimote is not connected + if (IsWpadConnected()) { + check = 1; + } + + // screensaver is called when wiimote shuts down, depending on the wiimotet idletime + if (!IsWpadConnected() && check !=0 && Settings.screensaver!=0) { + check++; + int screensaverIsOn=0; + if (check==11500) { //to allow time for the wii to turn off and not show the screensaver + screensaverIsOn=WindowScreensaver(); + } + if (screensaverIsOn==1)check=0; + } + covertOld=covert; + } + + // set alt dol default + if (menu == MENU_EXIT && altdoldefault) { + struct discHdr *header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); + struct Game_CFG* game_cfg = CFG_get_game_opt(header->id); + // use default only if no alt dol was selected manually + if (game_cfg) { + if (game_cfg->alternatedolstart != 0) + altdoldefault = false; + } + if (altdoldefault) { + int autodol = autoSelectDol((char*)header->id, true); + if (autodol>0) { + alternatedol = 2; + alternatedoloffset = autodol; + char temp[20]; + sprintf(temp,"%d",autodol); + } else { + // alt dol menu for games that require more than a single alt dol + int autodol = autoSelectDolMenu((char*)header->id, true); + if (autodol>0) { + alternatedol = 2; + alternatedoloffset = autodol; + } + } + } + } + + if (menu == MENU_EXIT) { + SDCard_deInit(); + } + + HaltGui(); + mainWindow->RemoveAll(); + mainWindow->Append(bgImg); + delete searchBar; + searchBar = NULL; + delete gameBrowser; + gameBrowser = NULL; + delete gameGrid; + gameGrid = NULL; + delete gameCarousel; + gameCarousel = NULL; + ResumeGui(); + return menu; +} + +void DiscListWinUpdateCallback(void * e) +{ + GuiWindow *w = (GuiWindow *)e; + for(int i=0; i<8; ++i) + { + if(Toolbar[i]->GetState() == STATE_SELECTED) + { + w->Remove(Toolbar[i]); + w->Append(Toolbar[i]); // draw the selected Icon allways on top + break; + } + } +} + +void rockout(int f) { + + + HaltGui(); + int num=(f==2?-1:gameSelected); + + char imgPath[100]; +#ifdef HW_RVL + if ((!(strcasestr(get_title(&gameList[num]),"guitar")|| + strcasestr(get_title(&gameList[num]),"band")|| + strcasestr(get_title(&gameList[num]),"rock")|| + f==1))||mountMethod) { + for (int i = 0; i < 4; i++) + delete pointer[i]; + snprintf(imgPath, sizeof(imgPath), "%splayer1_point.png", CFG.theme_path); + pointer[0] = new GuiImageData(imgPath, player1_point_png); + snprintf(imgPath, sizeof(imgPath), "%splayer2_point.png", CFG.theme_path); + pointer[1] = new GuiImageData(imgPath, player2_point_png); + snprintf(imgPath, sizeof(imgPath), "%splayer3_point.png", CFG.theme_path); + pointer[2] = new GuiImageData(imgPath, player3_point_png); + snprintf(imgPath, sizeof(imgPath), "%splayer4_point.png", CFG.theme_path); + pointer[3] = new GuiImageData(imgPath, player4_point_png); + } else { + + for (int i = 0; i < 4; i++) + delete pointer[i]; + snprintf(imgPath, sizeof(imgPath), "%srplayer1_point.png", CFG.theme_path); + pointer[0] = new GuiImageData(imgPath, rplayer1_point_png); + snprintf(imgPath, sizeof(imgPath), "%srplayer2_point.png", CFG.theme_path); + pointer[1] = new GuiImageData(imgPath, rplayer2_point_png); + snprintf(imgPath, sizeof(imgPath), "%srplayer3_point.png", CFG.theme_path); + pointer[2] = new GuiImageData(imgPath, rplayer3_point_png); + snprintf(imgPath, sizeof(imgPath), "%srplayer4_point.png", CFG.theme_path); + pointer[3] = new GuiImageData(imgPath, rplayer4_point_png); + } +#endif + ResumeGui(); +} diff --git a/source/menu/menu_format.cpp b/source/menu/menu_format.cpp new file mode 100644 index 00000000..a7ae8886 --- /dev/null +++ b/source/menu/menu_format.cpp @@ -0,0 +1,188 @@ +#include + +#include "menus.h" +#include "fatmounter.h" +#include "usbloader/usbstorage.h" +#include "usbloader/utils.h" +#include "usbloader/wbfs.h" +#include "libwiigui/gui_customoptionbrowser.h" + +extern bool load_from_fat; +extern char game_partition[6]; + +/**************************************************************************** + * MenuFormat + ***************************************************************************/ +int MenuFormat() { + + USBDevice_deInit(); + sleep(1); + + USBStorage_Init(); + + int menu = MENU_NONE; + char imgPath[100]; + + customOptionList options(MAX_PARTITIONS_EX); + extern PartList partitions; + + u32 cnt, counter = 0; + int choice, ret; + char text[ISFS_MAXPATH]; + + //create the partitionlist + for (cnt = 0; cnt < (u32) partitions.num; cnt++) { + partitionEntry *entry = &partitions.pentry[cnt]; + if (load_from_fat && partitions.pinfo[cnt].fs_type != FS_TYPE_FAT32) { + continue; // Skip non FAT partitions when fat loading is enabled. + } + + /* Calculate size in gigabytes */ + f32 size = entry->size * (partitions.sector_size / GB_SIZE); + + if (size) { + options.SetName(counter, "%s %d:",tr("Partition"), cnt+1); + options.SetValue(counter,"%.2fGB", size); + } else { + options.SetName(counter, "%s %d:",tr("Partition"), cnt+1); + options.SetValue(counter,tr("Can't be formatted")); + } + counter++; + } + + GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); + // because destroy GuiSound must wait while sound playing is finished, we use a global sound + if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); + // GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); + snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff.png", CFG.theme_path); + GuiImageData btnpwroff(imgPath, wiimote_poweroff_png); + snprintf(imgPath, sizeof(imgPath), "%swiimote_poweroff_over.png", CFG.theme_path); + GuiImageData btnpwroffOver(imgPath, wiimote_poweroff_over_png); + snprintf(imgPath, sizeof(imgPath), "%smenu_button.png", CFG.theme_path); + GuiImageData btnhome(imgPath, menu_button_png); + snprintf(imgPath, sizeof(imgPath), "%smenu_button_over.png", CFG.theme_path); + GuiImageData btnhomeOver(imgPath, menu_button_over_png); + GuiImageData battery(battery_png); + GuiImageData batteryBar(battery_bar_png); + GuiImageData batteryRed(battery_red_png); + GuiImageData batteryBarRed(battery_bar_red_png); + + + GuiTrigger trigA; + trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + GuiTrigger trigHome; + trigHome.SetButtonOnlyTrigger(-1, WPAD_BUTTON_HOME | WPAD_CLASSIC_BUTTON_HOME, 0); + + GuiImage poweroffBtnImg(&btnpwroff); + GuiImage poweroffBtnImgOver(&btnpwroffOver); + poweroffBtnImg.SetWidescreen(CFG.widescreen); + poweroffBtnImgOver.SetWidescreen(CFG.widescreen); + GuiButton poweroffBtn(&poweroffBtnImg,&poweroffBtnImgOver, 0, 3, THEME.power_x, THEME.power_y, &trigA, &btnSoundOver, btnClick2,1); + GuiImage exitBtnImg(&btnhome); + GuiImage exitBtnImgOver(&btnhomeOver); + exitBtnImg.SetWidescreen(CFG.widescreen); + exitBtnImgOver.SetWidescreen(CFG.widescreen); + GuiButton exitBtn(&exitBtnImg,&exitBtnImgOver, 0, 3, THEME.home_x, THEME.home_y, &trigA, &btnSoundOver, btnClick2,1); + exitBtn.SetTrigger(&trigHome); + + GuiCustomOptionBrowser optionBrowser(396, 280, &options, CFG.theme_path, "bg_options_settings.png", bg_options_settings_png, 0, 10); + optionBrowser.SetPosition(0, 40); + optionBrowser.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); + + HaltGui(); + GuiWindow w(screenwidth, screenheight); + w.Append(&poweroffBtn); + w.Append(&exitBtn); + + mainWindow->Append(&w); + mainWindow->Append(&optionBrowser); + + ResumeGui(); + + while (menu == MENU_NONE) { + + VIDEO_WaitVSync (); + + ret = optionBrowser.GetClickedOption(); + + if(ret >= 0) { + if(Settings.godmode == 1) { + partitionEntry *entry = &partitions.pentry[ret]; + if (entry->size) { + if (load_from_fat) { + WBFS_OpenPart(1, partitions.pinfo[ret].fat_i, entry->sector, + entry->size, (char *) &game_partition); + load_from_fat = true; + menu = MENU_DISCLIST; + + Settings.partition = ret; + cfg_save_global(); + } else { + sprintf(text, "%s %d : %.2fGB",tr("Partition"), ret+1, entry->size * (partitions.sector_size / GB_SIZE)); + choice = WindowPrompt( tr("Do you want to format:"), text,tr("Yes"),tr("No")); + if (choice == 1) { + ret = FormatingPartition(tr("Formatting, please wait..."), entry); + if (ret < 0) { + WindowPrompt(tr("Error !"),tr("Failed formating"),tr("Return")); + menu = MENU_SETTINGS; + } else { + sleep(1); + ret = WBFS_Open(); + sprintf(text, "%s %s", text,tr("formatted!")); + WindowPrompt(tr("Success:"),text,tr("OK")); + if(ret < 0) { + WindowPrompt(tr("ERROR"), tr("Failed to open partition"), tr("OK")); + Sys_LoadMenu(); + } + menu = MENU_DISCLIST; + } + } + } + } else if(Settings.godmode == 0) { + mainWindow->Remove(&optionBrowser); + char entered[20] = ""; + int result = OnScreenKeyboard(entered, 20,0); + mainWindow->Append(&optionBrowser); + if ( result == 1 ) { + if (!strcmp(entered, Settings.unlockCode)) { //if password correct + if (Settings.godmode == 0) { + WindowPrompt(tr("Correct Password"),tr("All the features of USB Loader GX are unlocked."),tr("OK")); + Settings.godmode = 1; + } + } else { + WindowPrompt(tr("Wrong Password"),tr("USB Loader GX is protected"),tr("OK")); + } + } + } + } + } + + if (shutdown == 1) + Sys_Shutdown(); + if (reset == 1) + Sys_Reboot(); + + if (poweroffBtn.GetState() == STATE_CLICKED) { + choice = WindowPrompt (tr("Shutdown System"),tr("Are you sure?"),tr("Yes"),tr("No")); + if (choice == 1) { + Sys_Shutdown(); + } + + } else if (exitBtn.GetState() == STATE_CLICKED) { + choice = WindowPrompt (tr("Return to Wii Menu"),tr("Are you sure?"),tr("Yes"),tr("No")); + if (choice == 1) { + Sys_LoadMenu(); + } + } + } + + + HaltGui(); + + mainWindow->Remove(&optionBrowser); + mainWindow->Remove(&w); + ResumeGui(); + + return menu; +} + diff --git a/source/menu/menu_install.cpp b/source/menu/menu_install.cpp new file mode 100644 index 00000000..dba46fa0 --- /dev/null +++ b/source/menu/menu_install.cpp @@ -0,0 +1,154 @@ +#include "menus.h" +#include "usbloader/usbstorage.h" +#include "usbloader/wbfs.h" +#include "usbloader/disc.h" +#include "usbloader/utils.h" +#include "usbloader/getentries.h" +#include "prompts/ProgressWindow.h" + +/**************************************************************************** + * MenuInstall + ***************************************************************************/ + +int MenuInstall() { + gprintf("\nMenuInstall()"); + + int menu = MENU_NONE; + static struct discHdr headerdisc ATTRIBUTE_ALIGN(32); + + Disc_SetUSB(NULL); + + int ret, choice = 0; + char name[200]; + + GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); + + char imgPath[100]; + + snprintf(imgPath, sizeof(imgPath), "%sbattery.png", CFG.theme_path); + GuiImageData battery(imgPath, battery_png); + snprintf(imgPath, sizeof(imgPath), "%sbattery_bar.png", CFG.theme_path); + GuiImageData batteryBar(imgPath, battery_bar_png); + snprintf(imgPath, sizeof(imgPath), "%sbattery_red.png", CFG.theme_path); + GuiImageData batteryRed(imgPath, battery_red_png); + snprintf(imgPath, sizeof(imgPath), "%sbattery_bar_red.png", CFG.theme_path); + GuiImageData batteryBarRed(imgPath, battery_bar_red_png); + + HaltGui(); + GuiWindow w(screenwidth, screenheight); + + mainWindow->Append(&w); + + ResumeGui(); + + while (menu == MENU_NONE) { + VIDEO_WaitVSync (); + + ret = DiscWait(tr("Insert Disk"),tr("Waiting..."),tr("Cancel"),0,0); + if (ret < 0) { + WindowPrompt (tr("Error reading Disc"),0,tr("Back")); + menu = MENU_DISCLIST; + break; + } + ret = Disc_Open(); + if (ret < 0) { + WindowPrompt (tr("Could not open Disc"),0,tr("Back")); + menu = MENU_DISCLIST; + break; + } + + ret = Disc_IsWii(); + if (ret < 0) { + choice = WindowPrompt (tr("Not a Wii Disc"),tr("Insert a Wii Disc!"),tr("OK"),tr("Back")); + + if (choice == 1) { + menu = MENU_INSTALL; + break; + } else + menu = MENU_DISCLIST; + break; + } + + Disc_ReadHeader(&headerdisc); + snprintf(name, sizeof(name), "%s", headerdisc.title); + + ret = WBFS_CheckGame(headerdisc.id); + if (ret) { + WindowPrompt (tr("Game is already installed:"),name,tr("Back")); + menu = MENU_DISCLIST; + break; + } + + f32 freespace, used; + + WBFS_DiskSpace(&used, &freespace); + float gamesize = WBFS_EstimeGameSize()/GB_SIZE; + + char gametxt[50]; + + sprintf(gametxt, "%s : %.2fGB", name, gamesize); + + wiilight(1); + choice = WindowPrompt(tr("Continue to install game?"),gametxt,tr("OK"),tr("Cancel")); + + if (choice == 1) { + + sprintf(gametxt, "%s", tr("Installing game:")); + + if (gamesize > freespace) { + char errortxt[50]; + sprintf(errortxt, "%s: %.2fGB, %s: %.2fGB",tr("Game Size"), gamesize, tr("Free Space"), freespace); + WindowPrompt(tr("Not enough free space!"),errortxt,tr("OK")); + menu = MENU_DISCLIST; + break; + } else { + USBStorage_Watchdog(0); + SetupGameInstallProgress(gametxt, name); + ret = WBFS_AddGame(); + ProgressStop(); + USBStorage_Watchdog(1); + wiilight(0); + if (ret != 0) { + WindowPrompt(tr("Install Error!"),0,tr("Back")); + menu = MENU_DISCLIST; + break; + } else { + __Menu_GetEntries(); //get the entries again + GuiSound * instsuccess = NULL; + bgMusic->Pause(); + instsuccess = new GuiSound(success_ogg, success_ogg_size, Settings.sfxvolume); + instsuccess->SetVolume(Settings.sfxvolume); + instsuccess->SetLoop(0); + instsuccess->Play(); + WindowPrompt (tr("Successfully installed:"),name,tr("OK")); + instsuccess->Stop(); + delete instsuccess; + bgMusic->Resume(); + menu = MENU_DISCLIST; + break; + } + } + } else { + menu = MENU_DISCLIST; + break; + } + + if (shutdown == 1) { + wiilight(0); + Sys_Shutdown(); + } + if (reset == 1) { + wiilight(0); + Sys_Reboot(); + } + } + + //Turn off the WiiLight + wiilight(0); + + HaltGui(); + + mainWindow->Remove(&w); + ResumeGui(); + return menu; +} diff --git a/source/menu/menus.h b/source/menu/menus.h new file mode 100644 index 00000000..269d998e --- /dev/null +++ b/source/menu/menus.h @@ -0,0 +1,24 @@ +#ifndef _MENUS_H +#define _MENUS_H + +#include "libwiigui/gui.h" +#include "language/gettext.h" +#include "prompts/PromptWindows.h" +#include "menu.h" +#include "gecko.h" +#include "filelist.h" +#include "sys.h" + +extern void ResumeGui(); +extern void HaltGui(); +extern GuiWindow * mainWindow; +extern GuiSound * bgMusic; +extern u8 shutdown; +extern u8 reset; + +int MenuInstall(); +int MenuDiscList(); +int MenuFormat(); +int MenuCheck(); + +#endif // _MENUS_H diff --git a/source/mload/ehcmodule.c b/source/mload/ehcmodule.c deleted file mode 100644 index e010289a..00000000 --- a/source/mload/ehcmodule.c +++ /dev/null @@ -1,1171 +0,0 @@ -#define size_ehcmodule 32432 - -unsigned char ehcmodule[32432] __attribute__((aligned (32)))={ - 127, 69, 76, 70, 1, 2, 1, 97, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 40, 0, 0, 0, 1, 19, 112, 0, 0, 0, 0, 0, 52, 0, 0, 0, - 0, 0, 0, 6, 6, 0, 52, 0, 32, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, - 0, 0, 0, 160, 0, 240, 0, 0, 0, 0, 0, 4, 0, 0, 0, 4, 0, 0, 0, 212, 0, 0, 0, 160, 0, 0, 0, 160, 0, 0, 0, 52, 0, 0, 0, - 52, 0, 240, 0, 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, 0, 0, 0, 212, 0, 240, 0, - 0, 0, 0, 64, 0, 0, 0, 0, 1, 0, 0, 1, 8, 19, 112, 0, 0, 19, 112, 0, 0, 0, 0, 117, 188, 0, 0, 117, 188, 0, 0, 0, 5, 0, - 0, 0, 4, 0, 0, 0, 1, 0, 0, 118, 196, 19, 112, 128, 0, 19, 112, 128, 0, 0, 0, 7, 236, 0, 3, 38, 72, 0, 0, 0, 6, 0, 0, - 0, 4, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 6, 0, 0, 0, 11, 0, 0, 0, 4, 0, 0, 0, 9, 19, 112, 0, 0, 0, 0, 0, 125, 0, 0, 0, - 120, 0, 0, 0, 126, 0, 0, 48, 0, 0, 0, 0, 127, 19, 115, 164, 72, 227, 160, 0, 0, 227, 160, 16, 0, 229, 159, 48, 204, - 225, 47, 255, 19, 229, 159, 192, 200, 229, 156, 192, 0, 225, 160, 0, 0, 231, 156, 193, 11, 225, 160, 0, 0, 225, 47, - 255, 28, 225, 160, 0, 0, 225, 160, 0, 0, 227, 160, 176, 63, 234, 255, 255, 245, 225, 160, 0, 0, 225, 160, 0, 0, 227, - 160, 176, 64, 234, 255, 255, 241, 227, 160, 0, 0, 238, 7, 15, 21, 225, 47, 255, 30, 225, 160, 0, 0, 225, 160, 0, 0, - 225, 160, 0, 0, 227, 24, 0, 16, 10, 0, 0, 18, 227, 200, 128, 16, 227, 160, 32, 16, 229, 135, 32, 0, 225, 160, 0, 0, - 225, 160, 32, 13, 225, 160, 0, 0, 229, 159, 208, 92, 225, 160, 0, 0, 233, 45, 95, 254, 225, 160, 0, 0, 235, 0, 0, 15, - 232, 189, 95, 254, 225, 160, 0, 0, 225, 160, 208, 2, 227, 16, 0, 1, 10, 0, 0, 2, 225, 160, 0, 0, 227, 160, 0, 4, 235, - 0, 0, 5, 227, 24, 0, 1, 10, 0, 0, 1, 229, 159, 240, 36, 225, 160, 0, 0, 229, 159, 240, 32, 225, 160, 0, 0, 229, 159, - 240, 28, 225, 160, 0, 0, 229, 159, 32, 24, 225, 47, 255, 18, 19, 112, 11, 25, 19, 115, 112, 160, 19, 115, 166, 72, 255, - 255, 30, 128, 255, 255, 30, 156, 255, 255, 29, 68, 19, 112, 9, 49, 225, 160, 0, 0, 225, 160, 0, 0, 70, 192, 71, 120, - 234, 0, 28, 5, 70, 192, 71, 120, 234, 0, 28, 49, 70, 192, 71, 120, 234, 0, 28, 11, 70, 192, 71, 120, 234, 0, 28, 39, - 70, 192, 71, 120, 234, 0, 27, 227, 70, 192, 71, 120, 234, 0, 27, 245, 70, 192, 71, 120, 234, 255, 255, 189, 70, 192, - 71, 120, 234, 0, 27, 223, 70, 192, 71, 120, 234, 0, 27, 207, 70, 192, 71, 120, 234, 255, 255, 187, 70, 192, 71, 120, - 234, 255, 255, 187, 70, 192, 71, 120, 234, 0, 27, 191, 70, 192, 71, 120, 234, 0, 27, 241, 70, 192, 71, 120, 234, 0, - 28, 23, 70, 192, 71, 120, 234, 255, 255, 212, 70, 192, 71, 120, 234, 0, 27, 239, 70, 192, 71, 120, 234, 0, 28, 23, 70, - 192, 71, 120, 234, 0, 27, 213, 70, 192, 71, 120, 234, 0, 27, 217, 70, 192, 71, 120, 234, 0, 27, 219, 70, 192, 71, 120, - 234, 0, 27, 211, 70, 192, 71, 120, 234, 0, 27, 207, 70, 192, 71, 120, 234, 0, 27, 201, 70, 192, 71, 120, 234, 0, 28, - 1, 181, 240, 28, 15, 120, 1, 28, 6, 28, 10, 58, 48, 6, 19, 14, 27, 36, 0, 28, 69, 43, 9, 216, 11, 1, 35, 28, 28, 67, - 20, 28, 40, 120, 1, 28, 69, 28, 10, 58, 48, 6, 19, 14, 27, 43, 9, 217, 243, 28, 11, 59, 97, 6, 27, 14, 27, 43, 5, 216, - 6, 1, 34, 28, 11, 59, 87, 28, 20, 67, 28, 28, 40, 231, 234, 28, 11, 59, 65, 6, 27, 14, 27, 43, 5, 217, 6, 28, 115, 66, - 157, 208, 10, 96, 60, 188, 240, 188, 2, 71, 8, 1, 34, 28, 11, 59, 55, 28, 20, 67, 28, 28, 40, 231, 214, 32, 0, 231, - 243, 70, 192, 181, 0, 75, 4, 176, 129, 28, 1, 104, 24, 247, 255, 255, 153, 176, 1, 188, 1, 71, 0, 19, 112, 128, 32, - 181, 0, 75, 9, 28, 1, 176, 129, 104, 24, 247, 255, 255, 129, 40, 0, 208, 2, 176, 1, 188, 2, 71, 8, 72, 4, 247, 255, - 255, 137, 32, 100, 240, 0, 253, 120, 231, 251, 70, 192, 19, 112, 128, 32, 19, 112, 128, 68, 181, 240, 70, 95, 70, 86, - 70, 77, 70, 68, 180, 240, 75, 206, 176, 151, 104, 24, 33, 128, 247, 255, 255, 100, 33, 32, 247, 255, 255, 77, 144, 16, - 240, 0, 251, 250, 247, 255, 255, 76, 33, 120, 247, 255, 255, 57, 72, 199, 153, 16, 144, 11, 247, 255, 255, 44, 72, 197, - 154, 16, 28, 1, 35, 0, 247, 255, 255, 110, 74, 195, 33, 0, 75, 195, 144, 13, 145, 14, 72, 195, 145, 15, 145, 17, 145, - 18, 145, 19, 146, 10, 73, 193, 74, 193, 147, 9, 70, 131, 145, 8, 146, 7, 75, 192, 72, 192, 73, 193, 74, 193, 36, 1, - 147, 6, 144, 5, 145, 4, 146, 12, 152, 16, 169, 21, 34, 0, 247, 255, 255, 87, 44, 0, 209, 45, 156, 10, 35, 0, 96, 35, - 156, 21, 44, 0, 208, 48, 120, 35, 120, 98, 6, 27, 4, 18, 67, 26, 120, 163, 2, 27, 67, 19, 120, 226, 67, 26, 42, 2, 209, - 0, 224, 253, 42, 2, 216, 74, 42, 1, 209, 0, 224, 209, 39, 1, 66, 127, 38, 1, 70, 89, 104, 11, 43, 0, 208, 0, 224, 195, - 36, 0, 46, 0, 208, 213, 152, 21, 28, 57, 247, 255, 254, 226, 152, 16, 169, 21, 34, 0, 247, 255, 255, 41, 44, 0, 208, - 209, 152, 13, 247, 255, 254, 224, 156, 10, 35, 0, 96, 35, 156, 21, 44, 0, 209, 206, 152, 9, 104, 3, 43, 0, 208, 1, 70, - 89, 96, 12, 154, 15, 42, 0, 209, 0, 224, 228, 70, 92, 104, 35, 43, 0, 209, 0, 224, 223, 152, 8, 104, 3, 43, 0, 209, - 0, 225, 171, 240, 4, 252, 84, 40, 0, 208, 5, 240, 4, 252, 80, 40, 0, 208, 1, 240, 4, 252, 76, 153, 8, 104, 11, 43, 0, - 209, 0, 225, 156, 152, 13, 73, 132, 247, 255, 254, 231, 36, 1, 231, 152, 42, 6, 209, 0, 224, 170, 42, 7, 209, 178, 126, - 35, 126, 98, 6, 27, 4, 18, 67, 26, 126, 163, 2, 27, 67, 19, 126, 226, 67, 26, 70, 146, 124, 35, 124, 98, 6, 27, 4, 18, - 67, 26, 124, 163, 2, 27, 67, 19, 124, 226, 67, 26, 70, 145, 125, 35, 125, 98, 6, 27, 4, 18, 67, 26, 125, 163, 2, 27, - 67, 19, 125, 226, 28, 21, 67, 29, 123, 35, 43, 0, 208, 0, 224, 153, 155, 17, 43, 0, 208, 0, 224, 149, 122, 35, 122, - 98, 6, 27, 4, 18, 67, 26, 122, 163, 122, 224, 2, 27, 67, 19, 67, 24, 240, 0, 254, 1, 28, 6, 68, 77, 0, 233, 70, 80, - 70, 168, 247, 255, 254, 144, 45, 0, 221, 9, 70, 84, 37, 0, 104, 32, 104, 97, 53, 1, 247, 255, 254, 135, 52, 8, 69, 168, - 220, 247, 153, 21, 76, 101, 123, 11, 123, 74, 6, 27, 4, 18, 67, 26, 123, 139, 2, 27, 67, 19, 123, 202, 67, 26, 66, 162, - 209, 0, 225, 202, 66, 162, 216, 119, 42, 6, 217, 0, 224, 145, 42, 5, 211, 0, 225, 12, 42, 1, 209, 0, 225, 130, 42, 0, - 209, 0, 225, 81, 42, 2, 209, 0, 225, 3, 39, 1, 38, 1, 69, 193, 219, 0, 231, 72, 70, 76, 0, 227, 70, 80, 24, 196, 70, - 77, 104, 32, 104, 97, 53, 1, 247, 255, 254, 37, 52, 8, 69, 168, 220, 247, 70, 89, 104, 11, 43, 0, 209, 0, 231, 59, 152, - 13, 73, 63, 247, 255, 254, 93, 36, 1, 231, 54, 123, 35, 123, 98, 6, 27, 4, 18, 67, 26, 123, 163, 153, 11, 2, 27, 67, - 19, 123, 226, 28, 21, 67, 29, 28, 40, 240, 6, 255, 230, 40, 0, 209, 51, 125, 35, 125, 98, 6, 27, 4, 18, 67, 26, 125, - 163, 2, 27, 67, 19, 125, 226, 28, 23, 154, 18, 67, 31, 42, 0, 209, 0, 224, 171, 35, 1, 147, 18, 38, 1, 231, 12, 39, - 1, 38, 1, 231, 9, 122, 35, 122, 98, 6, 27, 4, 18, 67, 26, 122, 163, 153, 17, 2, 27, 67, 19, 122, 226, 28, 16, 67, 24, - 66, 129, 209, 8, 34, 0, 146, 17, 39, 0, 38, 1, 230, 246, 38, 0, 231, 116, 36, 0, 230, 208, 240, 0, 253, 113, 240, 0, - 253, 101, 39, 0, 38, 1, 230, 235, 152, 17, 40, 0, 208, 76, 39, 6, 66, 127, 38, 1, 230, 228, 72, 34, 66, 130, 209, 0, - 224, 146, 66, 130, 217, 0, 224, 126, 75, 31, 66, 154, 209, 0, 225, 45, 66, 154, 210, 0, 225, 27, 51, 1, 66, 154, 209, - 0, 225, 51, 51, 2, 66, 154, 209, 129, 152, 12, 39, 0, 104, 3, 38, 1, 66, 90, 65, 83, 96, 3, 231, 123, 42, 12, 209, 0, - 224, 237, 42, 12, 210, 0, 231, 115, 28, 19, 59, 26, 43, 1, 217, 0, 231, 110, 39, 1, 38, 0, 231, 109, 19, 112, 128, 32, - 19, 112, 128, 96, 0, 152, 150, 128, 19, 112, 136, 92, 19, 112, 135, 240, 19, 112, 128, 12, 19, 112, 136, 8, 19, 115, - 116, 64, 19, 112, 136, 160, 19, 115, 116, 68, 19, 112, 128, 108, 19, 112, 135, 236, 85, 77, 83, 1, 85, 77, 83, 16, 85, - 77, 83, 3, 28, 40, 153, 4, 34, 10, 240, 6, 254, 147, 40, 0, 209, 171, 125, 35, 125, 98, 6, 27, 4, 18, 67, 26, 28, 46, - 125, 163, 54, 10, 28, 49, 2, 27, 67, 19, 125, 226, 120, 12, 28, 23, 28, 34, 58, 48, 67, 31, 6, 19, 14, 27, 37, 0, 28, - 72, 43, 9, 216, 11, 1, 43, 28, 29, 67, 21, 28, 1, 120, 12, 28, 72, 28, 34, 58, 48, 6, 19, 14, 27, 43, 9, 217, 243, 28, - 35, 59, 97, 6, 27, 14, 27, 43, 5, 216, 36, 1, 42, 28, 35, 59, 87, 28, 21, 67, 29, 28, 1, 231, 234, 36, 1, 240, 2, 255, - 216, 38, 1, 148, 18, 230, 94, 75, 165, 66, 154, 209, 0, 224, 151, 66, 154, 217, 0, 224, 238, 59, 1, 66, 154, 208, 0, - 231, 5, 70, 81, 104, 11, 70, 90, 104, 27, 96, 19, 230, 255, 35, 0, 70, 90, 96, 19, 147, 15, 39, 0, 38, 1, 230, 250, - 28, 35, 59, 65, 6, 27, 14, 27, 43, 5, 216, 0, 224, 207, 28, 115, 66, 152, 209, 0, 231, 82, 41, 0, 209, 0, 231, 79, 44, - 47, 208, 0, 231, 76, 169, 20, 247, 255, 253, 117, 40, 0, 209, 0, 231, 70, 120, 3, 43, 0, 208, 0, 231, 66, 28, 58, 153, - 20, 28, 40, 240, 0, 252, 105, 38, 1, 28, 7, 230, 35, 154, 7, 104, 19, 74, 135, 59, 1, 66, 147, 217, 0, 230, 91, 156, - 10, 35, 1, 96, 35, 152, 14, 33, 1, 154, 6, 240, 4, 252, 199, 35, 0, 96, 35, 40, 0, 208, 8, 154, 7, 32, 128, 4, 64, 104, - 17, 240, 6, 253, 109, 155, 14, 24, 27, 147, 14, 156, 5, 152, 14, 104, 35, 66, 131, 217, 0, 230, 64, 33, 0, 145, 14, - 230, 61, 46, 0, 208, 39, 70, 81, 105, 11, 70, 82, 136, 24, 105, 139, 136, 28, 106, 11, 136, 29, 104, 11, 120, 25, 104, - 147, 120, 26, 2, 3, 10, 0, 67, 3, 2, 32, 10, 36, 67, 32, 4, 0, 12, 0, 144, 0, 2, 40, 10, 45, 67, 40, 4, 0, 12, 0, 144, - 1, 70, 84, 107, 32, 4, 27, 144, 2, 12, 27, 28, 48, 240, 2, 251, 24, 38, 1, 28, 7, 230, 138, 46, 0, 208, 87, 39, 6, 66, - 127, 38, 1, 230, 132, 46, 0, 208, 249, 70, 80, 104, 3, 120, 25, 104, 131, 136, 26, 105, 3, 28, 48, 240, 2, 250, 240, - 38, 1, 28, 7, 230, 118, 70, 84, 104, 35, 152, 9, 104, 27, 39, 0, 96, 3, 38, 1, 230, 110, 152, 7, 240, 0, 252, 150, 153, - 5, 70, 83, 96, 8, 104, 26, 28, 7, 42, 0, 208, 221, 156, 7, 38, 1, 104, 35, 96, 19, 230, 95, 70, 80, 104, 3, 70, 81, - 104, 24, 104, 139, 38, 1, 104, 25, 70, 83, 105, 26, 240, 4, 252, 83, 28, 7, 230, 82, 70, 84, 104, 35, 105, 34, 104, - 24, 104, 163, 38, 1, 104, 25, 240, 4, 251, 32, 28, 7, 230, 71, 240, 5, 250, 244, 28, 7, 40, 0, 219, 96, 32, 1, 70, 89, - 96, 8, 144, 15, 153, 21, 38, 1, 122, 11, 122, 74, 6, 27, 4, 18, 67, 26, 122, 139, 2, 27, 67, 19, 122, 202, 67, 26, 146, - 17, 230, 48, 70, 81, 104, 11, 38, 1, 120, 24, 104, 139, 120, 25, 70, 83, 105, 26, 105, 155, 240, 0, 252, 0, 28, 7, 230, - 35, 1, 42, 28, 35, 59, 55, 28, 21, 67, 29, 28, 1, 230, 238, 76, 44, 66, 162, 208, 23, 72, 43, 66, 130, 208, 0, 230, - 19, 152, 19, 40, 0, 208, 51, 70, 81, 104, 11, 104, 25, 70, 83, 105, 26, 104, 155, 104, 27, 240, 5, 253, 50, 28, 7, 40, - 0, 209, 0, 231, 126, 39, 128, 2, 63, 38, 1, 230, 1, 122, 11, 122, 74, 6, 27, 4, 18, 67, 26, 122, 139, 70, 84, 2, 27, - 67, 19, 122, 202, 67, 26, 35, 0, 146, 17, 147, 20, 104, 227, 43, 4, 208, 21, 70, 81, 104, 8, 153, 20, 240, 5, 252, 24, - 144, 19, 40, 0, 208, 26, 35, 1, 70, 92, 96, 35, 147, 15, 39, 0, 38, 1, 229, 225, 36, 0, 148, 15, 231, 159, 39, 1, 66, - 127, 38, 1, 229, 218, 104, 161, 34, 4, 168, 20, 240, 6, 253, 74, 70, 81, 104, 8, 153, 20, 240, 5, 251, 253, 144, 19, - 40, 0, 209, 228, 34, 1, 39, 1, 146, 15, 66, 127, 38, 1, 229, 199, 85, 77, 83, 129, 0, 0, 7, 254, 87, 70, 83, 1, 87, - 70, 83, 2, 75, 1, 96, 24, 71, 112, 70, 192, 19, 112, 135, 252, 181, 240, 70, 71, 180, 128, 79, 30, 33, 16, 104, 59, - 77, 29, 67, 139, 96, 59, 104, 43, 76, 28, 104, 154, 104, 35, 70, 136, 104, 86, 43, 0, 208, 24, 28, 48, 240, 0, 248, - 56, 40, 0, 221, 27, 104, 43, 104, 154, 35, 55, 64, 51, 96, 83, 104, 59, 70, 66, 67, 19, 74, 19, 96, 59, 104, 19, 70, - 65, 67, 11, 96, 19, 32, 0, 188, 4, 70, 144, 188, 240, 188, 2, 71, 8, 75, 14, 104, 27, 43, 0, 208, 233, 28, 48, 240, - 0, 248, 27, 231, 227, 35, 0, 96, 35, 75, 10, 96, 24, 32, 4, 247, 255, 251, 231, 104, 43, 104, 154, 35, 55, 64, 51, 96, - 83, 231, 228, 70, 192, 13, 128, 0, 60, 19, 112, 128, 44, 19, 112, 135, 244, 13, 128, 0, 56, 19, 112, 135, 252, 19, 112, - 135, 248, 71, 24, 70, 192, 181, 112, 77, 21, 75, 21, 38, 2, 66, 118, 28, 41, 104, 24, 34, 0, 96, 46, 247, 255, 251, - 231, 75, 18, 34, 0, 104, 27, 76, 17, 104, 155, 96, 154, 75, 17, 104, 32, 96, 26, 247, 255, 251, 152, 104, 32, 247, 255, - 251, 205, 35, 1, 66, 91, 96, 35, 104, 43, 43, 0, 208, 7, 96, 46, 32, 4, 247, 255, 251, 211, 104, 40, 188, 112, 188, - 2, 71, 8, 75, 7, 104, 27, 96, 43, 231, 244, 70, 192, 19, 112, 136, 0, 19, 112, 128, 16, 19, 112, 128, 44, 19, 112, 128, - 20, 19, 112, 135, 244, 19, 112, 135, 248, 181, 16, 75, 15, 28, 4, 104, 26, 28, 8, 35, 1, 73, 13, 247, 255, 251, 169, - 75, 13, 33, 16, 96, 24, 72, 12, 240, 5, 251, 253, 33, 16, 72, 11, 240, 5, 251, 237, 75, 11, 32, 4, 96, 28, 75, 10, 104, - 27, 104, 154, 35, 55, 96, 147, 247, 255, 251, 161, 188, 16, 188, 1, 71, 0, 19, 112, 128, 16, 5, 245, 225, 0, 19, 112, - 128, 20, 13, 128, 0, 56, 13, 128, 0, 60, 19, 112, 135, 244, 19, 112, 128, 44, 181, 48, 77, 18, 74, 18, 104, 43, 176, - 129, 64, 19, 96, 43, 75, 17, 33, 128, 104, 24, 247, 255, 251, 88, 33, 32, 247, 255, 251, 65, 76, 14, 96, 32, 32, 4, - 247, 255, 251, 116, 104, 33, 34, 0, 32, 4, 247, 255, 251, 95, 104, 42, 35, 128, 2, 27, 67, 26, 96, 42, 32, 4, 247, 255, - 251, 111, 176, 1, 188, 48, 188, 1, 71, 0, 70, 192, 13, 4, 0, 204, 255, 255, 127, 255, 19, 112, 128, 32, 19, 112, 128, - 16, 181, 0, 75, 7, 2, 192, 104, 26, 28, 25, 224, 1, 66, 152, 211, 5, 104, 11, 26, 155, 213, 250, 104, 10, 66, 152, 210, - 249, 188, 1, 71, 0, 13, 128, 0, 16, 181, 0, 176, 129, 240, 5, 251, 210, 28, 3, 72, 20, 33, 4, 96, 3, 247, 255, 250, - 238, 240, 5, 251, 190, 34, 0, 28, 1, 72, 16, 240, 5, 251, 115, 33, 136, 2, 137, 72, 15, 247, 255, 250, 222, 75, 14, - 33, 128, 96, 24, 247, 255, 251, 9, 33, 32, 247, 255, 250, 242, 75, 11, 96, 24, 240, 1, 252, 208, 40, 0, 219, 5, 247, - 255, 251, 142, 32, 0, 176, 1, 188, 2, 71, 8, 32, 1, 66, 64, 231, 249, 70, 192, 19, 115, 112, 160, 19, 112, 11, 137, - 19, 113, 80, 160, 19, 112, 128, 32, 19, 112, 128, 24, 181, 48, 176, 129, 40, 37, 209, 0, 224, 116, 40, 37, 216, 20, - 40, 36, 209, 13, 76, 79, 75, 79, 96, 99, 247, 255, 250, 214, 28, 33, 72, 78, 34, 8, 240, 6, 251, 239, 72, 76, 33, 8, - 247, 255, 250, 201, 176, 1, 32, 0, 188, 48, 188, 2, 71, 8, 40, 38, 208, 46, 40, 60, 209, 246, 76, 67, 72, 70, 75, 70, - 28, 34, 96, 99, 28, 3, 202, 34, 195, 34, 33, 8, 247, 255, 250, 181, 72, 67, 75, 67, 28, 34, 96, 99, 28, 3, 202, 34, - 195, 34, 33, 8, 247, 255, 250, 171, 72, 64, 75, 64, 28, 34, 96, 99, 28, 3, 202, 34, 195, 34, 33, 8, 247, 255, 250, 161, - 75, 53, 96, 99, 247, 255, 250, 161, 28, 33, 34, 8, 72, 58, 240, 6, 251, 186, 72, 56, 33, 8, 247, 255, 250, 148, 231, - 201, 76, 45, 72, 47, 75, 54, 28, 34, 96, 99, 28, 3, 202, 34, 195, 34, 33, 8, 247, 255, 250, 136, 72, 44, 75, 50, 28, - 34, 96, 99, 28, 3, 202, 34, 195, 34, 33, 8, 247, 255, 250, 126, 72, 41, 75, 46, 28, 34, 96, 99, 28, 3, 202, 34, 195, - 34, 33, 8, 247, 255, 250, 116, 75, 30, 96, 99, 247, 255, 250, 116, 28, 33, 34, 8, 72, 39, 240, 6, 251, 141, 72, 38, - 33, 8, 247, 255, 250, 103, 231, 156, 76, 22, 72, 25, 75, 35, 28, 34, 96, 99, 28, 3, 202, 34, 195, 34, 33, 8, 247, 255, - 250, 91, 72, 22, 75, 31, 28, 34, 96, 99, 28, 3, 202, 34, 195, 34, 33, 8, 247, 255, 250, 81, 72, 19, 75, 27, 28, 34, - 96, 99, 28, 3, 202, 34, 195, 34, 33, 8, 247, 255, 250, 71, 75, 8, 96, 99, 247, 255, 250, 71, 28, 33, 34, 8, 72, 21, - 240, 6, 251, 96, 72, 19, 33, 8, 247, 255, 250, 58, 231, 111, 70, 192, 19, 112, 128, 36, 19, 112, 0, 96, 255, 255, 30, - 120, 19, 112, 0, 188, 255, 255, 33, 48, 19, 112, 0, 196, 255, 255, 33, 76, 19, 112, 0, 204, 255, 255, 31, 244, 255, - 255, 33, 40, 255, 255, 30, 176, 255, 255, 30, 204, 255, 255, 29, 116, 255, 255, 30, 168, 255, 255, 31, 112, 255, 255, - 31, 140, 255, 255, 30, 52, 255, 255, 31, 104, 181, 48, 77, 12, 176, 129, 35, 0, 104, 42, 73, 11, 247, 255, 250, 56, - 76, 10, 73, 11, 34, 0, 96, 32, 104, 40, 247, 255, 250, 57, 104, 32, 247, 255, 249, 242, 104, 32, 247, 255, 250, 39, - 176, 1, 188, 48, 188, 1, 71, 0, 70, 192, 19, 112, 128, 24, 0, 152, 150, 128, 19, 112, 128, 28, 19, 112, 136, 4, 181, - 48, 28, 3, 1, 64, 26, 192, 77, 13, 0, 128, 24, 192, 176, 129, 35, 0, 104, 42, 73, 11, 0, 192, 247, 255, 250, 16, 76, - 10, 73, 11, 34, 0, 96, 32, 104, 40, 247, 255, 250, 17, 104, 32, 247, 255, 249, 202, 104, 32, 247, 255, 249, 255, 176, - 1, 188, 48, 188, 1, 71, 0, 70, 192, 19, 112, 128, 24, 0, 152, 150, 128, 19, 112, 128, 28, 19, 112, 136, 4, 181, 240, - 70, 87, 70, 78, 70, 69, 180, 224, 28, 5, 28, 22, 28, 31, 14, 10, 6, 11, 32, 255, 67, 26, 2, 0, 28, 11, 64, 3, 2, 27, - 36, 255, 67, 26, 4, 36, 28, 11, 64, 35, 10, 27, 67, 26, 35, 0, 98, 43, 75, 51, 96, 234, 28, 10, 64, 26, 35, 128, 1, - 91, 26, 155, 66, 179, 217, 29, 28, 52, 4, 34, 67, 58, 6, 19, 14, 17, 67, 25, 35, 255, 2, 27, 64, 19, 2, 27, 67, 25, - 35, 255, 4, 27, 64, 26, 10, 18, 35, 128, 4, 91, 67, 17, 96, 169, 100, 44, 96, 43, 96, 107, 28, 32, 188, 28, 70, 144, - 70, 153, 70, 162, 188, 240, 188, 2, 71, 8, 70, 154, 69, 178, 210, 42, 35, 128, 1, 91, 24, 202, 75, 29, 28, 17, 64, 25, - 34, 1, 35, 0, 70, 172, 70, 144, 70, 153, 6, 11, 14, 10, 67, 26, 28, 11, 64, 3, 2, 27, 67, 26, 28, 11, 64, 35, 10, 27, - 67, 26, 70, 99, 97, 26, 70, 74, 98, 90, 35, 128, 1, 91, 28, 26, 68, 82, 24, 201, 66, 150, 216, 24, 28, 51, 66, 150, - 216, 19, 70, 178, 34, 1, 68, 144, 34, 4, 68, 148, 66, 158, 216, 8, 70, 84, 66, 179, 208, 177, 70, 80, 153, 8, 240, 6, - 250, 65, 26, 100, 231, 171, 70, 66, 42, 4, 221, 211, 231, 242, 70, 146, 231, 234, 28, 19, 231, 229, 70, 192, 0, 0, 15, - 255, 255, 255, 240, 0, 181, 48, 7, 67, 213, 45, 77, 58, 76, 58, 104, 40, 104, 35, 104, 129, 108, 74, 43, 0, 208, 40, - 75, 56, 64, 19, 43, 3, 208, 91, 104, 40, 104, 131, 28, 25, 108, 154, 104, 35, 49, 72, 43, 1, 208, 68, 75, 50, 64, 19, - 43, 3, 208, 87, 104, 43, 104, 33, 104, 155, 28, 24, 48, 76, 108, 218, 41, 2, 208, 46, 75, 44, 64, 19, 43, 3, 208, 71, - 104, 43, 104, 153, 104, 35, 109, 10, 43, 3, 208, 25, 75, 39, 64, 19, 43, 3, 208, 17, 188, 48, 188, 1, 71, 0, 7, 211, - 212, 216, 74, 35, 73, 36, 35, 2, 96, 19, 104, 11, 34, 32, 67, 147, 96, 11, 104, 131, 28, 25, 49, 72, 108, 154, 231, - 211, 35, 128, 1, 155, 101, 11, 231, 233, 7, 211, 212, 231, 74, 26, 35, 2, 73, 26, 96, 19, 104, 11, 34, 32, 67, 147, - 96, 11, 231, 222, 7, 211, 212, 210, 75, 20, 34, 32, 96, 25, 73, 20, 104, 11, 67, 147, 96, 11, 231, 202, 66, 26, 209, - 188, 74, 15, 35, 2, 73, 15, 96, 19, 104, 11, 34, 32, 67, 147, 96, 11, 104, 131, 28, 24, 48, 76, 108, 218, 231, 183, - 35, 128, 1, 155, 100, 75, 231, 159, 35, 128, 1, 155, 96, 3, 231, 179, 35, 128, 1, 155, 96, 11, 231, 163, 70, 192, 19, - 112, 128, 44, 19, 112, 136, 20, 0, 0, 32, 3, 19, 112, 136, 8, 13, 128, 0, 192, 181, 240, 75, 24, 28, 5, 104, 31, 35, - 84, 92, 252, 70, 140, 28, 22, 44, 0, 208, 32, 28, 57, 49, 96, 32, 0, 224, 3, 48, 1, 49, 40, 66, 132, 221, 24, 105, 139, - 43, 0, 209, 248, 136, 10, 2, 19, 10, 18, 67, 19, 4, 27, 12, 27, 66, 171, 209, 240, 136, 74, 2, 19, 10, 18, 67, 19, 4, - 27, 12, 27, 69, 99, 209, 232, 0, 131, 24, 27, 0, 219, 24, 251, 103, 158, 224, 1, 38, 6, 66, 118, 28, 48, 188, 240, 188, - 2, 71, 8, 70, 192, 19, 112, 128, 44, 181, 0, 40, 0, 208, 2, 35, 1, 66, 91, 98, 3, 32, 0, 188, 2, 71, 8, 70, 192, 181, - 0, 75, 5, 104, 24, 35, 84, 92, 195, 43, 0, 208, 2, 48, 88, 188, 2, 71, 8, 32, 0, 231, 251, 19, 112, 128, 44, 181, 240, - 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 70, 147, 74, 35, 28, 31, 104, 20, 35, 84, 92, 227, 70, 128, 70, 148, 43, 0, - 208, 59, 40, 0, 208, 57, 37, 0, 35, 84, 38, 0, 70, 169, 70, 154, 224, 1, 69, 69, 218, 36, 0, 179, 25, 155, 0, 219, 24, - 228, 111, 35, 43, 0, 208, 22, 0, 232, 28, 3, 70, 74, 51, 2, 82, 58, 52, 96, 83, 218, 136, 34, 28, 1, 4, 18, 10, 19, - 14, 18, 67, 19, 49, 4, 83, 203, 136, 99, 24, 56, 4, 27, 10, 26, 14, 27, 67, 26, 128, 194, 53, 1, 70, 99, 104, 28, 70, - 82, 92, 163, 54, 1, 66, 179, 220, 216, 6, 43, 14, 24, 70, 91, 112, 24, 32, 0, 188, 60, 70, 144, 70, 153, 70, 162, 70, - 171, 188, 240, 188, 2, 71, 8, 32, 0, 231, 242, 19, 112, 128, 44, 181, 0, 40, 0, 208, 1, 35, 0, 96, 3, 75, 12, 120, 27, - 43, 1, 208, 2, 32, 0, 188, 2, 71, 8, 73, 9, 120, 11, 43, 16, 208, 248, 40, 0, 208, 9, 74, 7, 51, 4, 0, 155, 88, 211, - 96, 3, 120, 11, 51, 20, 0, 155, 88, 208, 231, 237, 74, 2, 231, 248, 19, 112, 136, 56, 19, 112, 128, 52, 19, 115, 114, - 160, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 73, 254, 176, 137, 145, 0, 104, 11, 43, 0, 209, 0, 226, 210, - 76, 252, 77, 252, 104, 36, 104, 43, 34, 96, 98, 28, 104, 43, 33, 0, 106, 24, 240, 6, 249, 82, 104, 43, 33, 96, 106, - 24, 240, 4, 255, 147, 52, 127, 104, 43, 34, 31, 67, 148, 98, 92, 104, 43, 70, 145, 106, 88, 34, 96, 33, 0, 240, 6, 249, - 65, 104, 43, 33, 96, 106, 88, 240, 4, 255, 130, 52, 127, 70, 75, 67, 156, 104, 43, 34, 96, 98, 156, 104, 43, 33, 0, - 106, 152, 240, 6, 249, 49, 104, 43, 33, 96, 106, 152, 240, 4, 255, 114, 52, 127, 104, 43, 70, 73, 67, 140, 98, 220, - 104, 43, 34, 96, 106, 216, 33, 0, 240, 6, 249, 33, 104, 43, 33, 96, 106, 216, 240, 4, 255, 98, 52, 127, 104, 43, 70, - 74, 67, 148, 99, 28, 104, 43, 34, 96, 107, 24, 33, 0, 240, 6, 249, 17, 104, 43, 33, 96, 107, 24, 240, 4, 255, 82, 52, - 127, 70, 75, 67, 156, 104, 43, 34, 96, 99, 92, 104, 43, 33, 0, 107, 88, 240, 6, 249, 1, 104, 43, 33, 96, 107, 88, 240, - 4, 255, 66, 52, 127, 104, 43, 70, 73, 67, 140, 99, 156, 104, 43, 34, 96, 107, 152, 33, 0, 240, 6, 248, 241, 104, 43, - 33, 96, 107, 152, 240, 4, 255, 50, 52, 127, 104, 43, 70, 74, 67, 148, 99, 220, 104, 43, 34, 96, 107, 216, 33, 0, 240, - 6, 248, 225, 104, 43, 33, 96, 107, 216, 240, 4, 255, 34, 52, 127, 70, 75, 67, 156, 34, 96, 28, 32, 33, 0, 240, 6, 248, - 212, 28, 32, 33, 96, 240, 4, 255, 22, 52, 127, 70, 73, 67, 140, 34, 96, 28, 32, 33, 0, 240, 6, 248, 200, 28, 32, 33, - 96, 240, 4, 255, 10, 52, 127, 70, 74, 67, 148, 28, 32, 34, 96, 33, 0, 240, 6, 248, 188, 28, 32, 33, 96, 240, 4, 254, - 254, 52, 127, 70, 75, 67, 156, 34, 96, 28, 32, 33, 0, 240, 6, 248, 176, 28, 32, 33, 96, 240, 4, 254, 242, 52, 127, 70, - 73, 67, 140, 34, 96, 28, 32, 33, 0, 240, 6, 248, 164, 28, 32, 33, 96, 240, 4, 254, 230, 52, 127, 70, 74, 67, 148, 28, - 32, 34, 96, 33, 0, 240, 6, 248, 152, 28, 32, 33, 96, 240, 4, 254, 218, 52, 127, 70, 75, 67, 156, 34, 96, 28, 32, 33, - 0, 240, 6, 248, 140, 28, 32, 33, 96, 240, 4, 254, 206, 52, 127, 70, 73, 67, 140, 34, 96, 28, 32, 33, 0, 240, 6, 248, - 128, 28, 32, 33, 96, 240, 4, 254, 194, 52, 127, 70, 74, 75, 140, 67, 148, 96, 28, 155, 0, 73, 139, 104, 29, 70, 138, - 96, 13, 34, 96, 33, 0, 28, 40, 240, 6, 248, 109, 28, 40, 240, 4, 254, 114, 70, 82, 100, 104, 104, 19, 33, 0, 96, 89, - 104, 19, 53, 127, 96, 153, 104, 19, 34, 128, 5, 210, 146, 3, 70, 81, 97, 154, 70, 75, 67, 157, 104, 9, 28, 40, 70, 139, - 240, 4, 254, 93, 70, 128, 28, 40, 240, 4, 254, 89, 28, 4, 28, 40, 240, 4, 254, 85, 28, 6, 28, 40, 240, 4, 254, 81, 34, - 255, 35, 255, 2, 18, 4, 27, 146, 2, 64, 20, 64, 30, 70, 65, 34, 224, 147, 1, 10, 54, 64, 17, 35, 2, 2, 36, 67, 52, 14, - 0, 67, 25, 67, 4, 6, 9, 67, 12, 70, 89, 96, 12, 70, 82, 104, 19, 33, 128, 4, 74, 97, 26, 70, 81, 104, 11, 70, 147, 97, - 90, 104, 8, 33, 96, 240, 4, 254, 108, 70, 82, 96, 85, 33, 0, 34, 96, 28, 40, 240, 6, 248, 31, 28, 40, 240, 4, 254, 36, - 70, 81, 100, 104, 104, 75, 39, 128, 4, 63, 96, 95, 104, 75, 34, 0, 96, 154, 104, 75, 153, 3, 70, 74, 97, 153, 53, 127, - 70, 83, 67, 149, 104, 91, 28, 40, 147, 4, 240, 4, 254, 15, 70, 128, 28, 40, 240, 4, 254, 11, 28, 4, 28, 40, 240, 4, - 254, 7, 28, 6, 28, 40, 240, 4, 254, 3, 153, 2, 154, 1, 64, 12, 64, 22, 70, 67, 33, 224, 10, 54, 64, 11, 34, 2, 2, 36, - 67, 52, 14, 0, 67, 19, 67, 4, 6, 27, 67, 28, 155, 4, 70, 81, 96, 28, 104, 75, 70, 90, 97, 26, 104, 75, 97, 90, 104, - 72, 33, 96, 240, 4, 254, 37, 70, 83, 96, 157, 33, 0, 34, 96, 28, 40, 240, 5, 255, 216, 28, 40, 240, 4, 253, 221, 70, - 81, 100, 104, 104, 139, 34, 0, 96, 95, 104, 139, 53, 127, 96, 154, 104, 139, 153, 3, 70, 74, 97, 153, 70, 83, 67, 149, - 104, 155, 28, 40, 147, 5, 240, 4, 253, 202, 70, 128, 28, 40, 240, 4, 253, 198, 28, 4, 28, 40, 240, 4, 253, 194, 28, - 6, 28, 40, 240, 4, 253, 190, 153, 2, 154, 1, 64, 12, 64, 22, 70, 67, 33, 224, 10, 54, 64, 11, 34, 2, 2, 36, 67, 52, - 14, 0, 67, 19, 67, 4, 6, 27, 67, 28, 155, 5, 70, 81, 96, 28, 104, 139, 70, 90, 97, 26, 104, 139, 97, 90, 104, 136, 33, - 96, 240, 4, 253, 224, 70, 83, 96, 221, 33, 0, 34, 96, 28, 40, 240, 5, 255, 147, 28, 40, 240, 4, 253, 152, 70, 81, 100, - 104, 104, 203, 34, 0, 96, 95, 104, 203, 53, 127, 96, 154, 104, 203, 153, 3, 70, 74, 97, 153, 70, 83, 67, 149, 104, 219, - 28, 40, 147, 6, 240, 4, 253, 133, 70, 128, 28, 40, 240, 4, 253, 129, 28, 4, 28, 40, 240, 4, 253, 125, 28, 6, 28, 40, - 240, 4, 253, 121, 153, 2, 154, 1, 64, 12, 64, 22, 70, 67, 33, 224, 10, 54, 64, 11, 34, 2, 224, 10, 70, 192, 19, 112, - 136, 104, 19, 112, 136, 100, 19, 112, 128, 44, 19, 112, 136, 96, 19, 115, 112, 192, 2, 36, 67, 52, 14, 0, 67, 19, 67, - 4, 6, 27, 67, 28, 155, 6, 70, 81, 96, 28, 104, 203, 70, 90, 97, 26, 104, 203, 97, 90, 104, 200, 33, 96, 240, 4, 253, - 143, 70, 83, 97, 29, 33, 0, 34, 96, 28, 40, 240, 5, 255, 66, 28, 40, 240, 4, 253, 71, 70, 81, 100, 104, 105, 11, 34, - 0, 96, 95, 105, 11, 53, 127, 96, 154, 105, 11, 153, 3, 70, 74, 97, 153, 70, 83, 67, 149, 105, 27, 28, 40, 147, 7, 240, - 4, 253, 52, 70, 128, 28, 40, 240, 4, 253, 48, 28, 4, 28, 40, 240, 4, 253, 44, 28, 6, 28, 40, 240, 4, 253, 40, 153, 2, - 154, 1, 64, 12, 64, 22, 70, 67, 33, 224, 10, 54, 64, 11, 34, 2, 2, 36, 67, 52, 14, 0, 67, 19, 67, 4, 6, 27, 67, 28, - 155, 7, 70, 81, 96, 28, 105, 11, 70, 90, 97, 26, 105, 11, 97, 90, 105, 8, 33, 96, 240, 4, 253, 74, 70, 83, 97, 93, 33, - 0, 34, 96, 28, 40, 240, 5, 254, 253, 28, 40, 240, 4, 253, 2, 70, 81, 100, 104, 105, 75, 34, 0, 96, 95, 105, 75, 53, - 127, 96, 154, 105, 75, 153, 3, 70, 74, 97, 153, 70, 83, 67, 149, 105, 91, 28, 40, 70, 153, 240, 4, 252, 239, 70, 128, - 28, 40, 240, 4, 252, 235, 28, 4, 28, 40, 240, 4, 252, 231, 28, 6, 28, 40, 240, 4, 252, 227, 153, 2, 154, 1, 64, 12, - 64, 22, 70, 67, 33, 224, 10, 54, 64, 11, 34, 2, 2, 36, 67, 52, 14, 0, 67, 19, 67, 4, 6, 27, 67, 28, 70, 75, 70, 81, - 96, 28, 105, 75, 70, 90, 97, 26, 105, 75, 97, 90, 105, 72, 33, 96, 240, 4, 253, 5, 153, 0, 70, 83, 105, 91, 104, 8, - 70, 152, 240, 4, 252, 192, 154, 0, 28, 6, 104, 16, 240, 4, 252, 187, 155, 0, 28, 4, 104, 24, 240, 4, 252, 182, 153, - 0, 28, 5, 104, 8, 240, 4, 252, 177, 154, 2, 155, 1, 64, 20, 64, 29, 33, 224, 10, 45, 34, 2, 64, 14, 2, 36, 67, 44, 67, - 22, 14, 0, 6, 54, 67, 4, 70, 67, 67, 52, 70, 81, 96, 28, 105, 72, 33, 96, 240, 4, 252, 217, 176, 9, 188, 60, 70, 144, - 70, 153, 70, 162, 70, 171, 188, 240, 188, 1, 71, 0, 77, 4, 76, 5, 104, 43, 105, 154, 96, 10, 106, 27, 96, 35, 28, 28, - 229, 38, 70, 192, 19, 112, 128, 44, 19, 112, 136, 100, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 124, 130, - 124, 199, 125, 6, 6, 19, 70, 148, 125, 68, 4, 58, 67, 26, 2, 51, 67, 19, 28, 33, 176, 129, 70, 128, 67, 25, 208, 121, - 124, 67, 70, 154, 43, 0, 208, 114, 34, 0, 70, 147, 70, 145, 70, 75, 24, 205, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, - 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 208, 82, 121, 43, 43, 0, 208, 58, 39, 0, 38, 0, 224, 10, 122, 107, - 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 25, 132, 123, 163, 123, 226, 6, 27, - 4, 18, 67, 26, 124, 35, 2, 27, 67, 19, 124, 98, 28, 16, 67, 24, 208, 1, 240, 4, 252, 60, 122, 99, 122, 162, 6, 27, 4, - 18, 67, 26, 122, 227, 2, 27, 67, 19, 123, 34, 28, 16, 67, 24, 208, 1, 240, 4, 252, 46, 121, 43, 55, 1, 54, 18, 66, 187, - 220, 210, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 240, 4, 252, 28, - 70, 66, 124, 82, 70, 67, 70, 146, 70, 66, 124, 155, 124, 215, 70, 156, 4, 58, 6, 27, 67, 26, 70, 67, 125, 30, 2, 51, - 67, 19, 70, 66, 125, 84, 28, 33, 67, 25, 35, 1, 34, 13, 68, 155, 68, 145, 69, 218, 221, 8, 70, 98, 6, 19, 4, 58, 67, - 26, 2, 51, 67, 19, 28, 33, 67, 25, 231, 143, 28, 8, 240, 4, 251, 247, 176, 1, 188, 60, 70, 144, 70, 153, 70, 162, 70, - 171, 188, 240, 188, 1, 71, 0, 181, 16, 75, 19, 48, 16, 104, 27, 0, 128, 104, 155, 24, 28, 104, 98, 35, 128, 1, 155, - 66, 26, 209, 0, 64, 90, 35, 46, 67, 154, 96, 98, 32, 5, 247, 255, 249, 65, 35, 128, 104, 98, 1, 155, 66, 26, 208, 0, - 64, 90, 35, 46, 67, 154, 96, 98, 32, 5, 247, 255, 249, 53, 75, 5, 32, 5, 96, 99, 247, 255, 249, 48, 188, 16, 188, 1, - 71, 0, 70, 192, 19, 112, 128, 44, 0, 0, 24, 1, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 75, 51, 176, 129, - 104, 26, 28, 3, 51, 16, 104, 146, 0, 155, 24, 210, 28, 21, 70, 147, 75, 47, 104, 82, 53, 4, 64, 19, 43, 1, 209, 76, - 33, 0, 35, 136, 70, 136, 1, 89, 75, 43, 38, 128, 79, 43, 70, 138, 0, 118, 70, 153, 33, 4, 28, 19, 67, 139, 70, 82, 67, - 19, 96, 43, 32, 60, 247, 255, 250, 55, 104, 43, 74, 37, 32, 50, 64, 19, 96, 43, 247, 255, 250, 48, 104, 60, 224, 1, - 69, 75, 216, 11, 32, 10, 247, 255, 250, 7, 104, 43, 66, 51, 208, 17, 104, 59, 27, 27, 213, 244, 104, 60, 69, 75, 217, - 243, 70, 89, 104, 74, 72, 26, 176, 1, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 104, 42, - 35, 4, 66, 26, 209, 16, 33, 1, 68, 136, 70, 67, 43, 4, 209, 202, 35, 128, 1, 155, 67, 19, 34, 42, 67, 147, 70, 90, 96, - 83, 32, 10, 247, 255, 250, 1, 70, 91, 104, 90, 32, 0, 231, 223, 4, 147, 212, 2, 32, 1, 66, 64, 231, 218, 247, 255, 255, - 106, 32, 1, 66, 64, 231, 213, 70, 192, 19, 112, 128, 44, 0, 0, 32, 1, 0, 0, 39, 15, 13, 128, 0, 16, 255, 255, 254, 213, - 255, 255, 248, 48, 181, 240, 70, 87, 70, 70, 180, 192, 28, 2, 176, 129, 70, 128, 7, 210, 212, 71, 32, 1, 70, 66, 7, - 82, 213, 53, 78, 130, 77, 130, 104, 52, 104, 43, 104, 161, 108, 74, 43, 0, 209, 0, 224, 169, 75, 127, 64, 19, 43, 3, - 209, 0, 224, 239, 104, 52, 104, 42, 104, 163, 28, 31, 55, 72, 108, 153, 42, 1, 209, 0, 224, 177, 75, 120, 64, 11, 43, - 3, 209, 0, 224, 221, 104, 51, 104, 155, 28, 25, 108, 218, 104, 43, 49, 76, 43, 2, 209, 0, 224, 194, 75, 113, 64, 19, - 43, 3, 209, 0, 224, 203, 104, 51, 104, 153, 104, 43, 109, 10, 43, 3, 209, 0, 224, 168, 75, 107, 64, 19, 43, 3, 209, - 0, 224, 142, 40, 0, 208, 4, 35, 18, 70, 66, 66, 26, 208, 0, 224, 196, 176, 1, 188, 12, 70, 144, 70, 154, 188, 240, 188, - 2, 71, 8, 77, 99, 104, 44, 44, 0, 208, 10, 107, 96, 33, 96, 247, 254, 251, 115, 107, 96, 33, 96, 240, 4, 250, 231, 107, - 164, 44, 0, 209, 244, 76, 92, 104, 35, 43, 0, 208, 26, 108, 88, 33, 32, 247, 254, 251, 100, 104, 35, 33, 32, 108, 88, - 240, 4, 250, 215, 104, 34, 35, 128, 4, 91, 97, 19, 75, 85, 104, 34, 104, 27, 33, 32, 107, 91, 97, 83, 104, 35, 108, - 88, 247, 254, 251, 93, 104, 35, 74, 80, 105, 155, 96, 19, 104, 40, 40, 0, 208, 39, 38, 255, 37, 255, 35, 3, 34, 64, - 79, 76, 2, 54, 4, 45, 70, 156, 70, 146, 104, 130, 6, 19, 14, 17, 67, 25, 28, 19, 64, 51, 2, 27, 67, 25, 64, 42, 10, - 18, 28, 12, 67, 20, 10, 35, 70, 98, 64, 19, 43, 2, 208, 7, 107, 193, 108, 3, 105, 74, 24, 210, 12, 35, 64, 59, 26, 210, - 97, 74, 108, 3, 43, 0, 209, 8, 107, 128, 40, 0, 209, 224, 75, 51, 32, 0, 104, 26, 35, 0, 100, 19, 231, 89, 70, 83, 66, - 28, 208, 243, 107, 194, 35, 1, 66, 91, 73, 45, 97, 83, 104, 11, 34, 0, 100, 26, 104, 11, 32, 5, 100, 26, 66, 64, 231, - 73, 33, 1, 66, 10, 208, 0, 231, 86, 75, 46, 34, 32, 96, 25, 73, 46, 32, 1, 104, 11, 66, 64, 67, 147, 96, 11, 104, 163, - 28, 31, 55, 72, 108, 153, 231, 81, 35, 128, 1, 155, 101, 11, 231, 108, 66, 17, 208, 0, 231, 79, 75, 36, 73, 36, 96, - 26, 104, 11, 34, 32, 67, 147, 96, 11, 104, 163, 32, 1, 28, 25, 49, 76, 108, 218, 66, 64, 231, 74, 33, 1, 66, 10, 208, - 0, 231, 87, 75, 27, 34, 32, 96, 25, 73, 26, 32, 1, 104, 11, 66, 64, 67, 147, 96, 11, 231, 79, 33, 1, 66, 10, 208, 0, - 231, 61, 75, 20, 34, 32, 96, 25, 73, 19, 32, 1, 104, 11, 66, 64, 67, 147, 96, 11, 231, 51, 35, 128, 1, 155, 96, 11, - 231, 47, 35, 128, 1, 155, 96, 59, 231, 29, 35, 128, 1, 155, 100, 75, 231, 11, 32, 6, 66, 64, 231, 55, 19, 112, 128, - 44, 19, 112, 136, 20, 0, 0, 32, 3, 19, 112, 136, 36, 19, 112, 136, 40, 19, 112, 136, 96, 19, 112, 136, 44, 0, 0, 127, - 255, 19, 112, 136, 8, 13, 128, 0, 192, 180, 15, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 176, 133, 175, 14, - 35, 128, 73, 163, 207, 16, 1, 155, 70, 104, 129, 195, 145, 0, 78, 161, 120, 35, 70, 176, 70, 178, 43, 0, 208, 13, 43, - 37, 208, 21, 70, 106, 70, 104, 115, 147, 48, 14, 247, 254, 250, 176, 28, 61, 52, 1, 28, 47, 120, 35, 43, 0, 209, 241, - 176, 5, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 8, 176, 4, 71, 24, 28, 99, 147, 1, 120, 99, 59, - 100, 6, 27, 14, 27, 43, 20, 217, 4, 28, 61, 156, 1, 28, 47, 52, 1, 231, 229, 156, 0, 0, 155, 88, 227, 70, 159, 104, - 58, 42, 0, 209, 0, 226, 48, 35, 15, 64, 19, 9, 17, 70, 179, 29, 218, 43, 9, 221, 0, 225, 201, 51, 48, 117, 243, 35, - 15, 64, 11, 29, 218, 9, 9, 43, 9, 221, 0, 226, 3, 51, 48, 117, 179, 35, 15, 64, 11, 29, 218, 9, 9, 43, 9, 221, 0, 225, - 239, 51, 48, 117, 115, 35, 15, 64, 11, 29, 218, 9, 9, 43, 9, 221, 0, 225, 219, 51, 48, 117, 51, 35, 15, 64, 11, 29, - 218, 9, 9, 43, 9, 221, 0, 225, 199, 51, 48, 116, 243, 35, 15, 64, 11, 29, 218, 9, 9, 43, 9, 221, 0, 225, 180, 51, 48, - 116, 179, 35, 15, 64, 11, 29, 218, 43, 9, 221, 0, 225, 161, 51, 48, 34, 15, 116, 115, 9, 11, 64, 19, 29, 218, 43, 9, - 221, 0, 225, 150, 51, 48, 116, 51, 35, 0, 118, 51, 124, 49, 35, 48, 112, 51, 35, 120, 112, 115, 41, 48, 208, 0, 225, - 236, 34, 16, 50, 1, 92, 177, 41, 48, 208, 251, 28, 19, 41, 0, 209, 0, 225, 198, 92, 242, 42, 0, 209, 0, 225, 231, 51, - 1, 24, 243, 33, 2, 84, 114, 120, 26, 49, 1, 51, 1, 42, 0, 209, 249, 35, 0, 84, 115, 70, 88, 29, 61, 247, 254, 250, 29, - 231, 132, 104, 60, 44, 0, 209, 0, 225, 182, 28, 32, 33, 10, 240, 5, 250, 84, 33, 10, 28, 5, 28, 32, 240, 5, 250, 141, - 70, 66, 49, 48, 118, 81, 28, 40, 33, 10, 240, 5, 250, 72, 33, 10, 28, 4, 28, 40, 240, 5, 250, 129, 70, 67, 49, 48, 118, - 25, 28, 32, 33, 10, 240, 5, 250, 60, 33, 10, 28, 5, 28, 32, 240, 5, 250, 117, 70, 68, 49, 48, 117, 225, 28, 40, 33, - 10, 240, 5, 250, 48, 33, 10, 28, 4, 28, 40, 240, 5, 250, 105, 70, 64, 49, 48, 117, 129, 28, 32, 33, 10, 240, 5, 250, - 36, 33, 10, 28, 5, 28, 32, 240, 5, 250, 93, 70, 66, 49, 48, 117, 81, 28, 40, 33, 10, 240, 5, 250, 24, 33, 10, 28, 4, - 28, 40, 240, 5, 250, 81, 70, 67, 49, 48, 117, 25, 28, 32, 33, 10, 240, 5, 250, 12, 33, 10, 28, 5, 28, 32, 240, 5, 250, - 69, 70, 68, 49, 48, 116, 225, 28, 40, 33, 10, 240, 5, 250, 0, 33, 10, 28, 4, 28, 40, 240, 5, 250, 57, 70, 64, 49, 48, - 116, 129, 28, 32, 33, 10, 240, 5, 250, 50, 70, 66, 49, 48, 116, 81, 28, 32, 33, 10, 240, 5, 249, 237, 33, 10, 240, 5, - 250, 40, 70, 67, 49, 48, 116, 25, 70, 68, 124, 34, 35, 0, 70, 195, 118, 163, 42, 48, 208, 0, 225, 85, 35, 16, 51, 1, - 70, 64, 92, 194, 42, 48, 208, 250, 28, 25, 42, 0, 209, 0, 225, 41, 70, 65, 92, 202, 42, 0, 209, 0, 225, 73, 51, 1, 68, - 67, 33, 0, 70, 68, 84, 98, 120, 26, 49, 1, 51, 1, 42, 0, 209, 248, 35, 0, 70, 64, 84, 67, 231, 96, 104, 56, 29, 61, - 247, 254, 249, 126, 230, 229, 70, 192, 19, 112, 128, 120, 19, 115, 114, 128, 104, 56, 70, 129, 40, 0, 209, 0, 225, 11, - 33, 10, 240, 5, 250, 64, 70, 72, 28, 12, 33, 10, 240, 5, 249, 241, 23, 227, 24, 228, 64, 92, 28, 5, 52, 48, 70, 80, - 118, 68, 33, 10, 28, 40, 240, 5, 250, 48, 28, 40, 28, 12, 33, 10, 240, 5, 249, 225, 23, 225, 24, 100, 64, 76, 70, 82, - 52, 48, 118, 20, 33, 10, 28, 5, 240, 5, 250, 33, 28, 40, 28, 12, 33, 10, 240, 5, 249, 210, 23, 227, 24, 228, 64, 92, - 28, 5, 52, 48, 70, 80, 117, 196, 33, 10, 28, 40, 240, 5, 250, 17, 28, 40, 28, 12, 33, 10, 240, 5, 249, 194, 23, 225, - 24, 100, 64, 76, 70, 82, 52, 48, 117, 148, 33, 10, 28, 5, 240, 5, 250, 2, 28, 40, 28, 12, 33, 10, 240, 5, 249, 179, - 23, 227, 24, 228, 64, 92, 28, 5, 52, 48, 70, 80, 117, 68, 33, 10, 28, 40, 240, 5, 249, 242, 28, 40, 28, 12, 33, 10, - 240, 5, 249, 163, 23, 225, 24, 100, 64, 76, 70, 82, 52, 48, 117, 20, 33, 10, 28, 5, 240, 5, 249, 227, 28, 40, 28, 12, - 33, 10, 240, 5, 249, 148, 23, 227, 24, 228, 64, 92, 28, 5, 52, 48, 70, 80, 116, 196, 33, 10, 28, 40, 240, 5, 249, 211, - 28, 40, 28, 12, 33, 10, 240, 5, 249, 132, 23, 225, 24, 100, 64, 76, 70, 82, 52, 48, 116, 148, 33, 10, 28, 5, 240, 5, - 249, 196, 23, 203, 24, 201, 64, 89, 70, 84, 49, 48, 116, 97, 28, 40, 33, 10, 240, 5, 249, 112, 33, 10, 240, 5, 249, - 183, 23, 200, 24, 9, 64, 65, 49, 48, 116, 33, 35, 0, 70, 73, 70, 211, 118, 163, 41, 0, 218, 0, 224, 134, 32, 0, 70, - 83, 124, 25, 41, 48, 208, 0, 224, 133, 34, 16, 50, 1, 70, 84, 92, 161, 41, 48, 208, 250, 28, 19, 41, 0, 209, 0, 30, - 83, 70, 81, 92, 202, 42, 0, 208, 9, 51, 1, 24, 9, 68, 83, 112, 10, 120, 26, 48, 1, 49, 1, 51, 1, 42, 0, 209, 248, 35, - 0, 70, 82, 84, 19, 230, 151, 28, 19, 51, 48, 117, 243, 35, 15, 64, 11, 29, 218, 9, 9, 43, 9, 220, 0, 230, 52, 224, 55, - 28, 19, 230, 102, 28, 19, 51, 48, 34, 15, 116, 115, 9, 11, 64, 19, 29, 218, 43, 9, 220, 0, 230, 92, 231, 242, 28, 19, - 51, 48, 116, 179, 35, 15, 64, 11, 29, 218, 43, 9, 220, 0, 230, 73, 231, 234, 28, 19, 51, 48, 116, 243, 35, 15, 64, 11, - 29, 218, 9, 9, 43, 9, 220, 0, 230, 54, 231, 234, 28, 19, 51, 48, 117, 51, 35, 15, 64, 11, 29, 218, 9, 9, 43, 9, 220, - 0, 230, 34, 231, 233, 28, 19, 51, 48, 117, 115, 35, 15, 64, 11, 29, 218, 9, 9, 43, 9, 220, 0, 230, 14, 231, 233, 28, - 19, 51, 48, 117, 179, 35, 15, 64, 11, 29, 218, 9, 9, 43, 9, 220, 0, 229, 250, 231, 233, 30, 75, 230, 211, 30, 83, 230, - 54, 73, 18, 35, 48, 70, 139, 112, 11, 112, 72, 230, 63, 75, 15, 70, 155, 70, 88, 35, 48, 112, 3, 112, 68, 230, 56, 73, - 11, 35, 48, 70, 139, 112, 11, 112, 74, 230, 50, 35, 45, 70, 82, 112, 19, 32, 1, 231, 116, 34, 16, 35, 16, 231, 125, - 34, 16, 35, 16, 230, 21, 33, 16, 35, 16, 230, 173, 33, 0, 230, 189, 33, 2, 230, 30, 19, 115, 114, 128, 181, 240, 70, - 95, 70, 86, 70, 77, 70, 68, 180, 240, 75, 57, 28, 1, 104, 27, 176, 139, 104, 154, 75, 56, 104, 84, 104, 27, 50, 68, - 0, 155, 24, 210, 104, 18, 72, 53, 70, 147, 247, 255, 253, 92, 4, 33, 212, 62, 75, 51, 70, 153, 4, 99, 212, 62, 73, 49, - 70, 138, 4, 161, 212, 62, 75, 47, 70, 152, 4, 227, 212, 62, 73, 45, 70, 140, 6, 161, 212, 62, 79, 43, 6, 227, 212, 62, - 78, 42, 7, 33, 212, 62, 77, 40, 7, 99, 212, 62, 74, 39, 7, 161, 212, 62, 75, 37, 147, 9, 7, 227, 212, 62, 73, 35, 70, - 67, 147, 0, 70, 99, 147, 1, 155, 9, 146, 5, 147, 6, 70, 74, 70, 83, 145, 7, 72, 31, 28, 33, 151, 2, 150, 3, 149, 4, - 247, 255, 253, 40, 70, 89, 72, 28, 247, 255, 253, 36, 176, 11, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, - 188, 1, 71, 0, 73, 23, 70, 137, 4, 99, 213, 192, 75, 22, 70, 154, 4, 161, 213, 192, 73, 21, 70, 136, 4, 227, 213, 192, - 75, 20, 70, 156, 6, 161, 213, 192, 79, 19, 6, 227, 213, 192, 78, 18, 7, 33, 213, 192, 77, 18, 7, 99, 213, 192, 74, 17, - 7, 161, 213, 192, 73, 17, 145, 9, 7, 227, 213, 192, 73, 16, 231, 191, 70, 192, 19, 112, 128, 44, 19, 112, 136, 20, 19, - 112, 128, 204, 19, 112, 134, 240, 19, 112, 129, 56, 19, 112, 129, 96, 19, 112, 128, 228, 19, 112, 128, 236, 19, 112, - 128, 248, 19, 112, 129, 0, 19, 112, 129, 8, 19, 112, 129, 16, 19, 112, 129, 24, 19, 112, 129, 32, 19, 112, 129, 40, - 19, 112, 129, 48, 181, 48, 75, 20, 176, 129, 104, 28, 108, 33, 41, 7, 221, 5, 37, 0, 176, 1, 28, 40, 188, 48, 188, 2, - 71, 8, 75, 15, 104, 27, 0, 219, 24, 91, 0, 90, 24, 210, 106, 35, 1, 82, 24, 157, 28, 75, 100, 35, 28, 40, 240, 3, 254, - 221, 33, 0, 28, 4, 34, 96, 28, 40, 240, 5, 248, 207, 35, 64, 96, 171, 35, 128, 4, 91, 99, 108, 96, 43, 96, 107, 231, - 222, 70, 192, 19, 112, 128, 44, 19, 112, 136, 12, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 176, 131, 247, - 254, 255, 79, 75, 144, 34, 31, 104, 28, 70, 146, 28, 38, 28, 32, 54, 127, 67, 150, 240, 3, 254, 183, 33, 0, 28, 5, 34, - 96, 28, 32, 240, 5, 248, 169, 99, 101, 35, 64, 34, 128, 70, 153, 96, 163, 4, 83, 107, 114, 70, 152, 6, 17, 14, 19, 67, - 25, 35, 255, 4, 27, 147, 1, 64, 19, 10, 27, 67, 25, 35, 255, 2, 27, 64, 26, 2, 18, 67, 17, 70, 66, 96, 98, 96, 33, 28, - 32, 33, 96, 28, 53, 70, 155, 53, 127, 240, 3, 254, 207, 70, 83, 28, 48, 67, 157, 240, 3, 254, 140, 33, 0, 28, 4, 34, - 96, 28, 48, 240, 5, 248, 126, 99, 116, 70, 74, 96, 178, 107, 106, 28, 48, 6, 19, 14, 17, 67, 25, 70, 91, 64, 19, 2, - 27, 67, 25, 155, 1, 28, 44, 64, 26, 10, 18, 67, 17, 70, 66, 96, 114, 96, 49, 33, 96, 240, 3, 254, 173, 52, 127, 70, - 83, 28, 40, 67, 156, 240, 3, 254, 105, 33, 0, 28, 6, 34, 96, 28, 40, 240, 5, 248, 91, 99, 110, 70, 74, 96, 170, 107, - 98, 28, 40, 6, 19, 14, 17, 67, 25, 70, 91, 64, 19, 2, 27, 67, 25, 155, 1, 64, 26, 10, 18, 67, 17, 70, 66, 96, 106, 96, - 41, 33, 96, 240, 3, 254, 139, 28, 32, 240, 3, 254, 74, 33, 0, 28, 5, 34, 96, 28, 32, 240, 5, 248, 60, 70, 66, 70, 75, - 99, 101, 96, 163, 96, 34, 96, 98, 28, 32, 33, 96, 240, 3, 254, 120, 77, 77, 73, 78, 104, 42, 104, 11, 79, 77, 97, 147, - 104, 42, 104, 75, 78, 76, 97, 211, 75, 76, 70, 154, 104, 139, 70, 82, 96, 19, 104, 203, 96, 59, 105, 11, 33, 96, 96, - 51, 104, 43, 105, 152, 240, 3, 254, 72, 104, 42, 105, 147, 100, 218, 104, 43, 34, 0, 105, 155, 70, 145, 100, 154, 104, - 43, 105, 156, 28, 32, 240, 3, 254, 21, 100, 96, 104, 51, 70, 90, 108, 89, 104, 43, 64, 10, 105, 152, 155, 1, 2, 18, - 64, 11, 10, 27, 67, 26, 14, 11, 67, 26, 35, 224, 64, 25, 35, 2, 67, 25, 6, 9, 67, 10, 96, 2, 104, 43, 33, 96, 105, 154, - 35, 128, 4, 27, 96, 83, 104, 43, 70, 74, 105, 155, 96, 154, 104, 43, 105, 154, 35, 128, 5, 219, 97, 147, 104, 43, 70, - 66, 105, 155, 97, 26, 104, 43, 105, 155, 97, 90, 104, 43, 105, 152, 240, 3, 254, 36, 104, 43, 33, 96, 105, 216, 240, - 3, 254, 7, 104, 42, 105, 211, 100, 218, 104, 43, 70, 74, 105, 219, 100, 154, 104, 43, 105, 220, 28, 32, 240, 3, 253, - 213, 70, 83, 100, 96, 104, 24, 33, 96, 240, 3, 253, 245, 70, 83, 104, 26, 104, 43, 100, 211, 70, 82, 104, 19, 70, 74, - 100, 154, 70, 83, 104, 28, 28, 32, 240, 3, 253, 194, 70, 82, 100, 96, 104, 16, 33, 96, 240, 3, 253, 250, 104, 56, 33, - 96, 240, 3, 253, 222, 104, 58, 104, 43, 100, 211, 104, 59, 70, 74, 100, 154, 104, 60, 28, 32, 240, 3, 253, 174, 100, - 96, 104, 56, 33, 96, 240, 3, 253, 231, 176, 3, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 1, 71, 0, - 19, 112, 136, 96, 19, 112, 128, 44, 19, 115, 112, 192, 19, 112, 136, 28, 19, 112, 136, 32, 19, 112, 136, 24, 181, 240, - 79, 35, 75, 35, 176, 129, 96, 59, 240, 3, 253, 227, 40, 0, 219, 58, 240, 3, 254, 229, 96, 56, 104, 130, 75, 31, 33, - 1, 96, 19, 104, 56, 104, 130, 104, 19, 66, 11, 209, 252, 33, 252, 240, 3, 253, 186, 38, 128, 37, 128, 36, 0, 4, 118, - 1, 109, 104, 59, 33, 4, 108, 219, 81, 30, 104, 59, 108, 219, 89, 24, 52, 4, 240, 3, 253, 171, 66, 172, 209, 243, 247, - 255, 254, 159, 104, 57, 34, 1, 35, 84, 84, 202, 104, 59, 32, 0, 104, 154, 105, 155, 108, 91, 97, 147, 104, 59, 104, - 154, 35, 4, 96, 147, 104, 59, 104, 154, 75, 9, 96, 19, 104, 59, 104, 155, 104, 25, 176, 1, 188, 240, 188, 2, 71, 8, - 32, 1, 66, 64, 231, 248, 70, 192, 19, 112, 128, 44, 19, 115, 115, 68, 0, 1, 0, 32, 0, 1, 0, 33, 181, 240, 70, 95, 70, - 86, 70, 77, 70, 68, 180, 240, 75, 155, 176, 137, 104, 28, 28, 7, 108, 33, 41, 7, 221, 1, 32, 0, 224, 170, 75, 152, 104, - 27, 0, 219, 24, 91, 0, 90, 24, 210, 106, 35, 1, 82, 24, 155, 147, 5, 28, 75, 100, 35, 152, 5, 240, 3, 253, 38, 34, 96, - 28, 4, 33, 0, 152, 5, 240, 4, 255, 24, 154, 5, 35, 64, 96, 147, 35, 128, 4, 91, 96, 19, 96, 83, 99, 84, 99, 215, 35, - 0, 97, 123, 105, 59, 126, 125, 70, 152, 126, 59, 43, 0, 209, 0, 224, 140, 34, 128, 35, 192, 156, 5, 146, 7, 0, 91, 104, - 254, 45, 0, 208, 0, 147, 7, 105, 250, 75, 128, 64, 19, 147, 6, 59, 1, 147, 4, 35, 255, 2, 26, 70, 145, 34, 128, 4, 27, - 1, 82, 70, 154, 146, 3, 6, 51, 14, 50, 67, 26, 70, 75, 64, 51, 2, 27, 67, 26, 70, 83, 64, 51, 10, 27, 67, 26, 35, 0, - 98, 35, 96, 226, 75, 116, 154, 3, 64, 51, 26, 208, 70, 195, 69, 128, 211, 0, 224, 134, 35, 0, 70, 69, 70, 152, 155, - 7, 4, 42, 67, 26, 6, 19, 14, 17, 67, 25, 70, 75, 64, 19, 2, 27, 67, 25, 70, 83, 64, 26, 10, 18, 35, 128, 4, 91, 67, - 17, 70, 90, 96, 35, 96, 99, 96, 161, 100, 34, 154, 4, 25, 83, 154, 6, 66, 19, 209, 3, 155, 7, 74, 98, 24, 155, 147, - 7, 70, 67, 43, 0, 221, 0, 224, 151, 35, 128, 4, 91, 96, 99, 105, 59, 28, 38, 43, 0, 208, 36, 126, 61, 45, 0, 209, 33, - 247, 255, 253, 184, 28, 4, 40, 0, 209, 0, 231, 116, 107, 66, 99, 199, 6, 19, 14, 17, 67, 25, 35, 255, 2, 27, 64, 19, - 2, 27, 67, 25, 35, 255, 4, 27, 64, 26, 10, 18, 67, 17, 96, 49, 99, 176, 154, 7, 35, 128, 0, 91, 64, 83, 74, 76, 33, - 0, 67, 19, 34, 0, 149, 0, 247, 254, 251, 88, 104, 163, 34, 128, 4, 18, 67, 19, 96, 163, 152, 5, 176, 9, 188, 60, 70, - 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 35, 8, 104, 121, 147, 0, 35, 160, 34, 8, 0, 155, 152, 5, 247, - 254, 251, 64, 247, 255, 253, 126, 28, 4, 40, 0, 209, 0, 231, 58, 107, 66, 99, 199, 6, 19, 14, 17, 67, 25, 35, 255, 2, - 27, 64, 19, 2, 27, 67, 25, 35, 255, 4, 27, 64, 26, 10, 18, 155, 5, 67, 17, 70, 66, 96, 25, 99, 152, 42, 0, 209, 79, - 75, 48, 147, 7, 231, 80, 28, 5, 69, 128, 217, 77, 35, 128, 1, 91, 24, 242, 75, 44, 28, 17, 34, 1, 64, 25, 28, 32, 70, - 148, 6, 11, 14, 10, 67, 26, 70, 75, 64, 11, 2, 27, 67, 26, 70, 83, 64, 11, 10, 27, 67, 26, 97, 2, 34, 128, 1, 82, 35, - 0, 24, 173, 98, 67, 24, 137, 69, 168, 216, 5, 70, 69, 70, 67, 27, 91, 70, 171, 70, 152, 231, 85, 35, 1, 68, 156, 70, - 98, 48, 4, 42, 4, 221, 223, 28, 40, 153, 6, 240, 4, 253, 168, 70, 66, 26, 109, 27, 82, 70, 171, 70, 144, 231, 69, 247, - 255, 253, 42, 40, 0, 209, 0, 230, 231, 107, 66, 99, 160, 6, 19, 14, 17, 67, 25, 70, 75, 64, 19, 2, 27, 67, 25, 70, 83, - 64, 26, 10, 18, 67, 17, 96, 33, 68, 94, 99, 199, 28, 4, 231, 21, 74, 10, 75, 7, 146, 7, 230, 255, 69, 128, 209, 216, - 231, 204, 19, 112, 128, 44, 19, 112, 136, 12, 0, 0, 7, 255, 0, 0, 15, 255, 128, 0, 0, 0, 128, 0, 1, 128, 255, 255, 240, - 0, 128, 0, 0, 128, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 77, 214, 176, 131, 144, 1, 70, 138, 36, 0, 78, - 213, 70, 168, 79, 213, 224, 5, 32, 10, 52, 1, 247, 254, 250, 97, 66, 188, 208, 26, 104, 51, 104, 153, 105, 43, 105, - 138, 108, 91, 66, 154, 211, 242, 70, 64, 105, 67, 108, 91, 66, 154, 216, 237, 104, 11, 36, 32, 28, 26, 104, 51, 67, - 162, 104, 155, 32, 10, 96, 26, 247, 254, 250, 73, 104, 51, 104, 155, 104, 27, 66, 35, 209, 242, 70, 81, 126, 10, 42, - 0, 209, 0, 226, 87, 70, 83, 105, 25, 41, 0, 208, 9, 126, 91, 43, 0, 209, 0, 226, 54, 70, 82, 104, 144, 240, 3, 252, - 3, 70, 83, 96, 216, 70, 80, 126, 3, 43, 0, 208, 0, 226, 35, 104, 51, 105, 219, 70, 152, 75, 183, 79, 183, 70, 66, 96, - 26, 28, 56, 70, 65, 34, 96, 240, 3, 252, 198, 34, 0, 70, 67, 195, 4, 51, 4, 70, 64, 96, 66, 195, 4, 195, 4, 195, 4, - 195, 4, 195, 4, 195, 4, 195, 4, 195, 4, 195, 4, 96, 26, 104, 51, 73, 172, 100, 26, 104, 11, 34, 1, 64, 83, 96, 11, 70, - 80, 247, 255, 254, 68, 75, 168, 100, 184, 96, 24, 28, 5, 152, 1, 70, 82, 105, 131, 126, 17, 105, 212, 34, 128, 1, 146, - 67, 26, 35, 15, 64, 11, 2, 27, 28, 16, 67, 24, 41, 0, 208, 0, 225, 223, 75, 159, 28, 1, 67, 25, 6, 11, 14, 10, 36, 255, - 2, 36, 67, 26, 28, 11, 64, 35, 2, 27, 32, 255, 4, 0, 67, 26, 28, 11, 64, 3, 73, 152, 10, 27, 67, 26, 35, 64, 96, 122, - 96, 187, 145, 0, 104, 11, 108, 90, 28, 17, 28, 19, 64, 33, 64, 3, 10, 27, 2, 9, 67, 25, 14, 19, 67, 25, 35, 224, 64, - 26, 35, 2, 67, 26, 6, 18, 67, 17, 96, 57, 107, 106, 6, 19, 14, 17, 67, 25, 28, 19, 64, 35, 2, 27, 64, 2, 67, 25, 10, - 18, 35, 128, 67, 17, 4, 91, 97, 123, 97, 57, 70, 83, 126, 26, 42, 0, 208, 17, 153, 1, 6, 19, 106, 72, 43, 0, 218, 0, - 225, 214, 33, 0, 35, 15, 64, 19, 24, 203, 64, 216, 7, 194, 212, 0, 225, 201, 105, 187, 34, 128, 67, 19, 97, 187, 105, - 187, 74, 122, 108, 188, 64, 19, 97, 187, 44, 0, 208, 6, 28, 32, 33, 96, 240, 3, 251, 89, 107, 164, 44, 0, 209, 248, - 34, 96, 70, 64, 28, 57, 240, 3, 252, 71, 77, 114, 35, 1, 96, 43, 75, 113, 72, 114, 104, 25, 247, 254, 248, 23, 104, - 51, 33, 32, 105, 152, 240, 3, 251, 44, 104, 51, 108, 121, 105, 152, 35, 255, 2, 27, 28, 10, 64, 26, 35, 255, 4, 27, - 64, 11, 10, 27, 2, 18, 67, 26, 14, 11, 67, 26, 35, 224, 64, 25, 35, 2, 67, 25, 6, 9, 67, 10, 96, 2, 104, 51, 33, 32, - 105, 152, 240, 3, 251, 41, 104, 51, 36, 32, 104, 155, 104, 26, 104, 51, 67, 34, 104, 155, 32, 10, 96, 26, 247, 254, - 249, 94, 104, 51, 104, 155, 104, 26, 66, 34, 208, 243, 247, 253, 255, 173, 35, 0, 70, 131, 96, 43, 40, 0, 209, 4, 75, - 85, 104, 27, 43, 0, 209, 0, 224, 215, 104, 49, 75, 83, 104, 138, 104, 27, 50, 68, 0, 155, 24, 210, 104, 19, 34, 5, 64, - 19, 43, 5, 208, 2, 74, 77, 35, 1, 96, 19, 70, 90, 66, 80, 65, 80, 70, 129, 40, 0, 208, 0, 224, 195, 50, 5, 209, 0, 224, - 192, 104, 139, 36, 32, 104, 27, 28, 26, 104, 51, 67, 162, 104, 155, 32, 10, 96, 26, 247, 254, 249, 41, 104, 51, 104, - 155, 104, 27, 66, 35, 209, 242, 108, 188, 44, 0, 208, 6, 107, 96, 33, 96, 240, 3, 250, 197, 107, 164, 44, 0, 209, 248, - 70, 65, 34, 32, 28, 56, 240, 3, 251, 187, 70, 81, 126, 10, 42, 0, 208, 19, 155, 1, 28, 17, 106, 88, 35, 15, 64, 25, - 6, 19, 43, 0, 218, 0, 225, 50, 34, 1, 28, 19, 64, 139, 67, 152, 105, 187, 9, 219, 64, 19, 64, 139, 67, 3, 152, 1, 98, - 67, 104, 51, 33, 32, 105, 152, 247, 253, 251, 28, 104, 51, 33, 32, 105, 152, 240, 3, 250, 115, 153, 0, 36, 32, 104, - 11, 108, 89, 104, 51, 28, 10, 105, 152, 35, 255, 2, 27, 64, 26, 35, 255, 4, 27, 64, 11, 10, 27, 2, 18, 67, 26, 14, 11, - 67, 26, 35, 224, 64, 25, 35, 2, 67, 25, 6, 9, 67, 10, 96, 2, 104, 51, 33, 32, 105, 152, 247, 253, 250, 201, 104, 51, - 104, 155, 104, 26, 104, 51, 67, 34, 104, 155, 32, 10, 96, 26, 247, 254, 248, 203, 104, 51, 104, 155, 104, 26, 66, 34, - 208, 243, 34, 0, 70, 145, 36, 0, 77, 3, 224, 36, 70, 192, 19, 115, 112, 192, 19, 112, 128, 44, 0, 0, 19, 136, 19, 112, - 136, 40, 19, 115, 114, 32, 19, 112, 136, 12, 19, 112, 136, 36, 64, 64, 64, 0, 19, 112, 136, 32, 1, 0, 0, 128, 19, 112, - 136, 16, 19, 112, 128, 48, 19, 112, 25, 153, 19, 112, 136, 8, 19, 112, 136, 20, 32, 10, 52, 1, 247, 254, 248, 158, 66, - 172, 208, 5, 104, 51, 104, 155, 105, 154, 108, 123, 66, 154, 208, 243, 70, 83, 105, 25, 41, 0, 208, 7, 126, 91, 43, - 0, 209, 0, 224, 152, 70, 82, 104, 208, 240, 3, 250, 66, 70, 80, 126, 3, 43, 0, 209, 0, 224, 152, 70, 73, 41, 0, 208, - 2, 70, 82, 105, 82, 70, 147, 176, 3, 70, 88, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 35, - 1, 70, 153, 104, 51, 36, 32, 104, 155, 104, 27, 28, 26, 104, 51, 67, 162, 104, 155, 32, 10, 96, 26, 247, 254, 248, 103, - 104, 50, 104, 147, 104, 27, 66, 35, 209, 242, 105, 144, 33, 32, 247, 253, 250, 130, 104, 51, 33, 32, 105, 152, 240, - 3, 249, 217, 152, 0, 36, 32, 104, 3, 108, 89, 104, 51, 28, 10, 105, 152, 35, 255, 2, 27, 64, 26, 35, 255, 4, 27, 64, - 11, 10, 27, 2, 18, 67, 26, 14, 11, 67, 26, 35, 224, 64, 25, 35, 2, 67, 25, 6, 9, 67, 10, 96, 2, 104, 51, 33, 32, 105, - 152, 247, 253, 250, 47, 104, 51, 104, 155, 104, 26, 104, 51, 67, 34, 104, 155, 32, 10, 96, 26, 247, 254, 248, 49, 104, - 51, 104, 155, 104, 26, 66, 34, 208, 243, 70, 81, 126, 10, 42, 0, 209, 0, 231, 98, 155, 1, 28, 17, 106, 88, 35, 15, 64, - 25, 6, 19, 43, 0, 219, 71, 34, 1, 28, 19, 64, 139, 67, 152, 75, 36, 104, 27, 9, 219, 64, 19, 64, 139, 67, 3, 152, 1, - 98, 67, 231, 77, 75, 32, 28, 34, 64, 26, 35, 128, 4, 18, 5, 219, 67, 26, 28, 17, 67, 1, 230, 24, 70, 81, 126, 75, 43, - 0, 208, 10, 75, 26, 104, 27, 70, 152, 229, 214, 70, 82, 104, 144, 240, 3, 249, 196, 70, 83, 96, 216, 229, 199, 75, 22, - 104, 27, 70, 152, 229, 203, 70, 83, 104, 216, 240, 3, 249, 161, 70, 80, 126, 3, 43, 0, 208, 0, 231, 102, 104, 64, 33, - 8, 240, 3, 249, 160, 231, 97, 75, 14, 96, 26, 104, 8, 33, 8, 240, 3, 249, 177, 70, 82, 96, 80, 229, 158, 105, 187, 34, - 128, 67, 147, 97, 187, 230, 52, 33, 16, 230, 39, 49, 16, 231, 181, 49, 16, 230, 202, 70, 192, 19, 112, 136, 44, 0, 0, - 7, 255, 19, 112, 136, 24, 19, 112, 136, 28, 19, 112, 136, 8, 181, 48, 176, 137, 70, 109, 118, 41, 9, 201, 118, 105, - 33, 128, 0, 137, 145, 7, 36, 0, 70, 105, 148, 0, 146, 4, 147, 2, 247, 255, 253, 68, 176, 9, 188, 48, 188, 2, 71, 8, - 181, 240, 70, 71, 180, 128, 176, 136, 70, 128, 70, 104, 48, 58, 136, 5, 48, 4, 136, 6, 72, 40, 4, 45, 104, 4, 32, 248, - 88, 32, 4, 54, 112, 66, 2, 26, 10, 27, 67, 26, 4, 18, 12, 19, 112, 195, 10, 43, 14, 45, 67, 43, 14, 18, 4, 27, 112, - 130, 12, 55, 12, 26, 14, 27, 113, 3, 14, 54, 2, 59, 67, 51, 4, 27, 113, 66, 14, 26, 12, 27, 112, 1, 113, 195, 70, 108, - 35, 0, 9, 201, 113, 130, 118, 35, 118, 97, 35, 64, 144, 0, 147, 7, 152, 16, 75, 20, 151, 4, 66, 152, 216, 12, 96, 160, - 70, 105, 70, 64, 247, 255, 253, 3, 28, 5, 176, 8, 28, 40, 188, 4, 70, 144, 188, 240, 188, 2, 71, 8, 28, 56, 240, 3, - 248, 252, 28, 58, 153, 16, 144, 2, 240, 4, 250, 157, 70, 105, 70, 64, 247, 255, 252, 239, 153, 2, 28, 5, 28, 58, 152, - 16, 240, 4, 250, 147, 152, 2, 240, 3, 248, 222, 231, 226, 70, 192, 19, 112, 128, 44, 19, 136, 0, 0, 181, 0, 176, 133, - 42, 0, 209, 4, 32, 3, 66, 64, 176, 5, 188, 2, 71, 8, 28, 19, 34, 0, 145, 0, 146, 1, 146, 2, 33, 1, 34, 11, 247, 255, - 255, 142, 231, 242, 70, 192, 181, 0, 176, 133, 34, 0, 146, 0, 146, 1, 146, 2, 28, 11, 34, 9, 33, 0, 247, 255, 255, 129, - 176, 5, 188, 2, 71, 8, 181, 112, 176, 132, 28, 4, 32, 1, 28, 14, 240, 3, 248, 187, 28, 5, 40, 0, 208, 23, 35, 0, 147, - 0, 35, 1, 147, 1, 144, 2, 33, 128, 28, 32, 34, 8, 35, 0, 247, 255, 255, 105, 28, 4, 40, 0, 219, 1, 120, 43, 112, 51, - 28, 40, 240, 3, 248, 153, 176, 4, 28, 32, 188, 112, 188, 2, 71, 8, 36, 4, 66, 100, 231, 247, 70, 192, 181, 16, 176, - 132, 28, 20, 70, 106, 50, 27, 120, 18, 2, 36, 67, 28, 35, 0, 147, 0, 146, 1, 145, 2, 34, 6, 33, 128, 28, 35, 247, 255, - 255, 71, 176, 4, 188, 16, 188, 2, 71, 8, 70, 192, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 70, 129, 72, 84, - 70, 75, 104, 2, 51, 16, 104, 145, 0, 155, 24, 201, 70, 75, 176, 139, 0, 155, 147, 6, 68, 75, 0, 219, 70, 147, 28, 26, - 50, 88, 68, 90, 146, 9, 68, 91, 34, 0, 103, 26, 104, 3, 74, 74, 104, 155, 29, 14, 104, 91, 104, 75, 64, 19, 43, 1, 208, - 11, 36, 1, 66, 100, 176, 11, 28, 32, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 34, 0, 75, - 64, 70, 146, 70, 74, 50, 1, 70, 152, 4, 19, 39, 128, 12, 27, 0, 127, 146, 5, 147, 4, 75, 60, 32, 10, 96, 51, 247, 253, - 254, 214, 75, 58, 32, 100, 96, 51, 247, 253, 254, 209, 75, 57, 70, 66, 96, 51, 104, 20, 77, 56, 224, 1, 66, 171, 216, - 12, 32, 10, 247, 253, 254, 164, 104, 51, 66, 59, 208, 84, 70, 66, 104, 19, 27, 27, 213, 243, 104, 20, 66, 171, 217, - 242, 36, 2, 66, 100, 104, 50, 75, 47, 64, 19, 43, 5, 208, 18, 36, 1, 66, 100, 35, 1, 68, 154, 70, 82, 42, 4, 209, 210, - 44, 0, 219, 186, 70, 77, 53, 1, 155, 6, 34, 0, 68, 75, 0, 219, 68, 91, 103, 218, 103, 29, 231, 176, 35, 192, 1, 27, - 64, 26, 35, 128, 0, 219, 66, 154, 208, 229, 44, 0, 209, 229, 32, 100, 247, 253, 254, 150, 75, 30, 33, 128, 147, 7, 104, - 26, 75, 29, 146, 8, 154, 7, 96, 19, 35, 22, 147, 1, 155, 9, 34, 6, 147, 2, 28, 24, 35, 128, 0, 91, 148, 0, 247, 255, - 254, 173, 28, 4, 40, 0, 219, 19, 34, 0, 146, 0, 146, 1, 146, 2, 155, 4, 34, 5, 152, 9, 33, 0, 157, 5, 247, 255, 254, - 159, 155, 8, 154, 7, 28, 4, 96, 19, 40, 0, 219, 187, 231, 195, 36, 0, 231, 177, 155, 8, 154, 7, 96, 19, 231, 180, 19, - 112, 128, 44, 0, 0, 32, 1, 13, 128, 0, 16, 0, 0, 24, 3, 0, 0, 25, 3, 0, 0, 16, 1, 0, 0, 15, 159, 0, 0, 32, 5, 19, 112, - 128, 48, 0, 3, 13, 64, 181, 240, 77, 29, 176, 129, 104, 43, 28, 4, 104, 158, 35, 1, 96, 179, 247, 255, 255, 50, 28, - 7, 40, 0, 219, 17, 104, 43, 34, 55, 104, 153, 176, 1, 104, 75, 28, 56, 64, 19, 96, 75, 104, 43, 104, 154, 35, 4, 96, - 147, 104, 43, 104, 155, 104, 27, 188, 240, 188, 2, 71, 8, 104, 43, 34, 55, 104, 153, 32, 10, 104, 75, 52, 16, 64, 19, - 96, 75, 104, 43, 0, 164, 104, 155, 25, 52, 104, 27, 247, 253, 254, 38, 75, 7, 32, 50, 96, 99, 247, 253, 254, 33, 75, - 6, 32, 100, 96, 99, 247, 253, 254, 28, 75, 4, 96, 99, 231, 209, 70, 192, 19, 112, 128, 44, 0, 0, 24, 3, 0, 0, 25, 3, - 0, 0, 16, 1, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 73, 170, 0, 131, 104, 10, 70, 155, 24, 27, 70, 146, - 0, 219, 28, 26, 37, 0, 68, 83, 176, 133, 50, 88, 103, 29, 28, 6, 70, 136, 32, 50, 70, 81, 24, 140, 247, 253, 253, 246, - 35, 128, 39, 22, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 151, 1, 148, 2, 247, 255, 254, 21, 40, 0, 219, 0, 225, 10, 32, - 100, 247, 253, 253, 229, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 151, 1, 148, 2, 247, 255, 254, 5, 40, 0, 219, - 0, 224, 250, 32, 100, 247, 253, 253, 213, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 151, 1, 148, 2, 247, 255, - 253, 245, 40, 0, 219, 0, 224, 234, 32, 100, 247, 253, 253, 197, 28, 48, 247, 254, 251, 98, 32, 100, 247, 253, 253, 191, - 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 151, 1, 148, 2, 247, 255, 253, 223, 40, 0, 219, 0, 224, 212, 28, 48, - 247, 254, 251, 79, 32, 100, 247, 253, 253, 172, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 151, 1, 148, 2, 247, - 255, 253, 204, 40, 0, 219, 0, 224, 193, 28, 48, 247, 254, 251, 60, 32, 100, 247, 253, 253, 153, 35, 128, 28, 32, 33, - 128, 34, 6, 0, 91, 149, 0, 151, 1, 148, 2, 247, 255, 253, 185, 40, 0, 219, 0, 224, 174, 70, 66, 104, 19, 28, 55, 104, - 155, 55, 16, 0, 186, 24, 157, 104, 106, 35, 128, 1, 155, 66, 26, 209, 0, 64, 90, 35, 46, 67, 154, 96, 106, 32, 5, 247, - 253, 252, 65, 35, 128, 104, 106, 1, 155, 66, 26, 208, 0, 64, 90, 35, 46, 67, 154, 96, 106, 32, 5, 247, 253, 252, 53, - 75, 93, 32, 5, 96, 107, 247, 253, 252, 48, 32, 100, 247, 253, 253, 101, 28, 48, 247, 254, 251, 2, 32, 100, 247, 253, - 253, 95, 35, 0, 147, 0, 35, 22, 147, 1, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 148, 2, 247, 255, 253, 125, 40, 0, 218, - 115, 70, 65, 104, 11, 0, 186, 104, 155, 24, 157, 104, 106, 35, 128, 1, 155, 66, 26, 209, 0, 64, 90, 35, 46, 67, 154, - 96, 106, 32, 5, 247, 253, 252, 8, 35, 128, 104, 106, 1, 155, 66, 26, 208, 0, 64, 90, 35, 46, 67, 154, 96, 106, 32, 5, - 247, 253, 251, 252, 75, 64, 32, 5, 96, 107, 247, 253, 251, 247, 32, 100, 247, 253, 253, 44, 28, 48, 247, 254, 250, 201, - 32, 100, 247, 253, 253, 38, 35, 0, 147, 0, 35, 22, 147, 1, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 148, 2, 247, 255, - 253, 68, 40, 0, 218, 58, 70, 66, 104, 19, 0, 186, 104, 155, 24, 157, 104, 106, 35, 128, 1, 155, 66, 26, 209, 0, 64, - 90, 35, 46, 67, 154, 96, 106, 32, 5, 247, 253, 251, 207, 35, 128, 104, 106, 1, 155, 66, 26, 208, 0, 64, 90, 35, 46, - 67, 154, 96, 106, 32, 5, 247, 253, 251, 195, 75, 36, 32, 5, 96, 107, 247, 253, 251, 190, 32, 100, 247, 253, 252, 243, - 28, 48, 247, 254, 250, 144, 32, 100, 247, 253, 252, 237, 35, 0, 147, 0, 35, 22, 147, 1, 35, 128, 28, 32, 33, 128, 34, - 6, 0, 91, 148, 2, 247, 255, 253, 11, 40, 0, 218, 1, 72, 23, 224, 30, 33, 128, 2, 73, 4, 51, 24, 91, 12, 27, 28, 114, - 70, 153, 32, 50, 37, 0, 70, 144, 247, 253, 252, 209, 28, 32, 33, 0, 34, 5, 70, 75, 149, 0, 149, 1, 149, 2, 247, 255, - 252, 242, 40, 0, 219, 23, 70, 89, 25, 139, 0, 219, 68, 83, 34, 0, 103, 218, 70, 66, 103, 26, 176, 5, 188, 60, 70, 144, - 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 70, 192, 19, 112, 128, 44, 0, 0, 24, 1, 255, 255, 247, 103, 70, - 89, 25, 139, 0, 219, 70, 82, 24, 215, 70, 67, 103, 59, 103, 253, 33, 2, 34, 1, 35, 0, 28, 32, 149, 0, 149, 1, 149, 2, - 247, 255, 252, 199, 32, 50, 247, 253, 252, 154, 35, 22, 147, 1, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 148, - 2, 247, 255, 252, 185, 40, 0, 218, 0, 224, 199, 32, 50, 247, 253, 252, 137, 37, 0, 28, 32, 33, 0, 34, 5, 70, 75, 149, - 0, 149, 1, 149, 2, 247, 255, 252, 169, 40, 0, 218, 182, 70, 89, 25, 139, 0, 219, 70, 82, 24, 215, 70, 67, 103, 59, 103, - 253, 33, 2, 34, 1, 35, 0, 28, 32, 149, 0, 149, 1, 149, 2, 247, 255, 252, 150, 32, 50, 247, 253, 252, 105, 35, 22, 147, - 1, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 148, 2, 247, 255, 252, 136, 40, 0, 218, 0, 224, 152, 32, 50, 247, - 253, 252, 88, 37, 0, 28, 32, 33, 0, 34, 5, 70, 75, 149, 0, 149, 1, 149, 2, 247, 255, 252, 120, 40, 0, 219, 0, 231, 132, - 70, 89, 25, 139, 0, 219, 70, 82, 24, 215, 70, 67, 103, 59, 103, 253, 33, 2, 34, 1, 35, 0, 28, 32, 149, 0, 149, 1, 149, - 2, 247, 255, 252, 100, 32, 50, 247, 253, 252, 55, 35, 22, 147, 1, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 148, - 2, 247, 255, 252, 86, 40, 0, 219, 105, 32, 50, 247, 253, 252, 39, 37, 0, 28, 32, 33, 0, 34, 5, 70, 75, 149, 0, 149, - 1, 149, 2, 247, 255, 252, 71, 40, 0, 219, 0, 231, 83, 70, 89, 25, 139, 0, 219, 70, 82, 24, 215, 70, 67, 103, 59, 103, - 253, 33, 2, 34, 1, 35, 0, 28, 32, 149, 0, 149, 1, 149, 2, 247, 255, 252, 51, 32, 50, 247, 253, 252, 6, 35, 22, 147, - 1, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 148, 2, 247, 255, 252, 37, 40, 0, 218, 0, 103, 61, 32, 50, 247, 253, - 251, 245, 37, 0, 28, 32, 33, 0, 34, 5, 70, 75, 149, 0, 149, 1, 149, 2, 247, 255, 252, 21, 40, 0, 219, 0, 231, 33, 70, - 89, 25, 139, 0, 219, 70, 82, 24, 214, 70, 67, 103, 51, 103, 245, 33, 2, 34, 1, 35, 0, 28, 32, 149, 0, 149, 1, 149, 2, - 247, 255, 252, 1, 32, 50, 247, 253, 251, 212, 35, 22, 147, 1, 35, 128, 28, 32, 33, 128, 34, 6, 0, 91, 149, 0, 148, 2, - 247, 255, 251, 243, 40, 0, 219, 8, 32, 1, 66, 64, 231, 5, 103, 61, 231, 53, 103, 61, 231, 100, 103, 61, 231, 147, 103, - 53, 72, 1, 230, 252, 70, 192, 255, 255, 247, 62, 181, 48, 77, 11, 176, 129, 104, 43, 28, 4, 104, 154, 35, 1, 96, 147, - 247, 254, 249, 78, 40, 0, 219, 2, 28, 32, 247, 255, 253, 153, 104, 43, 176, 1, 104, 154, 35, 4, 96, 147, 188, 48, 188, - 2, 71, 8, 70, 192, 19, 112, 128, 44, 181, 48, 77, 19, 35, 0, 104, 42, 176, 129, 103, 83, 104, 43, 104, 155, 108, 91, - 7, 218, 212, 4, 32, 0, 176, 1, 188, 48, 188, 2, 71, 8, 32, 0, 247, 255, 253, 55, 28, 4, 32, 20, 247, 253, 251, 135, - 104, 43, 104, 155, 108, 90, 44, 0, 219, 4, 75, 6, 64, 26, 75, 6, 66, 154, 208, 2, 32, 0, 247, 255, 255, 194, 32, 101, - 66, 64, 231, 228, 70, 192, 19, 112, 128, 44, 0, 0, 57, 5, 0, 0, 16, 5, 181, 240, 70, 87, 70, 70, 180, 192, 38, 160, - 176, 137, 28, 5, 70, 136, 28, 23, 33, 255, 34, 13, 89, 128, 240, 3, 254, 186, 35, 144, 123, 42, 88, 232, 35, 0, 70, - 105, 147, 0, 35, 128, 89, 172, 0, 155, 118, 10, 9, 210, 147, 7, 118, 74, 35, 13, 147, 4, 148, 2, 247, 255, 248, 186, - 40, 0, 219, 2, 40, 13, 208, 7, 72, 41, 176, 9, 188, 12, 70, 144, 70, 154, 188, 240, 188, 2, 71, 8, 89, 171, 36, 255, - 104, 25, 104, 90, 104, 158, 123, 27, 70, 148, 70, 154, 14, 10, 6, 11, 67, 26, 2, 36, 28, 11, 32, 255, 64, 35, 4, 0, - 2, 27, 64, 1, 67, 26, 10, 9, 75, 28, 67, 10, 66, 154, 208, 1, 72, 27, 231, 222, 47, 0, 208, 11, 6, 51, 14, 50, 67, 26, - 28, 51, 64, 35, 2, 27, 67, 26, 28, 51, 64, 3, 10, 27, 67, 26, 96, 58, 70, 67, 43, 0, 208, 1, 70, 84, 112, 28, 70, 99, - 14, 26, 6, 27, 67, 26, 35, 255, 70, 100, 2, 27, 64, 35, 2, 27, 67, 26, 35, 255, 4, 27, 32, 152, 64, 35, 10, 27, 88, - 41, 67, 26, 66, 145, 208, 1, 72, 8, 231, 182, 74, 8, 28, 139, 64, 19, 74, 8, 64, 10, 67, 19, 80, 43, 32, 0, 231, 173, - 70, 192, 255, 255, 216, 237, 83, 66, 83, 85, 255, 255, 216, 236, 255, 255, 216, 235, 0, 0, 255, 255, 255, 255, 0, 0, - 181, 240, 70, 87, 70, 78, 70, 69, 180, 224, 78, 93, 28, 5, 104, 51, 176, 132, 70, 153, 75, 91, 96, 51, 70, 152, 35, - 144, 88, 192, 70, 154, 75, 89, 104, 27, 104, 154, 105, 195, 50, 68, 0, 155, 24, 210, 104, 19, 34, 1, 66, 19, 209, 0, - 224, 156, 70, 67, 96, 51, 75, 83, 104, 27, 43, 0, 208, 51, 136, 235, 34, 255, 147, 0, 39, 0, 35, 0, 33, 33, 151, 1, - 151, 2, 247, 255, 250, 234, 28, 4, 28, 33, 72, 76, 247, 254, 249, 251, 32, 60, 247, 253, 250, 184, 70, 67, 96, 51, 44, - 0, 218, 42, 32, 50, 247, 253, 250, 177, 70, 83, 88, 232, 33, 2, 34, 1, 35, 0, 151, 0, 151, 1, 151, 2, 247, 255, 250, - 209, 32, 5, 247, 253, 250, 164, 70, 75, 74, 64, 96, 51, 35, 1, 96, 19, 176, 4, 28, 32, 188, 28, 70, 144, 70, 153, 70, - 162, 188, 240, 188, 2, 71, 8, 147, 0, 147, 1, 147, 2, 33, 2, 35, 0, 34, 1, 247, 255, 250, 184, 32, 5, 247, 253, 250, - 139, 70, 67, 96, 51, 35, 144, 88, 232, 70, 152, 123, 43, 33, 2, 147, 0, 39, 0, 34, 1, 35, 0, 151, 1, 151, 2, 247, 255, - 250, 166, 28, 4, 32, 5, 247, 253, 250, 120, 72, 43, 28, 33, 247, 254, 249, 180, 44, 0, 219, 205, 70, 67, 88, 232, 123, - 107, 33, 2, 147, 0, 34, 1, 35, 0, 151, 1, 151, 2, 247, 255, 250, 145, 28, 4, 32, 5, 247, 253, 250, 99, 72, 34, 28, 33, - 247, 254, 249, 159, 44, 0, 219, 184, 32, 10, 247, 253, 250, 90, 70, 67, 32, 1, 88, 236, 240, 2, 251, 195, 28, 5, 40, - 0, 208, 22, 35, 1, 33, 128, 147, 1, 144, 2, 34, 8, 28, 32, 35, 0, 151, 0, 247, 255, 250, 114, 28, 4, 28, 40, 240, 2, - 251, 166, 72, 19, 28, 33, 247, 254, 249, 128, 44, 0, 219, 153, 70, 75, 96, 51, 231, 155, 33, 4, 72, 14, 66, 73, 36, - 4, 247, 254, 249, 117, 66, 100, 231, 142, 75, 8, 36, 1, 96, 26, 70, 75, 96, 51, 66, 100, 231, 140, 19, 112, 128, 48, - 0, 3, 13, 64, 19, 112, 128, 44, 19, 112, 136, 48, 19, 112, 129, 120, 19, 112, 136, 8, 19, 112, 129, 156, 19, 112, 129, - 196, 19, 112, 129, 236, 181, 0, 176, 129, 33, 0, 247, 255, 255, 41, 176, 1, 188, 2, 71, 8, 181, 240, 70, 95, 70, 86, - 70, 77, 70, 68, 180, 240, 176, 173, 28, 31, 70, 107, 51, 239, 146, 18, 120, 26, 59, 16, 120, 27, 6, 18, 147, 17, 70, - 107, 51, 227, 120, 27, 145, 19, 22, 18, 33, 175, 147, 16, 146, 15, 35, 0, 74, 203, 68, 105, 112, 11, 147, 42, 146, 14, - 96, 19, 155, 17, 14, 58, 59, 1, 6, 27, 14, 27, 147, 21, 6, 59, 67, 26, 35, 255, 2, 27, 64, 59, 2, 27, 67, 26, 35, 255, - 4, 27, 64, 59, 10, 27, 67, 26, 73, 192, 75, 192, 36, 0, 28, 6, 146, 22, 148, 20, 147, 12, 145, 11, 44, 0, 208, 0, 224, - 135, 155, 15, 153, 16, 59, 1, 6, 27, 22, 27, 147, 15, 41, 0, 208, 11, 74, 184, 75, 185, 153, 21, 146, 13, 104, 21, 96, - 19, 41, 15, 216, 0, 224, 184, 36, 3, 66, 100, 227, 129, 75, 178, 74, 179, 147, 13, 104, 25, 96, 26, 155, 21, 70, 138, - 43, 15, 216, 0, 225, 156, 33, 1, 36, 3, 66, 74, 66, 100, 70, 144, 153, 13, 70, 83, 96, 11, 72, 171, 28, 33, 247, 254, - 248, 236, 75, 170, 73, 171, 104, 27, 72, 171, 104, 154, 75, 171, 104, 85, 104, 27, 50, 68, 0, 155, 24, 210, 104, 18, - 146, 26, 247, 254, 248, 221, 4, 41, 212, 99, 74, 166, 146, 23, 4, 105, 212, 99, 74, 164, 146, 24, 4, 169, 212, 99, 74, - 162, 146, 25, 4, 233, 212, 99, 74, 160, 70, 147, 6, 169, 212, 99, 74, 158, 70, 145, 6, 233, 212, 99, 74, 156, 70, 146, - 7, 41, 212, 99, 74, 154, 70, 148, 7, 105, 212, 99, 74, 152, 7, 171, 212, 99, 73, 150, 145, 9, 33, 1, 66, 13, 209, 99, - 73, 148, 155, 25, 146, 5, 147, 0, 70, 91, 147, 1, 70, 75, 154, 9, 147, 2, 70, 83, 147, 3, 70, 99, 72, 143, 147, 4, 146, - 6, 155, 24, 145, 7, 154, 23, 28, 41, 247, 254, 248, 162, 72, 139, 153, 26, 247, 254, 248, 158, 70, 67, 43, 1, 217, 8, - 35, 1, 153, 15, 41, 0, 221, 1, 43, 0, 209, 67, 44, 0, 219, 0, 224, 211, 154, 14, 35, 1, 96, 19, 224, 210, 28, 48, 33, - 0, 247, 255, 254, 94, 28, 4, 40, 0, 218, 0, 225, 19, 32, 5, 247, 253, 249, 67, 75, 118, 104, 27, 104, 154, 75, 119, - 50, 68, 104, 27, 0, 155, 24, 210, 104, 18, 34, 0, 146, 20, 231, 96, 75, 119, 147, 23, 4, 105, 213, 155, 75, 118, 147, - 24, 4, 169, 213, 155, 75, 117, 147, 25, 4, 233, 213, 155, 75, 116, 70, 155, 6, 169, 213, 155, 75, 115, 70, 153, 6, 233, - 213, 155, 75, 114, 70, 154, 7, 41, 213, 155, 75, 113, 70, 156, 7, 105, 213, 155, 74, 112, 7, 171, 213, 155, 75, 111, - 33, 1, 147, 9, 66, 13, 208, 155, 73, 110, 231, 154, 28, 163, 43, 1, 217, 0, 231, 51, 231, 182, 36, 160, 89, 48, 40, - 0, 209, 0, 231, 65, 33, 0, 34, 31, 240, 3, 252, 91, 89, 50, 75, 102, 96, 19, 35, 152, 88, 242, 89, 48, 6, 19, 14, 17, - 67, 25, 35, 255, 2, 27, 64, 19, 2, 27, 67, 25, 35, 255, 4, 27, 64, 26, 10, 18, 67, 17, 96, 65, 89, 51, 154, 22, 33, - 79, 96, 154, 89, 50, 35, 0, 115, 19, 68, 105, 89, 51, 120, 9, 115, 89, 35, 156, 92, 243, 43, 0, 209, 0, 225, 38, 89, - 50, 35, 12, 115, 147, 36, 160, 89, 48, 153, 54, 154, 17, 48, 15, 240, 3, 251, 233, 33, 144, 88, 112, 89, 51, 70, 136, - 34, 31, 123, 113, 247, 255, 248, 227, 28, 4, 40, 31, 208, 0, 226, 133, 154, 13, 96, 21, 47, 0, 208, 27, 70, 67, 123, - 114, 88, 240, 35, 0, 169, 34, 147, 34, 35, 128, 118, 10, 0, 155, 9, 210, 97, 203, 118, 74, 97, 15, 154, 18, 96, 138, - 247, 254, 254, 30, 28, 131, 28, 4, 43, 1, 216, 0, 225, 130, 44, 0, 218, 0, 225, 95, 66, 167, 208, 0, 225, 92, 155, 13, - 154, 13, 73, 38, 104, 27, 96, 17, 70, 105, 28, 48, 49, 175, 170, 42, 70, 152, 247, 255, 253, 45, 28, 4, 40, 0, 218, - 0, 225, 113, 155, 13, 70, 66, 96, 26, 28, 163, 43, 1, 216, 0, 231, 60, 155, 42, 43, 0, 208, 7, 73, 24, 104, 11, 43, - 0, 208, 3, 34, 175, 35, 1, 68, 106, 112, 19, 44, 0, 218, 0, 231, 40, 153, 12, 104, 11, 43, 0, 208, 0, 224, 206, 36, - 0, 153, 14, 35, 0, 96, 11, 155, 57, 43, 0, 208, 4, 33, 175, 68, 105, 28, 26, 120, 11, 112, 19, 155, 58, 43, 0, 208, - 2, 28, 25, 155, 42, 96, 11, 176, 45, 28, 32, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 70, - 192, 19, 112, 136, 8, 19, 112, 130, 104, 19, 112, 136, 64, 19, 112, 128, 48, 0, 3, 13, 64, 19, 112, 130, 28, 19, 112, - 128, 44, 19, 112, 130, 48, 19, 112, 128, 204, 19, 112, 136, 20, 19, 112, 134, 240, 19, 112, 129, 56, 19, 112, 129, 96, - 19, 112, 128, 228, 19, 112, 128, 236, 19, 112, 128, 248, 19, 112, 129, 0, 19, 112, 129, 8, 19, 112, 129, 16, 19, 112, - 129, 24, 19, 112, 129, 32, 19, 112, 129, 40, 19, 112, 129, 48, 85, 83, 66, 67, 32, 60, 247, 253, 248, 47, 75, 196, 104, - 27, 104, 154, 75, 195, 50, 68, 104, 27, 0, 155, 24, 210, 155, 20, 104, 18, 51, 1, 147, 20, 43, 2, 221, 0, 230, 205, - 32, 10, 247, 253, 248, 29, 35, 1, 230, 192, 36, 160, 89, 48, 40, 0, 209, 0, 230, 93, 33, 0, 34, 31, 240, 3, 251, 106, - 89, 50, 75, 183, 96, 19, 35, 152, 88, 242, 89, 48, 6, 19, 14, 17, 67, 25, 35, 255, 2, 27, 64, 19, 2, 27, 67, 25, 35, - 255, 4, 27, 64, 26, 10, 18, 67, 17, 96, 65, 89, 51, 153, 22, 96, 153, 89, 50, 35, 128, 66, 91, 115, 19, 34, 79, 68, - 106, 89, 51, 120, 18, 115, 90, 35, 156, 92, 243, 43, 0, 208, 70, 89, 50, 35, 12, 115, 147, 36, 160, 89, 48, 153, 54, - 154, 17, 48, 15, 37, 144, 240, 3, 250, 247, 89, 51, 89, 112, 123, 113, 34, 31, 247, 254, 255, 243, 28, 4, 40, 31, 208, - 0, 225, 156, 155, 13, 70, 82, 96, 26, 47, 0, 209, 0, 231, 41, 123, 50, 35, 0, 169, 34, 147, 34, 35, 128, 89, 112, 0, - 155, 118, 10, 9, 210, 118, 74, 97, 203, 97, 15, 154, 18, 96, 138, 247, 254, 253, 45, 28, 4, 40, 0, 219, 32, 28, 163, - 43, 1, 217, 0, 231, 12, 44, 0, 219, 0, 231, 15, 230, 92, 155, 17, 89, 50, 43, 6, 217, 0, 225, 108, 35, 6, 115, 147, - 230, 211, 34, 175, 68, 106, 120, 19, 43, 0, 209, 0, 231, 42, 76, 132, 35, 1, 230, 76, 155, 17, 89, 50, 43, 6, 217, 0, - 225, 88, 35, 6, 115, 147, 231, 179, 72, 128, 28, 33, 247, 253, 254, 219, 75, 122, 72, 126, 104, 27, 73, 126, 104, 154, - 75, 120, 104, 85, 104, 27, 50, 68, 0, 155, 24, 210, 104, 18, 146, 29, 247, 253, 254, 204, 4, 43, 212, 90, 73, 120, 145, - 27, 4, 107, 212, 83, 73, 118, 145, 28, 4, 171, 212, 76, 73, 116, 70, 139, 4, 235, 212, 69, 73, 114, 70, 137, 6, 171, - 212, 62, 73, 112, 70, 138, 6, 235, 212, 55, 73, 110, 70, 136, 7, 43, 212, 48, 73, 108, 70, 140, 7, 107, 212, 42, 74, - 106, 7, 169, 212, 32, 33, 1, 75, 104, 66, 13, 209, 32, 73, 103, 145, 8, 70, 89, 145, 0, 70, 73, 145, 1, 70, 81, 145, - 2, 146, 5, 70, 65, 154, 8, 145, 3, 70, 97, 145, 4, 147, 6, 146, 7, 28, 41, 72, 95, 154, 27, 155, 28, 247, 253, 254, - 145, 72, 94, 153, 29, 247, 253, 254, 141, 231, 139, 76, 92, 229, 238, 33, 1, 75, 92, 66, 13, 208, 222, 73, 91, 145, - 8, 231, 221, 74, 91, 231, 211, 74, 91, 70, 148, 231, 205, 74, 90, 70, 144, 231, 198, 74, 90, 70, 146, 231, 191, 74, - 89, 70, 145, 231, 184, 74, 89, 70, 147, 231, 177, 74, 88, 146, 28, 231, 170, 74, 88, 146, 27, 231, 163, 44, 0, 219, - 0, 230, 127, 15, 227, 229, 204, 152, 11, 28, 33, 247, 253, 254, 99, 75, 62, 72, 66, 104, 27, 73, 81, 104, 154, 75, 60, - 104, 85, 104, 27, 50, 68, 0, 155, 24, 210, 104, 18, 146, 33, 247, 253, 254, 84, 4, 43, 213, 0, 224, 150, 73, 60, 145, - 30, 4, 107, 213, 0, 224, 150, 73, 57, 145, 31, 4, 171, 213, 0, 224, 150, 73, 55, 145, 32, 4, 235, 213, 0, 224, 150, - 73, 52, 70, 139, 6, 171, 213, 0, 224, 150, 73, 50, 70, 137, 6, 235, 213, 0, 224, 150, 73, 47, 70, 138, 7, 43, 213, 0, - 224, 150, 73, 45, 70, 140, 7, 107, 213, 0, 224, 150, 74, 42, 7, 169, 213, 0, 224, 150, 75, 40, 147, 9, 35, 1, 66, 29, - 208, 0, 224, 150, 73, 37, 155, 32, 146, 5, 147, 0, 70, 91, 147, 1, 70, 75, 154, 9, 147, 2, 70, 83, 147, 3, 70, 99, 72, - 32, 147, 4, 146, 6, 145, 7, 155, 31, 28, 41, 154, 30, 247, 253, 254, 15, 72, 29, 153, 33, 247, 253, 254, 11, 28, 99, - 209, 0, 229, 117, 123, 51, 36, 144, 89, 48, 147, 0, 34, 1, 35, 0, 33, 2, 147, 1, 147, 2, 247, 254, 254, 231, 123, 50, - 89, 48, 6, 19, 106, 68, 43, 0, 219, 107, 33, 0, 35, 15, 64, 19, 24, 203, 33, 1, 64, 153, 67, 140, 70, 105, 98, 68, 49, - 175, 28, 48, 170, 42, 247, 255, 251, 57, 28, 4, 230, 13, 70, 192, 19, 112, 128, 44, 19, 112, 136, 20, 85, 83, 66, 67, - 255, 255, 216, 234, 19, 112, 130, 60, 19, 112, 128, 204, 19, 112, 130, 84, 19, 112, 134, 240, 19, 112, 129, 56, 19, - 112, 129, 96, 255, 255, 216, 233, 19, 112, 129, 40, 19, 112, 129, 48, 19, 112, 129, 32, 19, 112, 129, 24, 19, 112, 129, - 16, 19, 112, 129, 8, 19, 112, 129, 0, 19, 112, 128, 248, 19, 112, 128, 236, 19, 112, 128, 228, 19, 112, 130, 120, 74, - 40, 146, 30, 4, 107, 212, 0, 231, 104, 74, 39, 146, 31, 4, 171, 212, 0, 231, 104, 74, 37, 146, 32, 4, 235, 212, 0, 231, - 104, 74, 36, 70, 147, 6, 171, 212, 0, 231, 104, 74, 34, 70, 145, 6, 235, 212, 0, 231, 104, 74, 33, 70, 146, 7, 43, 212, - 0, 231, 104, 74, 31, 70, 148, 7, 107, 212, 0, 231, 104, 74, 30, 7, 169, 212, 0, 231, 104, 73, 29, 35, 1, 145, 9, 66, - 29, 209, 0, 231, 104, 73, 27, 231, 103, 33, 16, 231, 146, 35, 16, 115, 147, 230, 90, 35, 16, 115, 147, 229, 102, 40, - 0, 219, 10, 76, 22, 154, 13, 35, 1, 96, 21, 228, 225, 40, 0, 219, 10, 75, 19, 76, 18, 70, 152, 228, 130, 154, 13, 28, - 131, 96, 21, 43, 1, 216, 0, 228, 221, 228, 211, 154, 13, 70, 81, 28, 131, 96, 17, 70, 152, 228, 120, 70, 192, 19, 112, - 128, 228, 19, 112, 128, 236, 19, 112, 128, 248, 19, 112, 129, 0, 19, 112, 129, 8, 19, 112, 129, 16, 19, 112, 129, 24, - 19, 112, 129, 32, 19, 112, 129, 40, 19, 112, 129, 48, 255, 255, 216, 238, 255, 255, 216, 240, 181, 240, 28, 30, 35, - 160, 28, 23, 88, 195, 34, 128, 1, 18, 24, 156, 176, 137, 44, 0, 208, 44, 70, 106, 50, 30, 1, 75, 112, 83, 35, 37, 112, - 19, 35, 2, 147, 1, 35, 0, 147, 2, 147, 3, 147, 4, 35, 10, 146, 0, 147, 5, 28, 34, 35, 8, 247, 255, 251, 224, 40, 0, - 219, 19, 173, 6, 28, 40, 28, 33, 34, 4, 240, 3, 248, 254, 46, 0, 208, 1, 155, 6, 96, 51, 29, 33, 28, 40, 34, 4, 240, - 3, 248, 245, 47, 0, 208, 1, 155, 6, 96, 59, 32, 0, 176, 9, 188, 240, 188, 2, 71, 8, 32, 4, 66, 64, 231, 248, 70, 192, - 181, 240, 70, 87, 70, 78, 70, 69, 180, 224, 176, 136, 70, 109, 53, 26, 35, 18, 112, 43, 1, 75, 36, 0, 112, 107, 35, - 36, 113, 43, 112, 172, 112, 236, 113, 108, 35, 160, 88, 195, 34, 128, 1, 18, 24, 158, 28, 7, 70, 136, 46, 0, 208, 49, - 33, 0, 34, 36, 28, 48, 240, 3, 249, 12, 35, 6, 34, 10, 70, 153, 147, 1, 70, 146, 146, 5, 28, 56, 70, 65, 28, 50, 35, - 36, 149, 0, 148, 2, 148, 3, 148, 4, 247, 255, 251, 146, 40, 0, 218, 18, 33, 0, 34, 36, 28, 48, 240, 3, 248, 245, 70, - 75, 70, 82, 147, 1, 146, 5, 28, 56, 70, 65, 28, 50, 35, 36, 149, 0, 148, 2, 148, 3, 148, 4, 247, 255, 251, 125, 176, - 8, 188, 28, 70, 144, 70, 153, 70, 162, 188, 240, 188, 2, 71, 8, 32, 4, 66, 64, 231, 244, 181, 240, 70, 87, 70, 70, 180, - 192, 35, 160, 88, 195, 34, 128, 176, 141, 1, 18, 24, 159, 70, 109, 35, 47, 68, 107, 36, 0, 53, 31, 28, 6, 70, 136, 112, - 28, 28, 40, 33, 0, 34, 16, 70, 154, 240, 3, 248, 196, 47, 0, 208, 89, 35, 6, 112, 44, 147, 1, 35, 1, 147, 2, 70, 82, - 35, 10, 146, 3, 147, 5, 70, 65, 35, 0, 28, 48, 34, 0, 148, 4, 149, 0, 247, 255, 251, 71, 28, 4, 28, 33, 72, 37, 247, - 253, 252, 148, 28, 99, 208, 54, 70, 82, 120, 19, 43, 0, 208, 58, 35, 3, 70, 66, 112, 43, 1, 83, 36, 0, 112, 107, 33, - 0, 35, 18, 34, 18, 28, 56, 113, 43, 113, 108, 240, 3, 248, 152, 35, 6, 147, 1, 35, 10, 147, 5, 70, 65, 28, 48, 28, 58, - 35, 18, 148, 2, 148, 3, 148, 4, 149, 0, 247, 255, 251, 32, 28, 4, 28, 33, 72, 18, 247, 253, 252, 109, 44, 0, 219, 15, - 120, 185, 35, 15, 64, 25, 70, 83, 112, 25, 72, 14, 247, 253, 252, 99, 70, 82, 120, 19, 59, 2, 6, 27, 14, 27, 43, 2, - 216, 0, 76, 10, 176, 13, 28, 32, 188, 12, 70, 144, 70, 154, 188, 240, 188, 2, 71, 8, 44, 0, 218, 245, 231, 193, 36, - 4, 66, 100, 231, 241, 70, 192, 19, 112, 130, 132, 19, 112, 130, 168, 19, 112, 130, 200, 255, 255, 216, 239, 181, 240, - 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 123, 131, 28, 14, 176, 137, 28, 5, 66, 179, 216, 11, 36, 3, 66, 100, 176, - 9, 28, 32, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 74, 60, 79, 61, 72, 61, 96, 23, 33, - 0, 70, 145, 247, 253, 252, 36, 28, 40, 28, 49, 247, 255, 255, 92, 28, 4, 40, 0, 219, 73, 70, 75, 34, 26, 68, 106, 96, - 31, 35, 18, 112, 19, 1, 115, 112, 83, 39, 0, 35, 36, 113, 19, 112, 151, 112, 215, 113, 87, 35, 160, 70, 144, 88, 235, - 34, 128, 1, 18, 24, 210, 70, 146, 42, 0, 208, 54, 28, 16, 33, 0, 34, 36, 240, 3, 248, 25, 70, 67, 147, 0, 34, 6, 35, - 10, 146, 1, 147, 5, 70, 155, 28, 40, 28, 49, 70, 82, 35, 36, 151, 2, 151, 3, 151, 4, 247, 255, 250, 159, 28, 4, 40, - 0, 218, 38, 33, 0, 34, 36, 70, 80, 240, 3, 248, 1, 70, 66, 146, 0, 35, 6, 70, 90, 147, 1, 146, 5, 28, 40, 28, 49, 70, - 82, 35, 36, 151, 2, 151, 3, 151, 4, 247, 255, 250, 136, 28, 4, 40, 0, 218, 15, 72, 21, 28, 33, 247, 253, 251, 211, 75, - 17, 70, 74, 96, 19, 231, 152, 33, 4, 72, 16, 66, 73, 36, 4, 247, 253, 251, 201, 66, 100, 231, 243, 28, 33, 72, 12, 247, - 253, 251, 195, 28, 51, 29, 50, 51, 20, 0, 146, 0, 155, 28, 49, 24, 170, 24, 235, 28, 40, 247, 255, 254, 104, 28, 4, - 28, 33, 72, 5, 247, 253, 251, 179, 231, 222, 19, 112, 128, 48, 0, 15, 66, 64, 19, 112, 130, 236, 19, 112, 131, 8, 19, - 112, 131, 28, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 176, 141, 144, 5, 32, 22, 70, 137, 240, 1, 253, 202, - 28, 4, 144, 11, 40, 0, 209, 0, 226, 13, 35, 0, 147, 0, 35, 18, 147, 1, 35, 128, 144, 2, 33, 128, 152, 5, 34, 6, 0, 91, - 247, 254, 252, 117, 144, 6, 40, 0, 219, 0, 224, 142, 152, 11, 240, 1, 253, 166, 70, 74, 70, 73, 124, 137, 124, 215, - 6, 11, 4, 58, 67, 26, 70, 75, 70, 140, 125, 30, 70, 73, 125, 76, 2, 51, 67, 19, 28, 33, 67, 25, 209, 0, 225, 222, 70, - 74, 124, 82, 70, 144, 42, 0, 209, 0, 225, 230, 35, 0, 70, 155, 70, 154, 70, 82, 24, 141, 122, 107, 122, 170, 6, 27, - 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 208, 82, 121, 43, 43, 0, 208, 58, 39, 0, 38, 0, 224, - 10, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 25, 132, 123, 163, 123, - 226, 6, 27, 4, 18, 67, 26, 124, 35, 2, 27, 67, 19, 124, 98, 28, 16, 67, 24, 208, 1, 240, 1, 253, 93, 122, 99, 122, 162, - 6, 27, 4, 18, 67, 26, 122, 227, 2, 27, 67, 19, 123, 34, 28, 16, 67, 24, 208, 1, 240, 1, 253, 79, 121, 43, 55, 1, 54, - 18, 66, 159, 219, 210, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 240, - 1, 253, 61, 70, 74, 70, 75, 70, 73, 124, 137, 124, 91, 124, 215, 70, 152, 4, 58, 6, 11, 67, 26, 70, 75, 70, 140, 125, - 30, 70, 73, 125, 76, 2, 51, 67, 19, 28, 33, 67, 25, 34, 1, 35, 13, 68, 147, 68, 154, 69, 195, 219, 0, 225, 123, 70, - 97, 6, 11, 4, 58, 67, 26, 2, 51, 67, 19, 28, 33, 67, 25, 231, 142, 28, 33, 34, 18, 70, 72, 240, 2, 254, 199, 28, 32, - 240, 1, 253, 18, 70, 73, 120, 138, 120, 203, 2, 18, 67, 19, 4, 27, 10, 26, 14, 27, 67, 26, 4, 18, 12, 19, 14, 18, 112, - 138, 122, 10, 112, 203, 122, 75, 2, 18, 67, 19, 4, 27, 10, 26, 14, 27, 67, 26, 4, 18, 12, 19, 14, 18, 114, 10, 122, - 138, 114, 75, 122, 203, 2, 18, 67, 19, 4, 27, 10, 26, 14, 27, 67, 26, 4, 18, 12, 19, 14, 18, 114, 138, 123, 10, 114, - 203, 123, 75, 2, 18, 67, 19, 4, 27, 10, 26, 14, 27, 67, 26, 4, 18, 12, 19, 115, 75, 124, 75, 14, 18, 0, 88, 24, 192, - 0, 128, 115, 10, 24, 192, 240, 1, 252, 226, 70, 74, 14, 3, 116, 147, 12, 3, 116, 211, 10, 3, 117, 19, 117, 80, 40, 0, - 209, 0, 225, 47, 124, 83, 33, 0, 0, 90, 24, 210, 0, 146, 24, 210, 240, 2, 254, 185, 70, 73, 124, 75, 43, 0, 209, 0, - 225, 59, 34, 0, 146, 7, 146, 10, 32, 9, 240, 1, 252, 196, 28, 4, 40, 0, 209, 0, 225, 8, 153, 7, 34, 2, 6, 11, 14, 29, - 35, 9, 28, 33, 147, 0, 152, 5, 28, 43, 247, 254, 252, 25, 70, 75, 124, 154, 124, 219, 70, 73, 6, 18, 4, 27, 67, 19, - 125, 10, 2, 18, 67, 26, 125, 75, 28, 33, 67, 19, 154, 10, 24, 210, 70, 146, 28, 16, 34, 9, 240, 2, 254, 71, 28, 32, - 240, 1, 252, 146, 70, 83, 120, 154, 120, 219, 2, 18, 67, 19, 4, 27, 10, 26, 14, 27, 67, 26, 4, 18, 12, 20, 70, 81, 14, - 18, 112, 138, 112, 204, 28, 32, 240, 1, 252, 140, 144, 11, 40, 0, 209, 0, 224, 208, 70, 82, 120, 211, 152, 5, 147, 0, - 153, 11, 34, 2, 28, 43, 247, 254, 251, 227, 144, 6, 40, 0, 218, 0, 230, 197, 70, 83, 120, 29, 121, 27, 0, 216, 24, 192, - 0, 64, 240, 1, 252, 115, 70, 81, 14, 3, 114, 75, 12, 3, 114, 139, 10, 3, 114, 203, 115, 8, 40, 0, 209, 0, 224, 192, - 121, 11, 33, 0, 0, 218, 24, 210, 0, 82, 240, 2, 254, 75, 70, 82, 121, 19, 43, 0, 209, 0, 224, 138, 155, 11, 33, 0, 25, - 91, 27, 100, 70, 152, 70, 163, 145, 8, 145, 9, 70, 83, 122, 90, 122, 155, 70, 81, 6, 18, 4, 27, 67, 19, 122, 202, 2, - 18, 67, 26, 123, 11, 70, 65, 67, 19, 154, 9, 24, 157, 28, 40, 34, 9, 240, 2, 253, 231, 121, 43, 120, 44, 0, 216, 26, - 192, 240, 1, 252, 59, 14, 3, 115, 171, 12, 3, 115, 235, 10, 3, 116, 43, 116, 104, 40, 0, 209, 0, 224, 137, 70, 91, 27, - 27, 70, 155, 121, 43, 33, 0, 0, 218, 26, 210, 240, 2, 254, 18, 70, 89, 68, 160, 41, 0, 209, 0, 224, 120, 70, 66, 120, - 83, 59, 4, 6, 27, 14, 27, 43, 1, 216, 0, 224, 112, 70, 64, 70, 90, 224, 5, 120, 67, 59, 4, 6, 27, 14, 27, 43, 1, 217, - 98, 120, 3, 26, 210, 24, 192, 42, 0, 209, 244, 70, 65, 26, 68, 6, 35, 14, 27, 115, 107, 44, 0, 209, 98, 121, 43, 43, - 0, 208, 37, 39, 0, 38, 0, 123, 171, 123, 234, 6, 27, 4, 18, 67, 26, 124, 43, 124, 108, 2, 27, 67, 19, 67, 28, 25, 164, - 70, 65, 34, 7, 28, 32, 240, 2, 253, 151, 120, 35, 121, 34, 68, 152, 121, 99, 2, 18, 67, 19, 4, 27, 10, 26, 14, 27, 67, - 26, 4, 18, 12, 19, 14, 18, 113, 34, 113, 99, 121, 43, 55, 1, 54, 7, 66, 187, 216, 219, 155, 8, 153, 9, 51, 1, 49, 18, - 147, 8, 145, 9, 70, 82, 121, 19, 153, 8, 66, 139, 217, 0, 231, 124, 152, 11, 240, 1, 251, 194, 154, 7, 155, 10, 50, - 1, 51, 13, 146, 7, 147, 10, 70, 73, 124, 75, 66, 147, 217, 0, 230, 251, 34, 0, 146, 6, 152, 6, 176, 13, 188, 60, 70, - 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 34, 4, 66, 82, 146, 6, 230, 0, 28, 8, 240, 1, 251, 164, 231, - 237, 70, 67, 26, 196, 6, 35, 14, 27, 231, 160, 35, 0, 115, 107, 231, 160, 35, 4, 66, 91, 147, 6, 229, 237, 28, 32, 240, - 1, 251, 160, 14, 3, 114, 107, 12, 3, 114, 171, 10, 3, 114, 235, 115, 40, 40, 0, 208, 239, 70, 65, 28, 34, 240, 2, 253, - 57, 70, 90, 27, 18, 68, 160, 70, 147, 231, 135, 28, 32, 240, 1, 251, 127, 35, 0, 147, 6, 231, 198, 181, 240, 70, 87, - 70, 78, 70, 69, 180, 224, 75, 175, 176, 138, 104, 27, 43, 0, 209, 9, 76, 173, 176, 10, 28, 32, 188, 28, 70, 144, 70, - 153, 70, 162, 188, 240, 188, 2, 71, 8, 33, 39, 36, 0, 68, 105, 112, 12, 70, 138, 240, 1, 252, 81, 74, 166, 35, 16, 112, - 19, 79, 165, 75, 166, 77, 166, 96, 59, 35, 17, 68, 107, 116, 156, 116, 220, 117, 28, 117, 92, 36, 144, 28, 25, 89, 40, - 70, 152, 70, 145, 247, 255, 253, 131, 78, 160, 70, 65, 121, 178, 121, 11, 66, 154, 209, 4, 121, 242, 121, 75, 66, 154, - 209, 0, 224, 138, 70, 66, 124, 147, 124, 210, 70, 65, 6, 27, 4, 18, 67, 26, 125, 11, 2, 27, 67, 19, 125, 74, 28, 17, - 67, 25, 208, 120, 70, 66, 124, 84, 44, 0, 208, 113, 35, 0, 70, 153, 70, 154, 70, 82, 24, 141, 122, 107, 122, 170, 6, - 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 208, 77, 121, 43, 43, 0, 208, 58, 39, 0, 38, 0, - 224, 10, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 25, 132, 123, 163, - 123, 226, 6, 27, 4, 18, 67, 26, 124, 35, 2, 27, 67, 19, 124, 98, 28, 16, 67, 24, 208, 1, 240, 1, 250, 255, 122, 99, - 122, 162, 6, 27, 4, 18, 67, 26, 122, 227, 2, 27, 67, 19, 123, 34, 28, 16, 67, 24, 208, 1, 240, 1, 250, 241, 121, 43, - 55, 1, 54, 18, 66, 159, 219, 210, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, - 67, 24, 240, 1, 250, 223, 70, 65, 70, 67, 124, 202, 124, 92, 124, 155, 4, 18, 6, 27, 67, 26, 125, 11, 2, 27, 67, 19, - 125, 74, 28, 17, 67, 25, 34, 1, 35, 13, 68, 145, 68, 154, 69, 161, 218, 12, 70, 65, 124, 139, 124, 202, 6, 27, 4, 18, - 67, 26, 125, 11, 2, 27, 67, 19, 125, 74, 28, 17, 67, 25, 231, 144, 28, 8, 240, 1, 250, 187, 72, 88, 247, 253, 248, 150, - 231, 68, 70, 67, 122, 26, 122, 49, 122, 112, 122, 91, 2, 9, 2, 18, 67, 8, 67, 19, 66, 152, 208, 0, 231, 104, 70, 67, - 122, 154, 122, 177, 122, 240, 122, 219, 2, 9, 2, 18, 67, 8, 67, 19, 66, 152, 208, 0, 231, 92, 70, 65, 123, 50, 123, - 139, 66, 154, 208, 0, 231, 86, 123, 114, 123, 203, 66, 154, 208, 0, 231, 81, 123, 178, 124, 11, 66, 154, 208, 0, 231, - 76, 70, 64, 247, 252, 254, 6, 89, 40, 70, 81, 247, 254, 249, 210, 40, 0, 219, 87, 75, 62, 70, 82, 96, 59, 120, 41, 120, - 19, 66, 139, 209, 82, 104, 170, 42, 0, 208, 8, 35, 144, 6, 18, 88, 232, 121, 233, 14, 18, 247, 254, 249, 157, 40, 0, - 219, 85, 75, 49, 28, 40, 96, 59, 33, 0, 247, 254, 254, 31, 40, 0, 219, 40, 75, 50, 96, 59, 121, 115, 43, 0, 208, 20, - 35, 0, 115, 171, 35, 144, 88, 232, 136, 235, 36, 1, 147, 0, 28, 43, 51, 14, 147, 2, 33, 161, 34, 254, 35, 0, 148, 1, - 247, 254, 249, 30, 40, 0, 219, 47, 123, 171, 51, 1, 115, 171, 75, 37, 28, 40, 96, 59, 121, 49, 247, 255, 251, 101, 28, - 4, 28, 33, 72, 34, 247, 253, 248, 36, 44, 0, 218, 3, 76, 32, 230, 208, 76, 32, 230, 206, 121, 49, 28, 40, 247, 255, - 251, 6, 28, 4, 28, 33, 72, 29, 247, 253, 248, 21, 44, 0, 219, 25, 121, 51, 70, 73, 74, 27, 112, 11, 35, 1, 112, 19, - 230, 188, 76, 25, 230, 186, 35, 144, 88, 232, 247, 254, 249, 100, 40, 0, 218, 166, 76, 22, 230, 178, 115, 172, 28, 40, - 33, 0, 247, 254, 253, 209, 76, 20, 230, 171, 76, 20, 230, 169, 76, 20, 230, 167, 70, 192, 19, 112, 136, 52, 255, 255, - 252, 15, 19, 112, 128, 52, 19, 112, 128, 48, 0, 3, 13, 64, 19, 115, 114, 160, 19, 112, 136, 72, 19, 112, 131, 56, 0, - 38, 37, 160, 0, 15, 66, 64, 19, 112, 131, 96, 255, 255, 252, 19, 255, 255, 252, 21, 19, 112, 131, 8, 19, 112, 136, 56, - 255, 255, 252, 24, 255, 255, 252, 23, 255, 255, 252, 20, 255, 255, 252, 22, 255, 255, 252, 18, 181, 240, 70, 87, 70, - 78, 70, 69, 180, 224, 79, 112, 104, 59, 43, 0, 209, 8, 36, 1, 28, 32, 188, 28, 70, 144, 70, 153, 70, 162, 188, 240, - 188, 2, 71, 8, 77, 106, 78, 107, 104, 43, 36, 1, 104, 153, 104, 51, 28, 10, 0, 155, 50, 68, 24, 210, 104, 19, 66, 35, - 209, 34, 240, 1, 250, 191, 32, 100, 247, 252, 248, 106, 240, 1, 250, 174, 32, 100, 247, 252, 248, 101, 240, 1, 250, - 181, 32, 100, 247, 252, 248, 96, 240, 1, 250, 164, 32, 100, 247, 252, 248, 91, 240, 1, 250, 171, 32, 100, 247, 252, - 248, 86, 240, 1, 250, 154, 32, 100, 247, 252, 248, 81, 32, 250, 0, 64, 247, 252, 248, 77, 231, 199, 35, 0, 96, 139, - 32, 0, 247, 251, 254, 39, 104, 51, 70, 154, 104, 43, 70, 80, 104, 155, 96, 156, 70, 153, 247, 254, 249, 38, 70, 128, - 40, 0, 219, 71, 104, 43, 34, 55, 104, 153, 104, 75, 64, 19, 96, 75, 104, 43, 104, 154, 35, 4, 96, 147, 104, 43, 104, - 155, 104, 27, 70, 67, 43, 0, 219, 84, 32, 60, 247, 252, 248, 40, 104, 43, 72, 66, 104, 154, 104, 51, 50, 68, 0, 155, - 24, 210, 104, 20, 70, 65, 28, 34, 247, 252, 255, 92, 35, 1, 96, 59, 75, 60, 28, 34, 64, 26, 75, 60, 66, 154, 208, 4, - 36, 1, 32, 100, 247, 252, 248, 16, 231, 138, 76, 57, 38, 0, 112, 38, 96, 62, 247, 255, 253, 239, 74, 55, 75, 55, 96, - 19, 40, 0, 219, 70, 72, 54, 247, 252, 255, 65, 240, 1, 250, 69, 35, 1, 112, 35, 96, 62, 72, 51, 247, 251, 253, 217, - 104, 43, 36, 0, 104, 154, 35, 4, 96, 147, 231, 223, 104, 43, 34, 55, 104, 153, 70, 84, 104, 75, 32, 10, 64, 19, 96, - 75, 104, 43, 52, 16, 104, 155, 0, 164, 104, 27, 247, 251, 255, 228, 75, 40, 68, 76, 96, 99, 32, 50, 247, 251, 255, 222, - 75, 38, 32, 100, 96, 99, 247, 251, 255, 217, 75, 37, 96, 99, 231, 154, 104, 48, 247, 254, 249, 127, 70, 128, 32, 60, - 247, 251, 255, 207, 104, 43, 72, 21, 104, 154, 104, 51, 50, 68, 0, 155, 24, 210, 104, 20, 70, 65, 28, 34, 247, 252, - 255, 3, 35, 1, 96, 59, 70, 67, 43, 0, 219, 169, 231, 162, 35, 1, 96, 59, 70, 65, 72, 22, 247, 252, 254, 247, 112, 38, - 240, 1, 249, 250, 32, 100, 247, 251, 255, 177, 72, 14, 247, 251, 253, 142, 104, 43, 36, 1, 104, 154, 35, 4, 96, 147, - 231, 148, 19, 112, 136, 8, 19, 112, 128, 44, 19, 112, 136, 20, 19, 112, 131, 120, 0, 0, 49, 5, 0, 0, 16, 5, 19, 112, - 136, 56, 19, 112, 128, 48, 0, 15, 66, 64, 19, 112, 131, 164, 19, 112, 14, 189, 0, 0, 24, 3, 0, 0, 25, 3, 0, 0, 16, 1, - 19, 112, 131, 184, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 4, 9, 176, 155, 12, 9, 75, 133, 146, 16, 145, - 21, 74, 132, 73, 133, 146, 14, 145, 15, 74, 132, 73, 133, 147, 13, 75, 133, 145, 12, 146, 11, 147, 10, 33, 93, 74, 131, - 75, 132, 68, 105, 144, 17, 36, 0, 70, 138, 146, 9, 147, 8, 247, 255, 254, 218, 40, 0, 209, 13, 153, 15, 36, 0, 120, - 11, 43, 1, 208, 14, 155, 14, 34, 1, 36, 1, 96, 26, 66, 100, 247, 255, 254, 204, 40, 0, 208, 241, 44, 0, 219, 244, 153, - 15, 120, 11, 43, 1, 209, 240, 153, 14, 104, 10, 42, 0, 209, 227, 75, 115, 153, 13, 96, 11, 28, 97, 208, 104, 153, 12, - 32, 0, 104, 11, 104, 155, 96, 154, 247, 251, 253, 34, 154, 11, 153, 10, 120, 18, 32, 160, 28, 20, 52, 4, 0, 163, 88, - 203, 146, 18, 154, 21, 70, 153, 70, 75, 67, 83, 2, 128, 66, 131, 216, 84, 155, 21, 146, 19, 43, 0, 208, 87, 153, 18, - 28, 30, 154, 16, 7, 75, 14, 27, 0, 164, 157, 17, 147, 20, 70, 147, 148, 7, 155, 19, 28, 55, 66, 158, 217, 0, 28, 31, - 4, 58, 12, 17, 35, 103, 70, 136, 68, 107, 33, 0, 112, 25, 33, 42, 70, 83, 112, 25, 35, 83, 68, 107, 120, 25, 70, 83, - 112, 89, 70, 81, 14, 43, 112, 139, 12, 43, 112, 203, 14, 18, 10, 43, 113, 11, 113, 202, 35, 0, 70, 66, 113, 139, 114, - 75, 113, 77, 114, 10, 153, 10, 154, 18, 123, 139, 66, 147, 216, 51, 36, 3, 66, 100, 152, 8, 247, 251, 252, 215, 153, - 12, 104, 11, 104, 154, 35, 4, 96, 147, 154, 13, 75, 69, 96, 19, 154, 14, 33, 1, 96, 17, 231, 128, 40, 0, 218, 72, 152, - 8, 247, 251, 252, 198, 154, 12, 104, 19, 104, 154, 35, 4, 96, 147, 75, 61, 153, 13, 96, 11, 231, 237, 70, 73, 240, 2, - 249, 40, 155, 21, 144, 19, 43, 0, 209, 167, 152, 8, 247, 251, 252, 179, 154, 12, 36, 1, 104, 19, 66, 100, 104, 154, - 35, 4, 96, 147, 153, 13, 75, 50, 96, 11, 231, 216, 70, 75, 43, 0, 208, 200, 154, 9, 33, 1, 96, 17, 70, 65, 70, 75, 67, - 75, 33, 10, 70, 82, 145, 1, 33, 103, 146, 0, 68, 105, 34, 1, 146, 2, 145, 3, 34, 0, 33, 6, 146, 4, 145, 5, 70, 90, 72, - 34, 153, 18, 247, 254, 252, 155, 155, 9, 34, 0, 28, 4, 96, 26, 40, 0, 221, 187, 33, 103, 68, 105, 120, 11, 43, 0, 208, - 1, 76, 30, 231, 165, 70, 66, 26, 179, 4, 27, 12, 30, 153, 7, 155, 10, 88, 91, 70, 153, 46, 0, 208, 4, 70, 75, 67, 123, - 25, 237, 68, 155, 231, 108, 152, 8, 247, 251, 252, 110, 154, 12, 104, 19, 104, 154, 35, 4, 96, 147, 153, 13, 75, 16, - 96, 11, 154, 14, 104, 19, 43, 0, 208, 0, 231, 22, 176, 27, 32, 1, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, - 240, 188, 2, 71, 8, 70, 192, 19, 112, 128, 48, 19, 112, 136, 8, 19, 112, 136, 56, 19, 112, 128, 52, 19, 112, 128, 44, - 19, 115, 114, 160, 19, 112, 136, 64, 19, 112, 14, 189, 0, 15, 66, 64, 255, 255, 216, 234, 181, 240, 70, 95, 70, 86, - 70, 77, 70, 68, 180, 240, 176, 155, 146, 15, 74, 151, 144, 16, 146, 14, 104, 19, 43, 0, 208, 0, 224, 236, 75, 149, 147, - 13, 4, 11, 12, 27, 147, 21, 73, 147, 75, 148, 38, 0, 150, 18, 147, 12, 145, 6, 224, 10, 154, 13, 33, 1, 38, 1, 96, 17, - 66, 118, 154, 18, 50, 1, 146, 18, 42, 3, 221, 0, 224, 161, 154, 12, 104, 19, 43, 0, 209, 0, 147, 18, 247, 255, 253, - 167, 40, 0, 209, 0, 38, 0, 153, 14, 104, 11, 43, 0, 208, 4, 154, 13, 104, 19, 43, 3, 209, 0, 224, 142, 46, 0, 219, 223, - 75, 130, 147, 10, 120, 27, 43, 1, 209, 218, 155, 13, 104, 26, 42, 0, 209, 219, 73, 126, 75, 127, 145, 9, 96, 11, 75, - 126, 32, 0, 147, 8, 104, 27, 104, 155, 96, 154, 247, 251, 251, 242, 75, 123, 154, 6, 120, 27, 153, 21, 147, 17, 51, - 4, 147, 11, 0, 155, 88, 211, 32, 160, 70, 153, 70, 75, 67, 75, 2, 128, 145, 19, 66, 131, 217, 3, 70, 73, 240, 2, 248, - 76, 144, 19, 155, 21, 43, 0, 209, 0, 224, 189, 154, 17, 153, 15, 7, 83, 14, 27, 70, 139, 147, 20, 73, 109, 155, 21, - 70, 108, 157, 16, 70, 152, 52, 93, 145, 7, 154, 19, 70, 71, 69, 144, 217, 0, 28, 23, 4, 58, 12, 19, 33, 103, 70, 154, - 68, 105, 35, 0, 112, 11, 33, 40, 35, 83, 112, 33, 68, 107, 120, 27, 14, 18, 112, 99, 14, 43, 112, 163, 12, 43, 112, - 227, 113, 226, 33, 0, 10, 43, 70, 82, 113, 35, 113, 101, 113, 161, 114, 34, 114, 97, 153, 6, 154, 17, 123, 139, 66, - 147, 216, 58, 38, 3, 66, 118, 72, 87, 247, 251, 251, 162, 153, 8, 104, 11, 104, 154, 35, 4, 96, 147, 154, 9, 75, 78, - 96, 19, 153, 13, 35, 1, 96, 11, 154, 14, 104, 19, 43, 0, 208, 14, 153, 13, 104, 11, 43, 0, 208, 0, 224, 128, 153, 10, - 120, 11, 43, 1, 208, 0, 231, 102, 46, 0, 218, 0, 231, 99, 32, 1, 224, 14, 154, 13, 104, 19, 43, 0, 208, 241, 154, 18, - 50, 1, 146, 18, 42, 3, 220, 0, 231, 93, 15, 243, 34, 1, 64, 83, 6, 27, 14, 24, 176, 27, 188, 60, 70, 144, 70, 153, 70, - 162, 70, 171, 188, 240, 188, 2, 71, 8, 70, 75, 43, 0, 208, 193, 154, 7, 33, 1, 96, 17, 70, 81, 34, 10, 70, 75, 67, 75, - 146, 1, 33, 0, 34, 103, 145, 2, 68, 106, 145, 4, 33, 6, 146, 3, 145, 5, 70, 90, 152, 6, 153, 17, 148, 0, 247, 254, 251, - 97, 155, 7, 34, 0, 28, 6, 96, 26, 40, 0, 221, 16, 33, 103, 68, 105, 120, 11, 43, 0, 208, 13, 78, 41, 231, 160, 74, 30, - 146, 13, 104, 19, 43, 1, 220, 0, 231, 14, 35, 1, 96, 19, 32, 0, 231, 198, 40, 0, 219, 148, 70, 66, 70, 81, 26, 83, 4, - 27, 154, 11, 12, 27, 153, 6, 70, 152, 0, 147, 88, 203, 70, 66, 70, 153, 42, 0, 208, 4, 70, 75, 67, 123, 25, 237, 68, - 155, 231, 90, 72, 24, 247, 251, 251, 36, 153, 8, 104, 11, 104, 154, 35, 4, 96, 147, 154, 9, 75, 15, 96, 19, 231, 131, - 72, 18, 247, 251, 251, 24, 153, 8, 38, 1, 104, 11, 66, 118, 104, 154, 35, 4, 96, 147, 154, 9, 75, 8, 96, 19, 231, 114, - 32, 0, 231, 149, 70, 192, 19, 112, 135, 240, 19, 112, 136, 8, 19, 115, 114, 160, 19, 112, 136, 92, 19, 112, 136, 56, - 19, 112, 128, 48, 0, 15, 66, 64, 19, 112, 128, 44, 19, 112, 128, 52, 19, 112, 136, 64, 19, 112, 14, 189, 255, 255, 216, - 234, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 176, 155, 34, 103, 144, 15, 68, 106, 32, 0, 112, 16, 74, 192, - 35, 16, 112, 19, 156, 15, 74, 191, 35, 152, 37, 81, 80, 226, 68, 109, 35, 144, 80, 225, 116, 168, 116, 232, 117, 40, - 117, 104, 28, 8, 28, 41, 247, 255, 248, 139, 70, 171, 28, 5, 28, 41, 72, 183, 247, 252, 252, 45, 75, 183, 73, 183, 104, - 27, 72, 183, 104, 154, 75, 183, 104, 84, 104, 27, 50, 68, 0, 155, 24, 210, 104, 18, 146, 18, 247, 252, 252, 30, 4, 33, - 213, 0, 224, 218, 74, 178, 146, 17, 4, 97, 213, 0, 224, 218, 74, 175, 70, 145, 4, 161, 213, 0, 224, 218, 74, 173, 70, - 146, 4, 225, 213, 0, 224, 218, 74, 170, 70, 144, 6, 161, 213, 0, 224, 218, 74, 168, 70, 148, 6, 225, 213, 0, 224, 218, - 74, 165, 7, 35, 213, 0, 224, 218, 75, 163, 7, 97, 213, 0, 224, 218, 79, 161, 7, 161, 213, 0, 224, 218, 78, 159, 7, 225, - 213, 0, 224, 218, 73, 157, 145, 9, 70, 81, 145, 0, 146, 3, 70, 65, 154, 9, 145, 1, 70, 97, 72, 154, 145, 2, 147, 4, - 146, 7, 28, 33, 154, 17, 70, 75, 151, 5, 150, 6, 247, 252, 251, 222, 72, 149, 153, 18, 247, 252, 251, 218, 45, 0, 218, - 0, 226, 223, 75, 147, 104, 27, 43, 0, 209, 0, 224, 189, 76, 145, 70, 93, 148, 14, 121, 164, 121, 43, 66, 163, 209, 5, - 153, 14, 121, 107, 121, 202, 66, 154, 209, 0, 226, 222, 70, 90, 124, 147, 124, 210, 6, 27, 70, 92, 4, 18, 67, 26, 125, - 35, 2, 27, 67, 19, 125, 98, 28, 17, 67, 25, 209, 0, 226, 41, 124, 99, 43, 0, 209, 0, 226, 34, 37, 0, 70, 170, 70, 168, - 70, 66, 24, 141, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 208, 75, - 121, 43, 43, 0, 208, 58, 39, 0, 38, 0, 224, 10, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, - 42, 28, 16, 67, 24, 25, 132, 123, 163, 123, 226, 6, 27, 4, 18, 67, 26, 124, 35, 2, 27, 67, 19, 124, 98, 28, 16, 67, - 24, 208, 1, 240, 0, 253, 163, 122, 99, 122, 162, 6, 27, 4, 18, 67, 26, 122, 227, 2, 27, 67, 19, 123, 34, 28, 16, 67, - 24, 208, 1, 240, 0, 253, 149, 121, 43, 55, 1, 54, 18, 66, 159, 219, 210, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, - 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 70, 92, 240, 0, 253, 130, 124, 163, 124, 226, 6, 27, 4, 18, 67, 26, 125, - 35, 2, 27, 67, 19, 125, 98, 28, 17, 67, 25, 70, 92, 37, 1, 124, 99, 34, 13, 68, 170, 68, 144, 69, 154, 219, 0, 225, - 188, 124, 163, 124, 226, 6, 27, 4, 18, 67, 26, 125, 35, 2, 27, 67, 19, 125, 98, 28, 17, 67, 25, 231, 144, 75, 73, 147, - 17, 4, 97, 212, 0, 231, 36, 75, 72, 70, 153, 4, 161, 212, 0, 231, 36, 75, 70, 70, 154, 4, 225, 212, 0, 231, 36, 75, - 69, 70, 152, 6, 161, 212, 0, 231, 36, 75, 67, 70, 156, 6, 225, 212, 0, 231, 36, 74, 66, 7, 35, 212, 0, 231, 36, 75, - 65, 7, 97, 212, 0, 231, 36, 79, 64, 7, 161, 212, 0, 231, 36, 78, 63, 7, 225, 212, 0, 231, 36, 73, 62, 145, 9, 231, 35, - 73, 50, 70, 93, 121, 44, 145, 14, 154, 14, 73, 59, 113, 148, 70, 92, 121, 99, 113, 211, 122, 34, 122, 99, 2, 18, 67, - 19, 157, 14, 4, 27, 12, 26, 14, 27, 114, 43, 114, 106, 122, 162, 122, 227, 2, 18, 67, 19, 4, 27, 14, 26, 12, 27, 114, - 170, 114, 235, 123, 163, 115, 43, 123, 227, 115, 107, 124, 35, 115, 171, 35, 128, 66, 91, 145, 13, 96, 11, 124, 99, - 43, 0, 209, 0, 225, 62, 75, 41, 76, 41, 77, 42, 34, 0, 146, 16, 146, 19, 147, 12, 38, 0, 148, 11, 149, 10, 70, 89, 124, - 138, 124, 203, 6, 18, 4, 27, 67, 19, 125, 10, 152, 12, 2, 18, 67, 26, 125, 75, 153, 16, 67, 19, 154, 19, 24, 157, 122, - 42, 0, 82, 247, 252, 250, 204, 121, 43, 43, 0, 209, 0, 225, 18, 35, 0, 70, 153, 70, 154, 224, 102, 19, 112, 128, 52, - 44, 13, 224, 1, 19, 112, 131, 208, 19, 112, 128, 44, 19, 112, 131, 252, 19, 112, 128, 204, 19, 112, 136, 20, 19, 112, - 134, 240, 19, 112, 129, 56, 19, 112, 129, 96, 19, 112, 136, 52, 19, 112, 136, 72, 19, 112, 128, 228, 19, 112, 128, 236, - 19, 112, 128, 248, 19, 112, 129, 0, 19, 112, 129, 8, 19, 112, 129, 16, 19, 112, 129, 24, 19, 112, 129, 32, 19, 112, - 129, 40, 19, 112, 129, 48, 19, 112, 136, 68, 19, 112, 132, 24, 19, 112, 132, 136, 19, 112, 132, 120, 123, 163, 123, - 226, 6, 27, 4, 18, 67, 26, 124, 35, 2, 27, 67, 19, 124, 98, 28, 16, 67, 24, 208, 1, 240, 0, 252, 164, 122, 99, 122, - 162, 6, 27, 4, 18, 67, 26, 122, 227, 115, 166, 2, 27, 67, 19, 123, 34, 115, 230, 28, 16, 116, 38, 116, 102, 67, 24, - 208, 1, 240, 0, 252, 146, 121, 99, 114, 102, 114, 166, 114, 230, 115, 38, 43, 9, 209, 0, 224, 234, 43, 8, 209, 0, 224, - 154, 35, 1, 68, 153, 121, 43, 36, 18, 68, 162, 69, 75, 216, 0, 224, 167, 122, 106, 122, 171, 6, 18, 4, 27, 67, 19, 122, - 234, 70, 81, 2, 18, 67, 26, 123, 43, 67, 19, 24, 92, 121, 99, 43, 8, 209, 189, 121, 163, 43, 6, 208, 9, 43, 1, 208, - 7, 43, 2, 208, 5, 43, 3, 208, 3, 43, 4, 208, 1, 43, 5, 209, 176, 121, 227, 43, 80, 209, 173, 121, 35, 43, 1, 217, 170, - 154, 15, 33, 1, 35, 156, 84, 209, 72, 189, 34, 1, 121, 161, 247, 252, 250, 50, 154, 15, 115, 86, 115, 22, 121, 32, 30, - 1, 208, 198, 35, 0, 70, 152, 39, 0, 224, 4, 34, 1, 68, 144, 55, 7, 69, 65, 217, 29, 123, 162, 123, 227, 6, 18, 4, 27, - 67, 19, 124, 34, 2, 18, 67, 26, 124, 99, 67, 19, 25, 218, 120, 211, 43, 2, 209, 236, 120, 145, 6, 11, 43, 0, 219, 111, - 155, 15, 123, 91, 43, 0, 209, 1, 41, 0, 209, 52, 28, 1, 34, 1, 68, 144, 55, 7, 69, 65, 216, 225, 155, 15, 123, 25, 41, - 0, 208, 155, 123, 90, 42, 0, 208, 152, 72, 161, 247, 252, 249, 251, 153, 15, 154, 14, 123, 11, 70, 88, 116, 19, 123, - 75, 116, 83, 121, 107, 112, 11, 120, 163, 96, 75, 115, 211, 120, 227, 96, 139, 247, 251, 255, 135, 75, 153, 156, 13, - 157, 15, 96, 35, 72, 152, 120, 41, 104, 170, 247, 252, 249, 226, 35, 144, 70, 105, 88, 232, 49, 103, 247, 253, 251, - 72, 40, 0, 219, 0, 225, 54, 76, 146, 77, 146, 224, 225, 155, 15, 115, 89, 121, 19, 121, 81, 2, 27, 67, 25, 152, 11, - 247, 252, 249, 205, 121, 32, 28, 1, 231, 191, 121, 227, 43, 80, 208, 0, 231, 96, 121, 35, 43, 1, 216, 0, 231, 92, 121, - 163, 73, 136, 154, 13, 26, 203, 96, 19, 35, 1, 68, 153, 121, 43, 36, 18, 68, 162, 69, 75, 217, 0, 231, 87, 157, 16, - 153, 19, 53, 1, 49, 13, 149, 16, 145, 19, 70, 90, 124, 83, 66, 171, 217, 0, 230, 202, 72, 125, 247, 252, 249, 167, 70, - 88, 247, 251, 255, 64, 77, 121, 76, 119, 224, 172, 155, 15, 123, 27, 43, 0, 209, 139, 41, 0, 208, 137, 155, 15, 115, - 25, 121, 19, 121, 81, 2, 27, 67, 25, 152, 10, 247, 252, 249, 146, 121, 32, 28, 1, 231, 102, 28, 8, 240, 0, 251, 174, - 72, 111, 247, 252, 249, 137, 37, 1, 66, 109, 176, 27, 28, 40, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, - 188, 2, 71, 8, 75, 105, 153, 13, 70, 90, 96, 11, 124, 147, 124, 210, 6, 27, 70, 92, 4, 18, 67, 26, 125, 35, 2, 27, 67, - 19, 125, 98, 28, 17, 67, 25, 208, 199, 70, 93, 124, 108, 44, 0, 208, 123, 34, 0, 70, 146, 70, 144, 70, 67, 24, 205, - 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, 67, 24, 208, 76, 121, 43, 43, 0, - 208, 58, 39, 0, 38, 0, 224, 10, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, 67, 19, 123, 42, 28, 16, - 67, 24, 25, 132, 123, 163, 123, 226, 6, 27, 4, 18, 67, 26, 124, 35, 2, 27, 67, 19, 124, 98, 28, 16, 67, 24, 208, 1, - 240, 0, 251, 89, 122, 99, 122, 162, 6, 27, 4, 18, 67, 26, 122, 227, 2, 27, 67, 19, 123, 34, 28, 16, 67, 24, 208, 1, - 240, 0, 251, 75, 121, 43, 55, 1, 54, 18, 66, 159, 219, 210, 122, 107, 122, 170, 6, 27, 4, 18, 67, 26, 122, 235, 2, 27, - 67, 19, 123, 42, 28, 16, 67, 24, 70, 93, 240, 0, 251, 56, 124, 171, 124, 234, 6, 27, 4, 18, 67, 26, 125, 43, 124, 108, - 2, 27, 67, 19, 125, 106, 28, 17, 67, 25, 34, 1, 35, 13, 68, 146, 68, 152, 69, 162, 218, 23, 70, 93, 124, 171, 124, 234, - 6, 27, 4, 18, 67, 26, 125, 43, 2, 27, 67, 19, 125, 106, 28, 17, 67, 25, 231, 145, 75, 39, 76, 32, 147, 13, 75, 38, 96, - 35, 154, 13, 72, 38, 104, 17, 247, 252, 248, 237, 231, 100, 28, 8, 240, 0, 251, 11, 77, 28, 76, 25, 231, 241, 28, 10, - 122, 80, 122, 9, 122, 42, 122, 107, 2, 9, 2, 18, 67, 8, 67, 19, 66, 152, 208, 0, 229, 20, 155, 14, 122, 170, 122, 153, - 122, 216, 122, 235, 2, 9, 2, 18, 67, 8, 67, 19, 66, 152, 208, 0, 229, 8, 157, 14, 70, 89, 123, 42, 123, 139, 66, 154, - 208, 0, 229, 1, 123, 106, 123, 203, 66, 154, 208, 0, 228, 252, 123, 170, 124, 11, 66, 154, 208, 0, 228, 247, 229, 171, - 19, 112, 132, 64, 19, 112, 132, 152, 255, 255, 251, 79, 19, 112, 132, 224, 19, 112, 128, 48, 255, 255, 216, 231, 255, - 255, 216, 240, 19, 112, 132, 172, 19, 112, 131, 56, 255, 255, 177, 224, 19, 112, 136, 68, 0, 15, 66, 64, 19, 112, 133, - 136, 75, 50, 156, 13, 72, 50, 96, 35, 247, 252, 251, 42, 37, 103, 154, 15, 68, 109, 120, 41, 120, 19, 66, 139, 208, - 2, 72, 46, 247, 252, 248, 146, 75, 45, 76, 46, 37, 103, 96, 35, 155, 15, 68, 109, 120, 25, 120, 43, 66, 139, 208, 7, - 154, 15, 35, 144, 88, 208, 247, 253, 249, 225, 40, 0, 218, 0, 230, 167, 75, 38, 157, 13, 153, 15, 96, 43, 104, 138, - 42, 0, 208, 9, 35, 144, 6, 18, 88, 200, 14, 18, 121, 201, 247, 253, 249, 188, 40, 0, 218, 0, 230, 150, 78, 31, 75, 31, - 96, 38, 154, 13, 72, 31, 96, 19, 247, 252, 250, 245, 152, 15, 247, 253, 255, 10, 28, 5, 72, 28, 247, 252, 250, 238, - 45, 0, 219, 14, 157, 15, 35, 8, 115, 171, 153, 15, 37, 160, 89, 75, 43, 0, 208, 8, 75, 18, 72, 22, 96, 35, 247, 252, - 248, 81, 37, 0, 230, 199, 96, 38, 231, 90, 32, 129, 1, 64, 240, 0, 250, 119, 35, 31, 48, 31, 154, 15, 67, 152, 81, 80, - 40, 0, 209, 235, 157, 13, 75, 13, 96, 43, 37, 4, 66, 109, 231, 71, 255, 255, 251, 78, 19, 112, 133, 16, 19, 112, 133, - 44, 0, 38, 37, 160, 19, 112, 128, 48, 255, 255, 251, 77, 0, 15, 66, 64, 255, 255, 251, 76, 19, 112, 133, 88, 19, 112, - 133, 112, 19, 112, 133, 172, 255, 255, 251, 75, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 176, 143, 74, 134, - 144, 13, 72, 134, 35, 0, 144, 12, 73, 133, 128, 3, 146, 11, 128, 19, 74, 132, 75, 133, 36, 0, 145, 10, 112, 12, 146, - 9, 112, 20, 147, 8, 152, 8, 35, 120, 66, 91, 96, 3, 240, 0, 251, 24, 79, 127, 153, 13, 28, 56, 247, 255, 251, 175, 40, - 0, 219, 107, 73, 125, 37, 1, 115, 189, 120, 11, 120, 74, 6, 27, 4, 18, 67, 26, 120, 139, 70, 138, 2, 27, 67, 19, 120, - 202, 67, 26, 209, 103, 113, 76, 75, 118, 72, 118, 73, 119, 34, 1, 70, 144, 38, 0, 70, 145, 147, 7, 144, 6, 70, 187, - 145, 5, 224, 4, 33, 0, 54, 1, 70, 137, 69, 176, 221, 60, 152, 6, 28, 49, 247, 251, 255, 218, 6, 51, 14, 29, 28, 41, - 70, 88, 247, 254, 251, 144, 28, 4, 28, 33, 152, 7, 247, 251, 255, 207, 28, 163, 43, 1, 216, 0, 224, 127, 44, 0, 219, - 0, 224, 137, 70, 73, 41, 0, 208, 225, 70, 90, 35, 0, 115, 147, 136, 211, 33, 144, 88, 80, 147, 0, 75, 96, 34, 1, 146, - 1, 147, 2, 33, 161, 34, 254, 35, 0, 247, 253, 248, 159, 28, 1, 40, 0, 219, 98, 70, 88, 123, 131, 70, 82, 51, 1, 115, - 131, 35, 1, 113, 83, 123, 184, 70, 128, 70, 66, 152, 5, 247, 251, 255, 165, 33, 0, 70, 137, 69, 176, 220, 194, 152, - 8, 35, 122, 66, 91, 96, 3, 33, 0, 28, 56, 247, 253, 253, 109, 153, 10, 35, 0, 112, 11, 72, 77, 247, 251, 255, 147, 32, - 3, 66, 64, 176, 15, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 121, 75, 43, 0, 208, 18, 35, - 144, 88, 248, 136, 251, 115, 188, 147, 0, 28, 59, 51, 14, 147, 2, 33, 161, 34, 254, 35, 0, 149, 1, 247, 253, 248, 97, - 40, 0, 219, 84, 123, 187, 51, 1, 115, 187, 70, 82, 121, 21, 72, 59, 28, 41, 247, 251, 255, 108, 28, 41, 28, 56, 247, - 254, 251, 36, 28, 4, 28, 33, 72, 49, 247, 251, 255, 99, 28, 163, 43, 1, 217, 65, 44, 0, 219, 188, 154, 10, 35, 1, 112, - 19, 155, 9, 74, 49, 112, 29, 75, 49, 96, 19, 152, 8, 35, 0, 96, 3, 240, 0, 250, 87, 32, 0, 231, 189, 34, 1, 70, 88, - 115, 130, 231, 159, 70, 88, 247, 253, 253, 238, 154, 8, 35, 121, 66, 91, 96, 19, 152, 10, 35, 0, 112, 3, 32, 3, 66, - 64, 231, 172, 33, 0, 70, 82, 112, 17, 112, 81, 112, 145, 70, 83, 34, 1, 112, 218, 152, 13, 113, 29, 137, 3, 152, 12, - 128, 3, 152, 13, 137, 67, 152, 11, 128, 3, 155, 10, 112, 26, 152, 9, 74, 25, 75, 26, 112, 5, 96, 19, 154, 8, 96, 17, - 240, 0, 250, 40, 32, 0, 231, 142, 115, 189, 231, 124, 28, 56, 247, 253, 253, 193, 152, 8, 35, 121, 66, 91, 96, 3, 153, - 10, 35, 0, 32, 3, 112, 11, 66, 64, 231, 127, 70, 192, 19, 112, 136, 60, 19, 112, 136, 58, 19, 112, 136, 56, 19, 112, - 128, 52, 19, 112, 136, 68, 19, 115, 114, 160, 19, 112, 136, 72, 19, 112, 133, 236, 19, 112, 134, 12, 19, 112, 134, 40, - 19, 115, 114, 174, 19, 112, 134, 84, 19, 112, 133, 204, 19, 112, 128, 48, 0, 15, 66, 64, 181, 240, 70, 95, 70, 86, 70, - 77, 70, 68, 180, 240, 73, 117, 176, 131, 104, 12, 70, 139, 44, 0, 208, 9, 32, 0, 176, 3, 188, 60, 70, 144, 70, 153, - 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 77, 110, 32, 0, 104, 43, 38, 1, 104, 155, 96, 156, 247, 250, 253, 116, 74, - 107, 35, 1, 66, 91, 146, 0, 96, 19, 75, 106, 72, 106, 96, 30, 70, 153, 75, 106, 112, 28, 247, 251, 254, 199, 104, 41, - 74, 104, 103, 76, 96, 20, 111, 11, 70, 136, 70, 146, 43, 0, 208, 100, 70, 75, 96, 30, 104, 43, 32, 0, 104, 155, 96, - 158, 247, 251, 253, 22, 28, 4, 40, 0, 219, 3, 32, 0, 247, 253, 249, 96, 28, 4, 104, 43, 32, 20, 104, 154, 35, 4, 96, - 147, 247, 250, 255, 104, 104, 43, 70, 81, 104, 159, 104, 14, 28, 59, 0, 178, 51, 68, 24, 155, 104, 26, 44, 0, 219, 4, - 75, 85, 64, 26, 75, 85, 66, 154, 208, 40, 35, 1, 96, 187, 28, 48, 247, 253, 248, 59, 144, 1, 40, 0, 219, 113, 104, 43, - 34, 55, 104, 153, 32, 20, 104, 75, 64, 19, 96, 75, 104, 43, 104, 154, 35, 4, 96, 147, 104, 43, 104, 155, 104, 27, 247, - 250, 255, 64, 104, 43, 70, 81, 104, 154, 104, 11, 50, 68, 0, 155, 24, 210, 104, 16, 154, 1, 42, 0, 219, 42, 75, 65, - 28, 2, 64, 26, 75, 64, 66, 154, 209, 36, 70, 64, 48, 88, 247, 255, 254, 71, 40, 0, 209, 30, 70, 74, 35, 1, 70, 89, 96, - 11, 96, 16, 72, 58, 247, 250, 253, 1, 104, 43, 72, 57, 104, 154, 35, 4, 96, 147, 247, 251, 254, 90, 231, 114, 70, 75, - 96, 30, 104, 43, 72, 53, 104, 155, 108, 92, 28, 33, 247, 251, 254, 80, 66, 52, 209, 13, 154, 0, 104, 19, 51, 1, 208, - 39, 72, 45, 247, 250, 252, 231, 104, 43, 104, 154, 35, 4, 96, 147, 155, 0, 104, 24, 231, 90, 70, 81, 104, 8, 247, 253, - 248, 168, 28, 4, 32, 20, 247, 250, 254, 248, 104, 43, 70, 82, 104, 16, 104, 155, 0, 130, 51, 68, 24, 155, 104, 26, 44, - 0, 219, 4, 75, 29, 64, 26, 75, 29, 66, 154, 208, 1, 247, 253, 251, 47, 35, 101, 153, 0, 66, 91, 96, 11, 231, 215, 35, - 100, 66, 91, 96, 19, 231, 211, 104, 43, 34, 55, 104, 153, 28, 52, 104, 75, 32, 10, 64, 19, 96, 75, 104, 43, 52, 16, - 104, 155, 0, 164, 104, 27, 247, 250, 254, 207, 75, 19, 25, 60, 96, 99, 32, 50, 247, 250, 254, 201, 75, 17, 32, 100, - 96, 99, 247, 250, 254, 196, 75, 15, 96, 99, 231, 112, 70, 192, 19, 112, 136, 52, 19, 112, 128, 44, 19, 112, 136, 68, - 19, 112, 136, 8, 19, 112, 134, 116, 19, 112, 136, 56, 19, 112, 136, 20, 0, 0, 49, 5, 0, 0, 16, 5, 19, 112, 14, 189, - 19, 112, 134, 244, 19, 112, 135, 12, 0, 0, 24, 3, 0, 0, 25, 3, 0, 0, 16, 1, 71, 112, 70, 192, 71, 112, 70, 192, 181, - 0, 75, 4, 176, 129, 28, 1, 104, 24, 247, 250, 248, 161, 176, 1, 188, 1, 71, 0, 19, 112, 136, 108, 181, 0, 75, 9, 28, - 1, 176, 129, 104, 24, 247, 250, 248, 137, 40, 0, 208, 2, 176, 1, 188, 2, 71, 8, 72, 4, 247, 250, 248, 145, 32, 100, - 247, 250, 254, 128, 231, 251, 70, 192, 19, 112, 136, 108, 19, 112, 135, 44, 181, 0, 176, 129, 247, 250, 248, 120, 176, - 1, 188, 1, 71, 0, 70, 192, 181, 0, 176, 129, 247, 250, 248, 112, 176, 1, 188, 1, 71, 0, 70, 192, 181, 0, 176, 129, 247, - 250, 248, 104, 176, 1, 188, 1, 71, 0, 70, 192, 181, 16, 28, 4, 247, 250, 248, 48, 28, 32, 188, 16, 188, 2, 71, 8, 181, - 16, 28, 4, 247, 250, 248, 40, 28, 32, 188, 16, 188, 2, 71, 8, 181, 16, 28, 4, 247, 250, 248, 32, 28, 32, 188, 16, 188, - 2, 71, 8, 181, 0, 33, 224, 176, 129, 72, 7, 2, 9, 247, 250, 248, 17, 75, 6, 96, 24, 40, 0, 219, 3, 32, 0, 176, 1, 188, - 2, 71, 8, 32, 1, 66, 64, 231, 249, 19, 112, 144, 160, 19, 112, 136, 108, 181, 240, 70, 71, 180, 128, 78, 36, 176, 132, - 104, 52, 28, 7, 28, 13, 44, 0, 208, 36, 77, 33, 104, 44, 44, 0, 208, 18, 72, 32, 28, 57, 34, 6, 240, 1, 249, 9, 40, - 0, 209, 6, 176, 4, 28, 32, 188, 4, 70, 144, 188, 240, 188, 2, 71, 8, 28, 32, 240, 0, 249, 217, 35, 0, 96, 43, 104, 48, - 28, 57, 240, 0, 249, 227, 96, 40, 40, 0, 208, 4, 72, 19, 28, 57, 34, 6, 240, 1, 249, 27, 104, 44, 231, 229, 247, 255, - 254, 81, 73, 16, 28, 8, 70, 136, 247, 250, 255, 200, 75, 14, 28, 2, 96, 24, 40, 0, 209, 1, 36, 0, 231, 215, 70, 65, - 104, 11, 72, 11, 146, 0, 33, 0, 34, 0, 149, 1, 148, 2, 240, 0, 251, 167, 96, 48, 40, 0, 209, 191, 36, 0, 231, 200, 19, - 112, 136, 116, 19, 112, 136, 112, 19, 112, 128, 56, 19, 115, 116, 64, 19, 115, 116, 68, 19, 112, 97, 173, 181, 240, - 79, 15, 28, 30, 104, 59, 28, 21, 28, 12, 28, 48, 28, 25, 67, 81, 176, 129, 247, 249, 255, 162, 28, 32, 28, 41, 28, 50, - 247, 254, 255, 105, 40, 0, 209, 4, 32, 1, 176, 1, 188, 240, 188, 2, 71, 8, 104, 59, 28, 48, 28, 25, 67, 105, 247, 249, - 255, 192, 32, 0, 231, 243, 19, 115, 116, 64, 181, 0, 176, 129, 32, 129, 33, 0, 34, 0, 35, 0, 247, 249, 255, 172, 176, - 1, 188, 1, 71, 0, 70, 192, 181, 0, 176, 129, 32, 128, 33, 0, 34, 0, 35, 0, 247, 249, 255, 160, 176, 1, 188, 1, 71, 0, - 70, 192, 181, 48, 28, 13, 28, 4, 28, 19, 176, 129, 28, 42, 28, 33, 32, 16, 247, 249, 255, 146, 176, 1, 188, 48, 188, - 2, 71, 8, 181, 0, 28, 3, 176, 129, 28, 10, 32, 6, 28, 25, 35, 0, 247, 249, 255, 133, 176, 1, 188, 1, 71, 0, 181, 0, - 28, 3, 176, 129, 28, 10, 32, 5, 28, 25, 35, 0, 247, 249, 255, 121, 176, 1, 188, 1, 71, 0, 181, 48, 176, 129, 28, 4, - 28, 13, 28, 19, 42, 0, 221, 4, 32, 9, 28, 33, 28, 42, 247, 249, 255, 106, 176, 1, 188, 48, 188, 1, 71, 0, 181, 48, 176, - 129, 28, 4, 28, 13, 28, 19, 42, 0, 221, 4, 32, 2, 28, 33, 28, 42, 247, 249, 255, 90, 176, 1, 188, 48, 188, 1, 71, 0, - 181, 0, 176, 129, 32, 18, 33, 0, 34, 0, 35, 0, 247, 249, 255, 78, 176, 1, 188, 2, 71, 8, 70, 192, 181, 0, 176, 129, - 32, 17, 33, 0, 34, 0, 35, 0, 247, 249, 255, 66, 176, 1, 188, 2, 71, 8, 70, 192, 181, 0, 176, 129, 32, 1, 33, 0, 34, - 0, 35, 0, 247, 249, 255, 54, 176, 1, 188, 2, 71, 8, 70, 192, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 176, - 135, 144, 2, 104, 6, 70, 146, 106, 119, 70, 152, 28, 10, 30, 187, 64, 218, 4, 19, 12, 27, 147, 4, 155, 2, 122, 52, 104, - 90, 155, 4, 106, 53, 51, 128, 0, 91, 90, 211, 104, 112, 70, 153, 43, 0, 208, 84, 30, 107, 64, 227, 70, 155, 28, 10, - 30, 163, 27, 63, 64, 218, 8, 131, 151, 5, 59, 1, 70, 95, 28, 13, 64, 23, 64, 29, 209, 71, 69, 128, 211, 51, 122, 51, - 70, 69, 64, 221, 106, 50, 25, 235, 66, 147, 216, 58, 154, 5, 106, 241, 70, 75, 64, 147, 24, 121, 24, 201, 107, 52, 107, - 176, 28, 42, 70, 83, 240, 0, 248, 184, 28, 4, 40, 0, 209, 33, 122, 51, 28, 41, 64, 153, 70, 67, 26, 91, 25, 127, 70, - 152, 69, 95, 217, 16, 43, 0, 208, 14, 155, 4, 51, 1, 4, 27, 12, 27, 147, 4, 155, 2, 104, 90, 155, 4, 51, 128, 0, 91, - 90, 211, 70, 153, 43, 0, 208, 20, 39, 0, 68, 138, 104, 112, 69, 128, 210, 203, 70, 66, 42, 0, 209, 66, 36, 0, 176, 7, - 28, 32, 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 27, 213, 231, 194, 36, 1, 231, 241, 154, - 5, 70, 75, 64, 147, 147, 3, 106, 243, 154, 3, 24, 251, 24, 153, 75, 59, 147, 1, 104, 27, 66, 153, 208, 71, 107, 52, - 107, 176, 108, 243, 34, 1, 240, 0, 248, 114, 28, 4, 40, 0, 209, 219, 106, 243, 154, 3, 24, 251, 24, 155, 154, 1, 96, - 19, 75, 50, 108, 241, 104, 24, 75, 49, 104, 26, 240, 0, 255, 180, 104, 115, 0, 168, 26, 28, 69, 160, 210, 52, 108, 241, - 70, 66, 24, 9, 70, 80, 240, 0, 255, 169, 34, 0, 68, 194, 55, 1, 70, 144, 104, 112, 231, 131, 155, 5, 106, 241, 70, 77, - 64, 157, 24, 121, 107, 52, 107, 176, 25, 73, 108, 243, 34, 1, 240, 0, 248, 69, 28, 4, 40, 0, 209, 174, 106, 243, 74, - 29, 24, 251, 25, 91, 96, 19, 75, 28, 108, 241, 104, 24, 75, 27, 104, 26, 240, 0, 255, 136, 108, 241, 70, 80, 70, 66, - 240, 0, 255, 131, 231, 156, 75, 21, 74, 22, 108, 240, 104, 25, 104, 18, 240, 0, 255, 123, 231, 197, 108, 241, 28, 34, - 24, 9, 70, 80, 240, 0, 255, 116, 70, 67, 27, 27, 55, 1, 70, 152, 68, 162, 69, 95, 216, 0, 231, 127, 43, 0, 209, 0, 231, - 124, 155, 4, 51, 1, 4, 27, 12, 27, 147, 4, 155, 2, 104, 90, 155, 4, 51, 128, 0, 91, 90, 211, 70, 153, 43, 0, 208, 129, - 39, 0, 104, 112, 231, 56, 19, 112, 128, 64, 19, 112, 136, 120, 19, 112, 136, 124, 71, 32, 70, 192, 181, 16, 104, 2, - 28, 4, 109, 19, 59, 1, 101, 19, 104, 64, 247, 249, 254, 157, 28, 32, 247, 249, 254, 154, 188, 16, 188, 1, 71, 0, 70, - 192, 181, 240, 70, 87, 70, 70, 180, 192, 35, 72, 90, 194, 122, 3, 176, 129, 65, 26, 70, 144, 35, 1, 74, 53, 66, 91, - 96, 19, 143, 130, 28, 6, 70, 138, 42, 0, 208, 32, 37, 0, 39, 0, 224, 3, 53, 1, 68, 71, 66, 170, 217, 25, 104, 51, 25, - 91, 123, 27, 43, 0, 208, 246, 106, 241, 34, 1, 49, 1, 24, 121, 107, 176, 108, 243, 107, 52, 240, 0, 248, 86, 108, 241, - 70, 80, 34, 6, 240, 0, 254, 231, 40, 0, 208, 14, 143, 178, 53, 1, 68, 71, 66, 170, 216, 229, 34, 0, 70, 146, 176, 1, - 70, 80, 188, 12, 70, 144, 70, 154, 188, 240, 188, 2, 71, 8, 32, 12, 247, 249, 254, 97, 70, 130, 40, 0, 208, 38, 70, - 82, 96, 22, 96, 149, 35, 72, 90, 240, 247, 249, 254, 87, 70, 82, 28, 3, 96, 80, 40, 0, 208, 11, 106, 241, 107, 176, - 49, 1, 25, 201, 107, 52, 70, 66, 240, 0, 248, 38, 109, 51, 51, 1, 101, 51, 231, 217, 72, 13, 247, 249, 253, 219, 72, - 13, 247, 249, 253, 216, 72, 12, 247, 249, 253, 213, 70, 80, 247, 249, 254, 46, 35, 0, 70, 154, 231, 202, 72, 6, 247, - 249, 253, 204, 72, 5, 247, 249, 253, 201, 72, 5, 247, 249, 253, 198, 231, 192, 70, 192, 19, 112, 128, 64, 19, 112, 135, - 76, 19, 112, 135, 88, 19, 112, 131, 92, 71, 32, 70, 192, 181, 240, 70, 95, 70, 86, 70, 77, 70, 68, 180, 240, 176, 129, - 70, 139, 153, 10, 70, 130, 32, 84, 70, 145, 28, 31, 70, 136, 247, 249, 254, 18, 28, 5, 47, 0, 209, 87, 32, 128, 0, 128, - 247, 249, 254, 11, 35, 128, 2, 27, 97, 43, 70, 66, 35, 15, 117, 43, 23, 211, 12, 91, 68, 67, 19, 219, 67, 123, 97, 171, - 75, 146, 96, 40, 97, 235, 155, 11, 28, 6, 98, 235, 153, 12, 75, 143, 96, 31, 41, 0, 208, 62, 33, 0, 28, 58, 240, 0, - 254, 210, 35, 87, 112, 51, 35, 66, 112, 115, 35, 70, 112, 179, 35, 83, 28, 60, 112, 243, 47, 0, 209, 0, 224, 242, 35, - 0, 51, 1, 6, 27, 8, 100, 14, 27, 44, 0, 209, 249, 59, 1, 6, 27, 14, 27, 70, 66, 114, 51, 14, 19, 113, 51, 12, 19, 113, - 115, 10, 19, 113, 179, 113, 242, 105, 170, 75, 124, 66, 154, 216, 0, 224, 230, 75, 123, 66, 154, 216, 0, 224, 228, 75, - 122, 66, 154, 216, 0, 224, 226, 75, 121, 66, 154, 216, 0, 224, 224, 75, 120, 66, 154, 216, 0, 224, 222, 34, 11, 125, - 43, 24, 211, 114, 115, 224, 7, 28, 56, 231, 167, 106, 233, 70, 72, 34, 1, 28, 51, 240, 0, 248, 241, 120, 51, 120, 114, - 6, 27, 4, 18, 67, 26, 120, 179, 2, 27, 67, 19, 120, 242, 67, 26, 75, 108, 66, 154, 208, 0, 224, 177, 75, 107, 104, 27, - 66, 92, 65, 92, 44, 0, 208, 29, 47, 0, 208, 0, 224, 121, 44, 0, 208, 24, 70, 65, 41, 0, 208, 21, 121, 50, 121, 115, - 6, 18, 4, 27, 67, 19, 121, 178, 2, 18, 67, 26, 121, 243, 67, 19, 69, 67, 208, 9, 72, 95, 247, 249, 253, 28, 72, 94, - 247, 249, 253, 25, 72, 94, 247, 249, 253, 22, 224, 117, 122, 51, 36, 1, 28, 39, 64, 159, 96, 111, 122, 51, 105, 41, - 114, 43, 121, 51, 121, 114, 6, 27, 4, 18, 67, 26, 121, 179, 121, 240, 2, 27, 67, 19, 67, 24, 96, 232, 240, 0, 253, 64, - 28, 57, 67, 65, 97, 169, 122, 114, 125, 43, 64, 148, 98, 106, 26, 210, 105, 235, 64, 209, 64, 211, 4, 27, 12, 27, 4, - 58, 133, 107, 12, 18, 51, 128, 133, 41, 0, 91, 30, 81, 24, 201, 66, 82, 64, 17, 35, 72, 82, 233, 70, 91, 99, 107, 141, - 43, 70, 82, 99, 42, 8, 219, 122, 42, 98, 44, 26, 228, 70, 73, 64, 212, 99, 169, 100, 44, 153, 12, 41, 0, 209, 63, 100, - 105, 35, 72, 90, 233, 108, 40, 65, 17, 56, 1, 240, 0, 253, 15, 104, 106, 4, 0, 28, 19, 12, 0, 59, 12, 135, 168, 66, - 152, 217, 0, 135, 171, 28, 16, 247, 249, 253, 43, 35, 0, 100, 232, 101, 43, 176, 1, 28, 40, 188, 60, 70, 144, 70, 153, - 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 122, 51, 28, 58, 70, 156, 33, 0, 28, 75, 6, 27, 8, 82, 28, 8, 14, 25, 42, - 0, 209, 248, 69, 96, 209, 0, 231, 119, 72, 35, 247, 249, 252, 165, 72, 37, 247, 249, 252, 162, 72, 34, 247, 249, 252, - 159, 28, 40, 247, 249, 252, 248, 28, 48, 247, 249, 252, 245, 37, 0, 231, 214, 30, 120, 24, 192, 66, 123, 64, 24, 247, - 249, 252, 249, 141, 42, 100, 104, 8, 210, 33, 255, 240, 0, 253, 213, 122, 42, 231, 178, 35, 255, 231, 20, 72, 19, 247, - 249, 252, 132, 72, 21, 247, 249, 252, 129, 72, 18, 247, 249, 252, 126, 231, 221, 34, 6, 231, 39, 34, 7, 231, 37, 34, - 8, 231, 35, 34, 9, 231, 33, 34, 10, 231, 31, 70, 192, 0, 4, 96, 144, 19, 112, 136, 124, 0, 63, 255, 255, 0, 127, 255, - 255, 0, 255, 255, 255, 1, 255, 255, 255, 3, 255, 255, 255, 87, 66, 70, 83, 19, 112, 136, 128, 19, 112, 135, 76, 19, - 112, 135, 196, 19, 112, 131, 92, 19, 112, 135, 164, 19, 112, 135, 152, 71, 80, 70, 192, 181, 240, 70, 95, 70, 86, 70, - 77, 70, 68, 180, 240, 176, 177, 144, 14, 28, 24, 146, 12, 147, 11, 145, 13, 247, 249, 252, 174, 75, 241, 34, 1, 76, - 241, 66, 82, 96, 26, 104, 35, 28, 5, 43, 0, 209, 0, 227, 133, 75, 238, 152, 11, 33, 0, 96, 24, 34, 1, 152, 12, 28, 43, - 156, 14, 240, 0, 251, 158, 40, 0, 208, 0, 226, 183, 35, 255, 0, 91, 92, 235, 43, 85, 209, 0, 226, 232, 172, 32, 28, - 32, 33, 0, 34, 64, 240, 0, 253, 109, 32, 1, 66, 64, 33, 0, 145, 17, 144, 16, 35, 227, 120, 42, 0, 91, 24, 235, 120, - 110, 120, 168, 70, 163, 70, 148, 120, 236, 73, 220, 147, 10, 34, 228, 75, 219, 0, 82, 24, 105, 24, 170, 24, 235, 145, - 9, 146, 8, 147, 7, 33, 235, 74, 216, 35, 236, 0, 73, 0, 91, 24, 105, 24, 170, 24, 235, 145, 6, 146, 5, 147, 4, 70, 90, - 122, 82, 70, 89, 122, 9, 70, 91, 70, 144, 70, 98, 70, 137, 122, 159, 122, 217, 6, 19, 4, 50, 67, 26, 2, 3, 70, 138, - 67, 19, 73, 204, 67, 35, 66, 139, 209, 0, 226, 166, 70, 91, 121, 25, 41, 0, 209, 0, 226, 103, 70, 68, 4, 58, 2, 35, - 67, 19, 70, 78, 70, 80, 67, 51, 6, 2, 67, 19, 70, 152, 41, 15, 208, 0, 226, 110, 28, 25, 152, 12, 34, 1, 28, 43, 156, - 14, 240, 0, 251, 61, 40, 0, 208, 0, 226, 86, 158, 8, 152, 9, 120, 50, 120, 3, 153, 10, 2, 27, 4, 18, 67, 26, 156, 7, - 120, 11, 152, 6, 67, 26, 120, 35, 120, 0, 6, 27, 67, 26, 70, 70, 75, 180, 24, 183, 153, 5, 154, 4, 144, 19, 24, 235, - 120, 9, 120, 18, 147, 15, 120, 28, 70, 137, 70, 146, 148, 18, 152, 12, 28, 57, 34, 1, 28, 43, 158, 14, 240, 0, 251, - 22, 40, 0, 208, 0, 226, 46, 120, 40, 120, 110, 6, 3, 70, 132, 120, 168, 4, 50, 67, 26, 120, 236, 2, 3, 67, 19, 73, 162, - 67, 35, 66, 139, 209, 0, 226, 151, 70, 82, 70, 73, 4, 19, 2, 10, 67, 19, 154, 19, 153, 18, 67, 19, 6, 10, 28, 25, 67, - 17, 209, 0, 226, 12, 70, 66, 24, 140, 152, 12, 28, 33, 34, 1, 28, 43, 158, 14, 240, 0, 250, 238, 40, 0, 208, 0, 226, - 6, 152, 9, 153, 8, 120, 2, 120, 11, 158, 10, 4, 27, 2, 18, 67, 26, 152, 7, 120, 51, 153, 6, 67, 26, 120, 3, 120, 9, - 6, 27, 67, 26, 24, 167, 155, 4, 154, 5, 156, 15, 145, 20, 120, 18, 120, 27, 120, 36, 70, 145, 70, 154, 148, 21, 152, - 12, 28, 57, 34, 1, 28, 43, 158, 14, 240, 0, 250, 201, 40, 0, 208, 0, 225, 225, 120, 40, 120, 110, 6, 3, 70, 132, 120, - 168, 4, 50, 67, 26, 120, 236, 2, 3, 67, 19, 73, 124, 67, 35, 66, 139, 209, 0, 226, 86, 70, 82, 70, 73, 4, 19, 2, 10, - 67, 19, 154, 20, 153, 21, 67, 19, 6, 10, 28, 25, 67, 17, 209, 0, 225, 191, 70, 66, 24, 140, 152, 12, 28, 33, 34, 1, - 28, 43, 158, 14, 240, 0, 250, 161, 40, 0, 208, 0, 225, 185, 152, 9, 153, 8, 120, 2, 120, 11, 158, 10, 4, 27, 2, 18, - 67, 26, 152, 7, 120, 51, 153, 6, 67, 26, 120, 3, 120, 9, 6, 27, 67, 26, 24, 167, 155, 4, 154, 5, 156, 15, 145, 22, 120, - 18, 120, 27, 120, 36, 70, 145, 70, 154, 148, 23, 152, 12, 28, 57, 34, 1, 28, 43, 158, 14, 240, 0, 250, 124, 40, 0, 208, - 0, 225, 148, 120, 40, 120, 110, 6, 3, 70, 132, 120, 168, 4, 50, 67, 26, 120, 236, 2, 3, 67, 19, 73, 85, 67, 35, 66, - 139, 209, 0, 226, 21, 70, 82, 70, 73, 4, 19, 2, 10, 67, 19, 154, 22, 153, 23, 67, 19, 6, 10, 28, 25, 67, 17, 209, 0, - 225, 114, 70, 66, 24, 140, 152, 12, 28, 33, 34, 1, 28, 43, 158, 14, 240, 0, 250, 84, 40, 0, 208, 0, 225, 108, 152, 9, - 153, 8, 120, 2, 120, 11, 158, 10, 4, 27, 2, 18, 67, 26, 152, 7, 120, 51, 153, 6, 67, 26, 120, 3, 120, 9, 6, 27, 67, - 26, 24, 167, 155, 4, 154, 5, 156, 15, 145, 24, 120, 18, 120, 27, 120, 36, 70, 145, 70, 154, 148, 25, 152, 12, 28, 57, - 34, 1, 28, 43, 158, 14, 240, 0, 250, 47, 40, 0, 208, 0, 225, 71, 120, 40, 120, 110, 6, 3, 70, 132, 120, 168, 4, 50, - 67, 26, 120, 236, 2, 3, 67, 19, 73, 47, 67, 35, 66, 139, 209, 0, 225, 212, 70, 82, 70, 73, 4, 19, 2, 10, 67, 19, 154, - 24, 153, 25, 67, 19, 6, 10, 28, 25, 67, 17, 209, 0, 225, 37, 70, 66, 24, 140, 152, 12, 28, 33, 34, 1, 28, 43, 158, 14, - 240, 0, 250, 7, 40, 0, 208, 0, 225, 31, 152, 9, 153, 8, 120, 2, 120, 11, 158, 10, 4, 27, 2, 18, 67, 26, 152, 7, 120, - 51, 153, 6, 67, 26, 120, 3, 120, 9, 6, 27, 67, 26, 24, 167, 155, 4, 154, 5, 156, 15, 145, 26, 120, 18, 120, 27, 120, - 36, 70, 145, 70, 154, 148, 27, 152, 12, 28, 57, 34, 1, 28, 43, 158, 14, 240, 0, 249, 226, 40, 0, 208, 0, 224, 250, 120, - 40, 120, 110, 6, 3, 70, 132, 120, 168, 4, 50, 67, 26, 120, 236, 2, 3, 67, 19, 73, 8, 67, 35, 66, 139, 209, 0, 225, 75, - 224, 15, 19, 112, 128, 64, 19, 112, 136, 120, 19, 112, 136, 124, 0, 0, 1, 199, 0, 0, 1, 201, 0, 0, 1, 215, 87, 66, 70, - 83, 0, 0, 1, 217, 70, 82, 70, 73, 4, 19, 2, 10, 67, 19, 154, 26, 153, 27, 67, 19, 6, 10, 28, 25, 67, 17, 209, 0, 224, - 199, 70, 66, 24, 140, 152, 12, 28, 33, 34, 1, 28, 43, 158, 14, 240, 0, 249, 169, 40, 0, 208, 0, 224, 193, 152, 9, 153, - 8, 120, 2, 120, 11, 158, 10, 4, 27, 2, 18, 67, 26, 152, 7, 120, 51, 153, 6, 67, 26, 120, 3, 120, 9, 6, 27, 67, 26, 24, - 167, 155, 4, 154, 5, 156, 15, 145, 28, 120, 18, 120, 27, 120, 36, 70, 145, 70, 154, 148, 29, 152, 12, 28, 57, 34, 1, - 28, 43, 158, 14, 240, 0, 249, 132, 40, 0, 208, 0, 224, 156, 120, 40, 120, 110, 6, 3, 70, 132, 120, 168, 4, 50, 67, 26, - 120, 236, 2, 3, 67, 19, 73, 182, 67, 35, 66, 139, 209, 0, 224, 249, 70, 82, 70, 73, 4, 19, 2, 10, 67, 19, 154, 28, 153, - 29, 67, 19, 6, 10, 28, 25, 67, 17, 208, 123, 70, 66, 24, 140, 152, 12, 28, 33, 34, 1, 28, 43, 158, 14, 240, 0, 249, - 93, 40, 0, 209, 118, 152, 9, 153, 8, 120, 2, 120, 11, 158, 10, 4, 27, 2, 18, 67, 26, 152, 7, 120, 51, 153, 6, 67, 26, - 120, 3, 120, 9, 6, 27, 67, 26, 24, 167, 155, 4, 154, 5, 156, 15, 145, 30, 120, 18, 120, 27, 120, 36, 70, 145, 70, 154, - 148, 31, 152, 12, 28, 57, 34, 1, 28, 43, 158, 14, 240, 0, 249, 57, 40, 0, 209, 82, 120, 40, 120, 110, 6, 3, 70, 132, - 120, 168, 4, 50, 67, 26, 120, 236, 2, 3, 67, 19, 73, 145, 67, 35, 66, 139, 209, 0, 224, 235, 70, 82, 70, 73, 4, 19, - 2, 10, 67, 19, 154, 30, 153, 31, 67, 19, 6, 10, 28, 25, 67, 17, 208, 49, 70, 66, 24, 84, 152, 12, 28, 33, 34, 1, 28, - 43, 158, 14, 240, 0, 249, 19, 40, 0, 209, 44, 152, 9, 153, 8, 120, 2, 120, 11, 158, 10, 4, 27, 2, 18, 67, 26, 152, 7, - 120, 51, 67, 26, 120, 3, 152, 12, 6, 27, 67, 26, 24, 167, 28, 57, 34, 1, 28, 43, 156, 14, 240, 0, 248, 250, 40, 0, 209, - 20, 120, 46, 120, 168, 6, 51, 70, 180, 120, 110, 120, 236, 4, 50, 67, 26, 2, 3, 67, 19, 73, 114, 67, 35, 66, 139, 209, - 0, 224, 185, 171, 44, 69, 155, 208, 2, 33, 16, 68, 139, 229, 119, 28, 40, 247, 249, 249, 208, 36, 0, 176, 49, 28, 32, - 188, 60, 70, 144, 70, 153, 70, 162, 70, 171, 188, 240, 188, 2, 71, 8, 28, 25, 152, 12, 34, 1, 28, 43, 156, 14, 240, - 0, 248, 206, 28, 1, 40, 0, 209, 231, 120, 46, 120, 168, 6, 51, 70, 180, 120, 110, 120, 236, 4, 50, 67, 26, 2, 3, 67, - 19, 74, 92, 67, 35, 66, 147, 209, 211, 155, 17, 154, 59, 66, 147, 209, 0, 224, 170, 153, 16, 69, 136, 208, 203, 154, - 17, 70, 67, 50, 1, 146, 17, 147, 16, 231, 197, 70, 90, 121, 17, 229, 90, 75, 82, 92, 235, 43, 170, 208, 0, 229, 17, - 28, 232, 73, 80, 34, 4, 240, 0, 251, 6, 40, 0, 209, 0, 229, 9, 76, 78, 28, 40, 48, 54, 28, 33, 34, 3, 240, 0, 250, 252, - 40, 0, 209, 0, 228, 255, 28, 40, 48, 82, 28, 33, 34, 3, 240, 0, 250, 243, 40, 0, 209, 0, 228, 246, 38, 223, 172, 32, - 0, 118, 25, 169, 28, 32, 34, 64, 240, 0, 250, 30, 228, 243, 154, 59, 155, 17, 66, 154, 208, 97, 153, 16, 66, 185, 209, - 0, 230, 188, 51, 1, 147, 17, 151, 16, 230, 184, 154, 59, 155, 17, 66, 154, 208, 85, 153, 16, 66, 185, 209, 0, 230, 253, - 51, 1, 147, 17, 151, 16, 230, 249, 154, 59, 155, 17, 66, 154, 208, 73, 153, 16, 66, 143, 209, 0, 229, 95, 51, 1, 147, - 17, 151, 16, 229, 91, 154, 59, 155, 17, 66, 154, 208, 61, 153, 16, 66, 185, 209, 0, 229, 160, 51, 1, 147, 17, 151, 16, - 229, 156, 154, 59, 155, 17, 66, 154, 208, 49, 153, 16, 66, 185, 209, 0, 229, 225, 51, 1, 147, 17, 151, 16, 229, 221, - 154, 59, 155, 17, 66, 154, 208, 37, 153, 16, 66, 185, 209, 0, 230, 34, 51, 1, 147, 17, 151, 16, 230, 30, 154, 59, 155, - 17, 66, 154, 208, 25, 153, 16, 66, 185, 209, 0, 231, 11, 51, 1, 147, 17, 151, 16, 231, 7, 154, 59, 155, 17, 66, 154, - 208, 13, 153, 16, 66, 143, 209, 0, 231, 61, 154, 17, 151, 16, 50, 1, 146, 17, 231, 56, 152, 11, 247, 249, 249, 27, 96, - 32, 228, 116, 35, 0, 147, 0, 151, 1, 156, 60, 152, 14, 153, 13, 154, 12, 155, 11, 148, 2, 247, 255, 250, 236, 28, 4, - 28, 40, 247, 249, 248, 254, 231, 45, 70, 67, 145, 0, 147, 1, 231, 238, 70, 192, 87, 66, 70, 83, 0, 0, 1, 255, 19, 112, - 135, 224, 19, 112, 135, 232, 71, 32, 71, 48, 0, 0, 0, 0, 239, 0, 0, 204, 225, 47, 255, 30, 225, 160, 0, 0, 225, 160, - 0, 0, 230, 0, 0, 16, 225, 47, 255, 30, 230, 0, 0, 48, 225, 47, 255, 30, 230, 0, 0, 80, 225, 47, 255, 30, 230, 0, 0, - 112, 225, 47, 255, 30, 230, 0, 0, 144, 225, 47, 255, 30, 230, 0, 0, 176, 225, 47, 255, 30, 230, 0, 0, 208, 225, 47, - 255, 30, 230, 0, 0, 240, 225, 47, 255, 30, 230, 0, 1, 16, 225, 47, 255, 30, 230, 0, 1, 48, 225, 47, 255, 30, 230, 0, - 1, 80, 225, 47, 255, 30, 230, 0, 1, 112, 225, 47, 255, 30, 230, 0, 1, 144, 225, 47, 255, 30, 230, 0, 1, 176, 225, 47, - 255, 30, 230, 0, 1, 208, 225, 47, 255, 30, 230, 0, 1, 240, 225, 47, 255, 30, 230, 0, 2, 16, 225, 47, 255, 30, 230, 0, - 2, 48, 225, 47, 255, 30, 230, 0, 2, 80, 225, 47, 255, 30, 230, 0, 2, 112, 225, 47, 255, 30, 230, 0, 2, 144, 225, 47, - 255, 30, 230, 0, 2, 176, 225, 47, 255, 30, 230, 0, 2, 208, 225, 47, 255, 30, 230, 0, 2, 240, 225, 47, 255, 30, 230, - 0, 3, 16, 225, 47, 255, 30, 230, 0, 3, 48, 225, 47, 255, 30, 230, 0, 3, 80, 225, 47, 255, 30, 230, 0, 3, 112, 225, 47, - 255, 30, 230, 0, 3, 144, 225, 47, 255, 30, 230, 0, 3, 176, 225, 47, 255, 30, 230, 0, 3, 208, 225, 47, 255, 30, 230, - 0, 3, 240, 225, 47, 255, 30, 230, 0, 4, 16, 225, 47, 255, 30, 230, 0, 4, 48, 225, 47, 255, 30, 230, 0, 4, 80, 225, 47, - 255, 30, 230, 0, 4, 112, 225, 47, 255, 30, 230, 0, 4, 144, 225, 47, 255, 30, 230, 0, 4, 176, 225, 47, 255, 30, 230, - 0, 4, 208, 225, 47, 255, 30, 230, 0, 4, 240, 225, 47, 255, 30, 230, 0, 5, 16, 225, 47, 255, 30, 230, 0, 5, 48, 225, - 47, 255, 30, 230, 0, 5, 80, 225, 47, 255, 30, 230, 0, 6, 144, 225, 47, 255, 30, 230, 0, 7, 240, 225, 47, 255, 30, 230, - 0, 8, 16, 225, 47, 255, 30, 230, 0, 10, 16, 225, 47, 255, 30, 226, 144, 16, 0, 227, 176, 0, 4, 239, 0, 0, 171, 225, - 47, 255, 30, 225, 160, 0, 0, 225, 160, 0, 0, 41, 0, 208, 52, 35, 1, 34, 0, 180, 16, 66, 136, 211, 44, 36, 1, 7, 36, - 66, 161, 210, 4, 66, 129, 210, 2, 1, 9, 1, 27, 231, 248, 0, 228, 66, 161, 210, 4, 66, 129, 210, 2, 0, 73, 0, 91, 231, - 248, 66, 136, 211, 1, 26, 64, 67, 26, 8, 76, 66, 160, 211, 2, 27, 0, 8, 92, 67, 34, 8, 140, 66, 160, 211, 2, 27, 0, - 8, 156, 67, 34, 8, 204, 66, 160, 211, 2, 27, 0, 8, 220, 67, 34, 40, 0, 208, 3, 9, 27, 208, 1, 9, 9, 231, 227, 28, 16, - 188, 16, 71, 112, 181, 2, 240, 0, 248, 94, 32, 0, 188, 6, 71, 16, 70, 192, 181, 3, 247, 255, 255, 191, 188, 14, 67, - 66, 26, 137, 71, 24, 70, 192, 41, 0, 208, 65, 180, 16, 28, 4, 64, 76, 70, 164, 35, 1, 34, 0, 41, 0, 213, 0, 66, 73, - 40, 0, 213, 0, 66, 64, 66, 136, 211, 44, 36, 1, 7, 36, 66, 161, 210, 4, 66, 129, 210, 2, 1, 9, 1, 27, 231, 248, 0, 228, - 66, 161, 210, 4, 66, 129, 210, 2, 0, 73, 0, 91, 231, 248, 66, 136, 211, 1, 26, 64, 67, 26, 8, 76, 66, 160, 211, 2, 27, - 0, 8, 92, 67, 34, 8, 140, 66, 160, 211, 2, 27, 0, 8, 156, 67, 34, 8, 204, 66, 160, 211, 2, 27, 0, 8, 220, 67, 34, 40, - 0, 208, 3, 9, 27, 208, 1, 9, 9, 231, 227, 28, 16, 70, 100, 44, 0, 213, 0, 66, 64, 188, 16, 71, 112, 181, 2, 240, 0, - 248, 11, 32, 0, 188, 6, 71, 16, 181, 3, 247, 255, 255, 179, 188, 14, 67, 66, 26, 137, 71, 24, 70, 192, 71, 112, 70, - 192, 181, 112, 28, 14, 28, 21, 28, 4, 42, 3, 217, 32, 28, 51, 67, 3, 7, 154, 208, 18, 120, 35, 120, 8, 66, 131, 209, - 27, 30, 106, 224, 6, 52, 1, 49, 1, 120, 35, 120, 8, 58, 1, 66, 131, 209, 18, 42, 0, 209, 246, 32, 0, 188, 112, 188, - 2, 71, 8, 104, 2, 104, 11, 66, 154, 209, 4, 61, 4, 48, 4, 49, 4, 45, 3, 216, 246, 28, 4, 45, 0, 209, 224, 231, 238, - 26, 24, 231, 237, 181, 240, 28, 7, 28, 14, 28, 4, 28, 21, 28, 8, 28, 17, 42, 15, 217, 3, 28, 51, 67, 59, 7, 154, 208, - 11, 41, 0, 208, 5, 34, 0, 92, 131, 84, 163, 50, 1, 66, 138, 209, 250, 28, 56, 188, 240, 188, 2, 71, 8, 28, 58, 28, 49, - 28, 40, 104, 11, 96, 19, 104, 75, 96, 83, 104, 139, 96, 147, 104, 203, 56, 16, 96, 211, 49, 16, 50, 16, 40, 15, 216, - 242, 28, 43, 59, 16, 9, 26, 1, 17, 50, 1, 1, 18, 26, 89, 24, 176, 24, 188, 41, 3, 217, 216, 34, 0, 88, 131, 80, 163, - 50, 4, 26, 139, 43, 3, 216, 249, 31, 11, 8, 154, 0, 145, 50, 1, 0, 146, 26, 89, 24, 128, 24, 164, 231, 200, 181, 240, - 28, 7, 70, 140, 28, 16, 28, 57, 7, 186, 208, 14, 40, 0, 208, 73, 70, 98, 6, 19, 56, 1, 14, 27, 34, 3, 224, 2, 40, 0, - 208, 65, 56, 1, 112, 11, 49, 1, 66, 17, 209, 248, 28, 5, 28, 10, 40, 3, 217, 46, 35, 255, 70, 98, 64, 26, 2, 19, 67, - 19, 4, 26, 28, 20, 28, 14, 67, 28, 40, 15, 217, 18, 28, 2, 28, 11, 58, 16, 96, 28, 96, 92, 96, 156, 96, 220, 51, 16, - 42, 15, 216, 247, 28, 3, 59, 16, 28, 29, 9, 27, 51, 1, 34, 15, 1, 27, 64, 21, 24, 206, 45, 3, 217, 13, 34, 0, 80, 180, - 50, 4, 26, 171, 43, 3, 216, 250, 31, 43, 28, 29, 8, 155, 51, 1, 34, 3, 0, 155, 64, 21, 24, 246, 28, 50, 45, 0, 208, - 7, 70, 97, 6, 11, 14, 25, 35, 0, 84, 209, 51, 1, 66, 157, 209, 251, 28, 56, 188, 240, 188, 2, 71, 8, 70, 192, 181, 48, - 28, 11, 67, 3, 7, 154, 209, 28, 104, 2, 104, 11, 66, 154, 209, 24, 76, 16, 25, 19, 67, 147, 74, 15, 66, 19, 209, 11, - 28, 20, 48, 4, 49, 4, 104, 2, 104, 11, 66, 154, 209, 11, 77, 9, 25, 83, 67, 147, 66, 35, 208, 244, 32, 0, 224, 9, 120, - 10, 66, 154, 209, 5, 48, 1, 49, 1, 120, 3, 43, 0, 209, 247, 120, 10, 26, 152, 188, 48, 188, 2, 71, 8, 254, 254, 254, - 255, 128, 128, 128, 128, 181, 112, 28, 4, 42, 0, 208, 65, 28, 11, 67, 3, 7, 152, 209, 44, 28, 32, 28, 13, 42, 3, 217, - 38, 104, 36, 104, 11, 66, 156, 209, 34, 58, 4, 42, 0, 208, 50, 73, 27, 24, 99, 73, 27, 67, 163, 66, 11, 209, 44, 28, - 12, 224, 11, 104, 1, 104, 43, 66, 153, 209, 19, 58, 4, 42, 0, 208, 35, 78, 19, 25, 139, 67, 139, 66, 35, 209, 30, 48, - 4, 53, 4, 42, 3, 216, 239, 28, 4, 28, 41, 42, 0, 209, 5, 120, 3, 120, 40, 26, 24, 224, 19, 28, 4, 28, 41, 120, 35, 120, - 8, 58, 1, 66, 152, 208, 9, 231, 245, 40, 0, 208, 8, 52, 1, 49, 1, 120, 35, 120, 8, 66, 152, 209, 237, 58, 1, 42, 0, - 209, 244, 32, 0, 188, 112, 188, 2, 71, 8, 254, 254, 254, 255, 128, 128, 128, 128, 73, 79, 83, 32, 109, 111, 100, 117, - 108, 101, 0, 0, 0, 0, 0, 1, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255, 229, 31, 240, 4, 0, 0, 0, 0, 19, 115, 115, 68, 0, 15, 66, 64, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, - 255, 255, 87, 66, 70, 83, 32, 110, 111, 116, 32, 101, 110, 111, 117, 103, 104, 32, 109, 101, 109, 111, 114, 121, 33, - 10, 0, 0, 0, 0, 47, 100, 101, 118, 47, 117, 115, 98, 50, 0, 0, 0, 47, 100, 101, 118, 47, 117, 115, 98, 50, 47, 0, 0, - 19, 112, 30, 144, 19, 112, 28, 80, 19, 112, 28, 80, 19, 112, 28, 80, 19, 112, 28, 80, 19, 112, 30, 144, 19, 112, 28, - 80, 19, 112, 28, 80, 19, 112, 28, 80, 19, 112, 28, 80, 19, 112, 28, 80, 19, 112, 28, 80, 19, 112, 28, 80, 19, 112, 28, - 80, 19, 112, 28, 80, 19, 112, 30, 124, 19, 112, 28, 80, 19, 112, 29, 72, 19, 112, 28, 80, 19, 112, 28, 80, 19, 112, - 28, 98, 32, 32, 32, 32, 108, 111, 103, 95, 115, 116, 97, 116, 117, 115, 32, 32, 40, 37, 115, 41, 10, 0, 0, 0, 32, 65, - 115, 121, 110, 99, 0, 0, 32, 80, 101, 114, 105, 111, 100, 105, 99, 0, 0, 0, 32, 82, 101, 99, 108, 0, 0, 0, 32, 72, 97, - 108, 116, 0, 0, 0, 32, 73, 65, 65, 0, 0, 0, 0, 32, 70, 65, 84, 65, 76, 0, 0, 32, 70, 76, 82, 0, 0, 0, 0, 32, 80, 67, - 68, 0, 0, 0, 0, 32, 69, 82, 82, 0, 0, 0, 0, 32, 73, 78, 84, 0, 0, 0, 0, 32, 32, 32, 32, 115, 116, 97, 116, 117, 115, - 58, 32, 37, 120, 32, 37, 115, 37, 115, 37, 115, 37, 115, 37, 115, 37, 115, 37, 115, 37, 115, 37, 115, 37, 115, 10, 0, - 0, 0, 0, 32, 32, 32, 32, 115, 116, 97, 116, 117, 115, 32, 112, 111, 114, 116, 58, 32, 37, 120, 10, 0, 0, 0, 0, 117, - 115, 98, 115, 116, 111, 114, 97, 103, 101, 32, 114, 101, 115, 101, 116, 58, 32, 66, 85, 76, 75, 32, 82, 69, 83, 69, - 84, 32, 37, 105, 10, 0, 0, 0, 0, 117, 115, 98, 115, 116, 111, 114, 97, 103, 101, 32, 114, 101, 115, 101, 116, 58, 32, - 99, 108, 101, 97, 114, 104, 97, 108, 116, 32, 105, 110, 32, 114, 101, 116, 32, 37, 105, 10, 0, 0, 117, 115, 98, 115, - 116, 111, 114, 97, 103, 101, 32, 114, 101, 115, 101, 116, 58, 32, 99, 108, 101, 97, 114, 104, 97, 108, 116, 32, 111, - 117, 116, 32, 114, 101, 116, 32, 37, 105, 10, 0, 117, 115, 98, 115, 116, 111, 114, 97, 103, 101, 32, 114, 101, 115, - 101, 116, 58, 32, 85, 83, 66, 95, 71, 101, 116, 67, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 32, 114, - 101, 116, 32, 37, 105, 10, 0, 0, 95, 95, 115, 101, 110, 100, 95, 99, 98, 119, 32, 114, 101, 116, 32, 37, 105, 10, 0, - 0, 95, 115, 101, 110, 100, 95, 99, 98, 119, 0, 0, 0, 95, 95, 85, 83, 66, 95, 66, 108, 107, 77, 115, 103, 84, 105, 109, - 101, 111, 117, 116, 32, 37, 105, 10, 0, 95, 95, 85, 83, 66, 95, 66, 108, 107, 77, 115, 103, 84, 105, 109, 101, 111, - 117, 116, 0, 95, 95, 114, 101, 97, 100, 95, 99, 115, 119, 32, 37, 105, 10, 0, 0, 95, 95, 114, 101, 97, 100, 95, 99, - 115, 119, 0, 0, 32, 32, 32, 32, 83, 67, 83, 73, 95, 84, 69, 83, 84, 95, 85, 78, 73, 84, 95, 82, 69, 65, 68, 89, 32, - 114, 101, 116, 32, 37, 105, 10, 0, 0, 0, 0, 32, 32, 32, 32, 83, 67, 83, 73, 95, 82, 69, 81, 85, 69, 83, 84, 95, 83, - 69, 78, 83, 69, 32, 114, 101, 116, 32, 37, 105, 10, 0, 0, 32, 32, 32, 32, 83, 67, 83, 73, 95, 82, 69, 81, 85, 69, 83, - 84, 95, 83, 69, 78, 83, 69, 32, 115, 116, 97, 116, 117, 115, 32, 37, 120, 10, 0, 0, 0, 32, 32, 32, 32, 115, 116, 97, - 114, 116, 95, 115, 116, 111, 112, 32, 99, 109, 100, 32, 114, 101, 116, 32, 37, 105, 10, 0, 0, 32, 32, 32, 32, 73, 110, - 113, 117, 105, 114, 121, 32, 114, 101, 116, 32, 37, 105, 10, 0, 32, 32, 32, 32, 82, 101, 97, 100, 67, 97, 112, 97, 99, - 105, 116, 121, 32, 114, 101, 116, 32, 37, 105, 10, 0, 0, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, - 112, 101, 110, 40, 41, 58, 32, 100, 101, 118, 105, 99, 101, 32, 99, 104, 97, 110, 103, 101, 100, 33, 33, 33, 10, 0, - 0, 0, 32, 67, 108, 101, 97, 114, 32, 101, 114, 114, 111, 114, 32, 114, 101, 116, 32, 37, 105, 10, 0, 0, 0, 0, 85, 110, - 112, 108, 117, 103, 58, 32, 114, 101, 115, 101, 116, 95, 112, 111, 114, 116, 32, 114, 101, 116, 32, 37, 105, 32, 112, - 111, 114, 116, 32, 115, 116, 97, 116, 117, 115, 32, 37, 120, 10, 0, 0, 0, 102, 97, 115, 116, 95, 114, 101, 109, 111, - 117, 110, 116, 32, 79, 75, 10, 0, 0, 0, 0, 102, 97, 115, 116, 95, 114, 101, 109, 111, 117, 110, 116, 32, 75, 79, 32, - 114, 101, 116, 32, 37, 105, 10, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, - 85, 83, 66, 95, 71, 101, 116, 68, 101, 115, 99, 114, 105, 112, 116, 111, 114, 115, 32, 37, 105, 10, 0, 0, 0, 97, 102, - 116, 101, 114, 32, 85, 83, 66, 95, 71, 101, 116, 68, 101, 115, 99, 114, 105, 112, 116, 111, 114, 115, 0, 0, 0, 0, 85, - 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 117, 99, 100, 32, 37, 105, 32, 80, 111, - 119, 101, 114, 32, 37, 105, 32, 109, 65, 10, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, - 40, 41, 58, 32, 105, 110, 116, 101, 114, 102, 97, 99, 101, 32, 115, 117, 98, 99, 108, 97, 115, 115, 32, 37, 105, 32, - 97, 116, 97, 95, 112, 114, 111, 116, 32, 37, 105, 32, 10, 0, 0, 73, 110, 32, 80, 111, 105, 110, 116, 58, 32, 37, 105, - 10, 0, 0, 0, 79, 117, 116, 32, 80, 111, 105, 110, 116, 58, 32, 37, 105, 10, 0, 0, 101, 112, 95, 105, 110, 32, 37, 120, - 32, 101, 112, 95, 111, 117, 116, 32, 37, 120, 10, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, - 110, 40, 41, 58, 32, 99, 97, 110, 110, 111, 116, 32, 102, 105, 110, 100, 32, 97, 110, 121, 32, 105, 110, 116, 101, 114, - 102, 97, 99, 101, 33, 33, 33, 10, 0, 0, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40, - 41, 58, 32, 99, 111, 110, 102, 58, 32, 37, 120, 32, 97, 108, 116, 73, 110, 116, 101, 114, 102, 97, 99, 101, 58, 32, - 37, 120, 10, 0, 0, 0, 97, 102, 116, 101, 114, 32, 85, 83, 66, 95, 71, 101, 116, 67, 111, 110, 102, 105, 103, 117, 114, - 97, 116, 105, 111, 110, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 99, - 104, 97, 110, 103, 105, 110, 103, 32, 99, 111, 110, 102, 32, 102, 114, 111, 109, 32, 37, 120, 10, 0, 0, 0, 66, 101, - 102, 111, 114, 101, 32, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 82, 101, 115, 101, 116, 0, 65, 102, 116, 101, - 114, 32, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 82, 101, 115, 101, 116, 0, 0, 85, 83, 66, 83, 116, 111, 114, - 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 116, 114, 121, 95, 115, 116, 97, 116, 117, 115, 32, 37, 105, 10, - 0, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 79, 112, 101, 110, 40, 41, 58, 32, 114, 101, 116, 117, 114, - 110, 32, 48, 10, 0, 0, 0, 0, 70, 97, 115, 116, 32, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 77, 111, 117, 110, - 116, 76, 85, 78, 32, 37, 105, 35, 10, 0, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 77, 111, 117, 110, 116, - 76, 85, 78, 58, 32, 114, 101, 116, 32, 37, 105, 10, 0, 0, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 77, - 111, 117, 110, 116, 76, 85, 78, 32, 37, 105, 35, 10, 0, 0, 0, 0, 85, 83, 66, 83, 84, 79, 82, 65, 71, 69, 95, 71, 69, - 84, 95, 77, 65, 88, 95, 76, 85, 78, 32, 114, 101, 116, 32, 37, 105, 32, 109, 97, 120, 108, 117, 110, 32, 37, 105, 10, - 0, 0, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 77, 111, 117, 110, 116, 76, 85, 78, 32, 102, 97, 105, 108, - 33, 33, 33, 10, 0, 0, 0, 0, 10, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 10, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 73, 110, 105, 116, 40, 41, 10, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 10, 10, 0, 0, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, - 101, 95, 73, 110, 105, 116, 40, 41, 32, 79, 107, 10, 0, 0, 0, 85, 83, 66, 83, 116, 111, 114, 97, 103, 101, 95, 73, 110, - 105, 116, 40, 41, 32, 115, 116, 97, 116, 117, 115, 32, 37, 120, 10, 0, 0, 0, 0, 85, 83, 66, 32, 65, 108, 108, 111, 99, - 58, 32, 110, 111, 116, 32, 101, 110, 111, 117, 103, 104, 32, 109, 101, 109, 111, 114, 121, 33, 10, 0, 0, 119, 98, 102, - 115, 32, 101, 114, 114, 111, 114, 32, 0, 97, 108, 108, 111, 99, 97, 116, 105, 110, 103, 32, 109, 101, 109, 111, 114, - 121, 0, 0, 0, 116, 114, 121, 105, 110, 103, 32, 116, 111, 32, 99, 108, 111, 115, 101, 32, 119, 98, 102, 115, 32, 119, - 104, 105, 108, 101, 32, 100, 105, 115, 99, 115, 32, 115, 116, 105, 108, 108, 32, 111, 112, 101, 110, 0, 98, 97, 100, - 32, 109, 97, 103, 105, 99, 0, 0, 0, 104, 100, 32, 115, 101, 99, 116, 111, 114, 32, 115, 105, 122, 101, 32, 100, 111, - 101, 115, 110, 39, 116, 32, 109, 97, 116, 99, 104, 0, 0, 0, 0, 104, 100, 32, 110, 117, 109, 32, 115, 101, 99, 116, 111, - 114, 32, 100, 111, 101, 115, 110, 39, 116, 32, 109, 97, 116, 99, 104, 0, 78, 84, 70, 83, 0, 0, 0, 0, 70, 65, 84, 0 -}; diff --git a/source/mload/ehcmodule.h b/source/mload/ehcmodule.h deleted file mode 100644 index 82566eac..00000000 --- a/source/mload/ehcmodule.h +++ /dev/null @@ -1,3 +0,0 @@ -#define size_ehcmodule 32432 - -extern unsigned char ehcmodule[32432]; diff --git a/source/mload/mload.c b/source/mload/mload.c index 6c6394b7..93c9872d 100644 --- a/source/mload/mload.c +++ b/source/mload/mload.c @@ -16,7 +16,7 @@ */ #include "mload.h" -#include "ehcmodule.h" +#include "ehcmodule_fat_bin.h" #include "dip_plugin.h" #include @@ -549,7 +549,7 @@ int load_ehc_module() if(!external_ehcmodule) { if(mload_init()<0) return -1; - mload_elf((void *) ehcmodule, &my_data_elf); + mload_elf((void *) ehcmodule_fat_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; } diff --git a/source/patches/fst.c b/source/patches/fst.c index 4321a95b..56b610c8 100644 --- a/source/patches/fst.c +++ b/source/patches/fst.c @@ -37,6 +37,9 @@ extern struct SSettings Settings; +// Pre-allocate the buffer size for ocarina codes +u8 filebuff[MAX_GCT_SIZE]; + u32 do_sd_code(char *filename) { FILE *fp; @@ -73,28 +76,17 @@ u32 do_sd_code(char *filename) } fseek(fp, 0, SEEK_SET); - filebuff = (u8*) malloc (filesize); - if(filebuff == 0){ - fclose(fp); - sleep(2); - USBDevice_deInit(); - SDCard_deInit(); - return 0; - } - - ret = fread(filebuff, 1, filesize, fp); + ret = fread(&filebuff, 1, filesize, fp); if(ret != filesize){ - free(filebuff); fclose(fp); USBDevice_deInit(); SDCard_deInit(); return 0; } - memcpy((void*)0x800027E8,filebuff,filesize); + memcpy((void*)0x800027E8, &filebuff,filesize); *(vu8*)0x80001807 = 0x01; - free(filebuff); fclose(fp); USBDevice_deInit(); diff --git a/source/patches/fst.h b/source/patches/fst.h index 21491afd..7ef9ed28 100644 --- a/source/patches/fst.h +++ b/source/patches/fst.h @@ -27,6 +27,8 @@ extern "C" { #endif +#define MAX_GCT_SIZE 2056 + //u32 do_fst(u32 fstlocation); u32 do_sd_code(char *filename); diff --git a/source/prompts/ProgressWindow.cpp b/source/prompts/ProgressWindow.cpp index 951581e0..597851e5 100644 --- a/source/prompts/ProgressWindow.cpp +++ b/source/prompts/ProgressWindow.cpp @@ -16,6 +16,7 @@ #include "libwiigui/gui.h" #include "prompts/ProgressWindow.h" #include "usbloader/wbfs.h" +#include "usbloader/utils.h" /*** Variables used only in this file ***/ static lwp_t progressthread = LWP_THREAD_NULL; @@ -73,7 +74,7 @@ static void GameInstallProgress() { //Calculate speed in MB/s if (elapsed > 0) - speed = KBSIZE * gamesize * gameinstalldone/(gameinstalltotal*elapsed); + speed = KB_SIZE * gamesize * gameinstalldone/(gameinstalltotal*elapsed); if (gameinstalldone != gameinstalltotal) { //Expected time @@ -356,7 +357,7 @@ void ShowProgress(const char *title, const char *msg1, char *dynmsg2, f32 done, //Calculate speed in KB/s if (elapsed > 0) - speed = done/(elapsed*KBSIZE); + speed = done/(elapsed*KB_SIZE); if (done != total) { //Expected time @@ -376,12 +377,12 @@ void ShowProgress(const char *title, const char *msg1, char *dynmsg2, f32 done, } if (swSize == true) { - if (total < MBSIZE) - snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fKB/%0.2fKB", done * done/total / KBSIZE, total/KBSIZE); - else if (total > MBSIZE && total < GBSIZE) - snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fMB/%0.2fMB", done * done/total / MBSIZE, total/MBSIZE); + if (total < MB_SIZE) + snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fKB/%0.2fKB", done * done/total / KB_SIZE, total/KB_SIZE); + else if (total > MB_SIZE && total < GB_SIZE) + snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fMB/%0.2fMB", done * done/total / MB_SIZE, total/MB_SIZE); else - snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fGB/%0.2fGB", done * done/total / GBSIZE, total/GBSIZE); + snprintf(progressSizeLeft, sizeof(progressSizeLeft), "%0.2fGB/%0.2fGB", done * done/total / GB_SIZE, total/GB_SIZE); } showProgress = 1; diff --git a/source/prompts/ProgressWindow.h b/source/prompts/ProgressWindow.h index 632ac9fd..a0df8864 100644 --- a/source/prompts/ProgressWindow.h +++ b/source/prompts/ProgressWindow.h @@ -8,10 +8,6 @@ #ifndef _PROGRESSWINDOW_H_ #define _PROGRESSWINDOW_H_ -#define KBSIZE 1024.0 -#define MBSIZE 1048576.0 -#define GBSIZE 1073741824.0 - void InitProgressThread(); void ExitProgressThread(); void SetupGameInstallProgress(char * titl, char * game); diff --git a/source/prompts/TitleBrowser.cpp b/source/prompts/TitleBrowser.cpp index f28df747..9bc18aaf 100644 --- a/source/prompts/TitleBrowser.cpp +++ b/source/prompts/TitleBrowser.cpp @@ -25,6 +25,7 @@ #include "xml/xml.h" #include "../wad/title.h" #include "../usbloader/getentries.h" +#include "../usbloader/utils.h" #define typei 0x00010001 @@ -420,10 +421,10 @@ int TitleBrowser(u32 type) { snprintf(filepath, sizeof(filepath), "%s/wad/tmp.tmp", bootDevice); - if (infilesize < MBSIZE) - snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fKB"), infilesize/KBSIZE); + if (infilesize < MB_SIZE) + snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fKB"), infilesize/KB_SIZE); else - snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fMB"), infilesize/MBSIZE); + snprintf(filesizetxt, sizeof(filesizetxt), tr("Incoming file %0.2fMB"), infilesize/MB_SIZE); snprintf(temp, sizeof(temp), tr("Load file from: %s ?"), GetIncommingIP()); diff --git a/source/settings/Settings.cpp b/source/settings/Settings.cpp index 221d08dd..b9d0ee89 100644 --- a/source/settings/Settings.cpp +++ b/source/settings/Settings.cpp @@ -17,6 +17,8 @@ #include "listfiles.h" #include "sys.h" #include "cfg.h" +#include "usbloader/partition.h" +#include "usbloader/utils.h" #define MAXOPTIONS 13 @@ -36,7 +38,9 @@ extern u8 shutdown; extern u8 reset; extern u8 mountMethod; extern struct discHdr *dvdheader; - +extern PartList partitions; +extern char game_partition[6]; +extern bool load_from_fat; 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") }; @@ -46,6 +50,14 @@ static const char *opts_cios[settings_ios_max] = {"IOS 249","IOS 222", "IOS 223" 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")}; +bool IsValidPartition(int fs_type, int cios) { + if (cios == 249) { + return fs_type == FS_TYPE_WBFS; + } else { + return fs_type == FS_TYPE_WBFS || fs_type == FS_TYPE_FAT32; + } +} + /**************************************************************************** * MenuSettings ***************************************************************************/ @@ -968,10 +980,31 @@ int MenuSettings() if(ret == Idx && Settings.godmode == 1 && ++Settings.cios >= settings_cios_max) Settings.cios = 0; if (Settings.godmode == 1) - options2.SetValue(Idx,"%s", opts_cios[Settings.cios]); + options2.SetValue(Idx, "%s", opts_cios[Settings.cios]); else options2.SetValue(Idx, "********"); } + + if (ret == ++Idx || firstRun) + { + 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)); + } + + PartInfo pInfo = partitions.pinfo[Settings.partition]; + f32 partition_size = partitions.pentry[Settings.partition].size * (partitions.sector_size / GB_SIZE); + + // Get the partition name and it's size in GB's + options2.SetValue(Idx,"%s%d (%.2fGB)", pInfo.fs_type == FS_TYPE_FAT32 ? "FAT" : "WBFS", + pInfo.fs_type == FS_TYPE_FAT32 ? pInfo.fat_i : pInfo.wbfs_i, + partition_size); + } if(ret == ++Idx || firstRun) { @@ -2016,6 +2049,12 @@ int MenuSettings() if (opt_override != opt_overridenew && Settings.titlesOverride==0) titles_default(); + // Reinitialize WBFS partition, it might have changed + PartInfo pinfo = partitions.pinfo[Settings.partition]; + load_from_fat = pinfo.fs_type == FS_TYPE_FAT32; + WBFS_Close(); + WBFS_OpenPart(load_from_fat, Settings.partition, partitions.pentry[Settings.partition].sector, partitions.pentry[Settings.partition].size, (char *) &game_partition); + HaltGui(); mainWindow->RemoveAll(); @@ -2038,9 +2077,6 @@ int GameSettings(struct discHdr * header) int retVal = 0; - - - GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, Settings.sfxvolume); // because destroy GuiSound must wait while sound playing is finished, we use a global sound if(!btnClick2) btnClick2=new GuiSound(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); diff --git a/source/settings/cfg.c b/source/settings/cfg.c index 0e468b7a..ef285373 100644 --- a/source/settings/cfg.c +++ b/source/settings/cfg.c @@ -24,7 +24,7 @@ u8 videoChoice = 0; u8 faveChoice = no; u8 languageChoice = 0; u8 viChoice = 0; -u8 iosChoice = 0; +u8 iosChoice = 1; // Default IOS is 222 from now on u8 parentalcontrolChoice = 0; u8 fix002 = 0; u8 reloadblock = 0; @@ -40,6 +40,7 @@ u8 keyset = 0; u8 favoritevar = 0; u16 playcount = 0; u8 listDisplay = 0; +u8 partition = -1; char alternatedname[40]; #define TITLE_MAX 200 @@ -339,7 +340,7 @@ void Global_Default(void) { Settings.godmode = 1; Settings.gamesound = 1; Settings.parentalcontrol = 0; - Settings.cios = ios249; + Settings.cios = ios222; Settings.xflip = no; Settings.qboot = no; Settings.wiilight = 1; @@ -353,6 +354,7 @@ void Global_Default(void) { snprintf(Settings.db_language, sizeof(Settings.db_language), empty); Settings.db_JPtoEN = 0; Settings.screensaver = 3; + Settings.partition = -1; } @@ -1035,7 +1037,13 @@ void global_cfg_set(char *name, char *val) { Settings.screensaver = i; } return; - } + } else if (strcmp(name, "partition") == 0) { + int i; + if (sscanf(val, "%d", &i) == 1) { + Settings.partition = i; + } + return; + } cfg_bool("godmode", &Settings.godmode); @@ -1278,6 +1286,7 @@ bool cfg_save_global() { // save global settings fprintf(f, "error002 = %d\n ", Settings.error002); fprintf(f, "autonetwork = %d\n ", Settings.autonetwork); fprintf(f, "discart = %d\n ", Settings.discart); + fprintf(f, "partition = %d\n", Settings.partition); fclose(f); return true; } @@ -1609,6 +1618,7 @@ bool cfg_load_global() { Settings.gamesoundvolume = 80; Settings.titlesOverride = 1; + Settings.partition = -1; char * empty = ""; snprintf(Settings.db_url, sizeof(Settings.db_url), empty); snprintf(Settings.db_language, sizeof(Settings.db_language), empty); diff --git a/source/settings/cfg.h b/source/settings/cfg.h index 3b0aff23..674a4236 100644 --- a/source/settings/cfg.h +++ b/source/settings/cfg.h @@ -393,6 +393,7 @@ extern "C" { u8 gameDisplay; u8 patchcountrystrings; u8 screensaver; + u8 partition; short godmode; char covers_path[100]; char covers2d_path[100]; diff --git a/source/sys.cpp b/source/sys.cpp index e4346937..2396e828 100644 --- a/source/sys.cpp +++ b/source/sys.cpp @@ -14,6 +14,9 @@ #include "sys.h" #include "wpad.h" +extern char game_partition[6]; +extern bool load_from_fat; + //Wiilight stuff static vu32 *_wiilight_reg = (u32*)0xCD0000C0; void wiilight(int enable) { // Toggle wiilight (thanks Bool for wiilight source) @@ -62,6 +65,49 @@ void Sys_Reboot(void) { 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(); + + USBStorage_Deinit(); + + s32 ret = IOS_ReloadIOS(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 (load_from_fat && (ios == 222 || ios == 223)) { + WBFS_OpenNamed((char *) &game_partition); + } else { + WBFS_Open(); + } + + return ret; +} + int Sys_IosReload(int IOS) { s32 ret = -1; @@ -156,3 +202,7 @@ void Sys_BackToLoader(void) { // Channel Version Sys_LoadMenu(); } + +bool Sys_IsHermes() { + return IOS_GetVersion() == 222 || IOS_GetVersion() == 223; +} diff --git a/source/sys.h b/source/sys.h index 03c021e4..f2f0c2d0 100644 --- a/source/sys.h +++ b/source/sys.h @@ -11,6 +11,8 @@ void Sys_ShutdownToIdel(void); void Sys_ShutdownToStandby(void); void Sys_LoadMenu(void); void Sys_BackToLoader(void); +int Sys_ChangeIos(int ios); int Sys_IosReload(int IOS); +bool Sys_IsHermes(); #endif diff --git a/source/usbloader/alternatedol.c b/source/usbloader/alternatedol.c index 28c5027f..ff4f6686 100644 --- a/source/usbloader/alternatedol.c +++ b/source/usbloader/alternatedol.c @@ -216,7 +216,7 @@ u32 Load_Dol_from_disc(u32 doloffset, u8 videoSelected, u8 patchcountrystring, u void *offset; u32 pos; u32 len; - + while (load_dol_image_modified(&offset, &pos, &len)) { if (len != 0) { ret = WDVD_Read(offset, len, (doloffset<<2) + pos); diff --git a/source/usbloader/disc.c b/source/usbloader/disc.c index 40e4ca54..c57505de 100644 --- a/source/usbloader/disc.c +++ b/source/usbloader/disc.c @@ -22,6 +22,9 @@ static u32 *buffer = (u32 *)0x93000000; static u8 *diskid = (u8 *)Disc_ID; +extern int wbfs_part_fat; +extern u32 wbfs_part_idx; +extern u32 wbfs_part_lba; void __Disc_SetLowMem(void) { @@ -235,8 +238,15 @@ s32 Disc_Wait(void) { } s32 Disc_SetUSB(const u8 *id) { + u32 part = 0; + if (wbfs_part_fat) { + part = wbfs_part_lba; + } else { + part = wbfs_part_idx ? wbfs_part_idx - 1 : 0; + } + /* Set USB mode */ - return WDVD_SetUSBMode(id); + return WDVD_SetUSBMode(id, part); } s32 Disc_ReadHeader(void *outbuf) { diff --git a/source/usbloader/getentries.cpp b/source/usbloader/getentries.cpp index e0d5520f..db4fcc03 100644 --- a/source/usbloader/getentries.cpp +++ b/source/usbloader/getentries.cpp @@ -469,6 +469,7 @@ int __Menu_GetGameList(int t, wchar_t* gameFilter, discHdr ** PgameList, u32 *Pg if (buffer) free(buffer); return ret; } + for (u32 i = 0; i < cnt; i++) { struct discHdr *header = &buffer[i]; diff --git a/source/usbloader/partition.c b/source/usbloader/partition.c index 99bb1db1..58233185 100644 --- a/source/usbloader/partition.c +++ b/source/usbloader/partition.c @@ -4,7 +4,10 @@ #include "partition.h" #include "usbstorage.h" +#include "sdhc.h" #include "utils.h" +#include "libwbfs/libwbfs.h" +#include "wbfs.h" /* 'partition table' structure */ typedef struct { @@ -15,7 +18,6 @@ typedef struct { partitionEntry entries[MAX_PARTITIONS]; } ATTRIBUTE_PACKED partitionTable; - s32 Partition_GetEntries(partitionEntry *outbuf, u32 *outval) { static partitionTable table ATTRIBUTE_ALIGN(32); @@ -48,3 +50,141 @@ s32 Partition_GetEntries(partitionEntry *outbuf, u32 *outval) { return 0; } + +s32 Partition_GetEntriesEx(partitionEntry *outbuf, u32 *outval, int *num) +{ + static partitionTable table ATTRIBUTE_ALIGN(32); + partitionEntry *entry; + + u32 i, sector_size; + s32 ret; + int maxpart = *num; + + // Get sector size + ret = USBStorage_GetCapacity(§or_size); + if (ret == 0) return -1; + + u32 ext = 0; + u32 next = 0; + + // Read partition table + ret = USBStorage_ReadSectors(0, 1, &table); + if (!ret) return -1; + /* Swap endianess */ + for (i = 0; i < 4; i++) { + entry = &table.entries[i]; + entry->sector = swap32(entry->sector); + entry->size = swap32(entry->size); + if (!ext && entry->type == 0x0f) ext = entry->sector; + } + /* Set partition entries */ + memcpy(outbuf, table.entries, sizeof(table.entries)); + /* Set sector size */ + *outval = sector_size; + // num primary + *num = 4; + + next = ext; + // scan extended partition for logical + if (ext) for(i=0; isector = swap32(entry->sector); + entry->size = swap32(entry->size); + if (entry->type && entry->size && entry->sector) { + // rebase to abolute address + entry->sector += next; + // add logical + memcpy(&outbuf[*num], entry, sizeof(*entry)); + (*num)++; + // get next + entry++; + if (entry->type && entry->size && entry->sector) { + next = ext + swap32(entry->sector); + } else { + break; + } + } + + } + + return 0; +} + +char* part_type_data(int type) +{ + switch (type) { + case 0x01: return "FAT12"; + case 0x04: return "FAT16"; + case 0x06: return "FAT16"; //+ + case 0x07: return "NTFS"; + case 0x0b: return "FAT32"; + case 0x0c: return "FAT32"; + case 0x0e: return "FAT16"; + case 0x82: return "LxSWP"; + case 0x83: return "LINUX"; + case 0x8e: return "LxLVM"; + case 0xa8: return "OSX"; + case 0xab: return "OSXBT"; + case 0xaf: return "OSXHF"; + case 0xe8: return "LUKS"; + } + return NULL; +} + +int get_fs_type(char *buf) +{ + // WBFS + wbfs_head_t *head = (wbfs_head_t *)buf; + if (head->magic == wbfs_htonl(WBFS_MAGIC)) return FS_TYPE_WBFS; + // 55AA + if (buf[0x1FE] == 0x55 && buf[0x1FF] == 0xAA) { + // FAT + if (memcmp(buf+0x36,"FAT",3) == 0) return FS_TYPE_FAT16; + if (memcmp(buf+0x52,"FAT",3) == 0) return FS_TYPE_FAT32; + // NTFS + if (memcmp(buf+0x03,"NTFS",4) == 0) return FS_TYPE_NTFS; + } + return FS_TYPE_UNK; +} + +bool is_type_fat(int type) +{ + return (type == FS_TYPE_FAT16 || type == FS_TYPE_FAT32); +} + +s32 Partition_GetList(PartList *plist) +{ + partitionEntry *entry = NULL; + PartInfo *pinfo = NULL; + int i, ret; + + memset(plist, 0, sizeof(PartList)); + + // Get partition entries + plist->num = MAX_PARTITIONS_EX; + ret = Partition_GetEntriesEx(plist->pentry, &plist->sector_size, &plist->num); + if (ret < 0) { + return -1; + } + char buf[plist->sector_size]; + + // scan partitions for filesystem type + for (i = 0; i < plist->num; i++) { + pinfo = &plist->pinfo[i]; + entry = &plist->pentry[i]; + if (!entry->size) continue; + if (!part_type_data(entry->type)) continue; + if (!USBStorage_ReadSectors(entry->sector, 1, buf)) continue; + pinfo->fs_type = get_fs_type(buf); + if (pinfo->fs_type == FS_TYPE_WBFS) { + plist->wbfs_n++; + pinfo->wbfs_i = plist->wbfs_n; + } else if (is_type_fat(pinfo->fs_type)) { + plist->fat_n++; + pinfo->fat_i = plist->fat_n; + } + } + return 0; +} diff --git a/source/usbloader/partition.h b/source/usbloader/partition.h index f7716419..6aa881d1 100644 --- a/source/usbloader/partition.h +++ b/source/usbloader/partition.h @@ -27,10 +27,36 @@ extern "C" { } ATTRIBUTE_PACKED partitionEntry; /* Constants */ -#define MAX_PARTITIONS 4 + #define MAX_PARTITIONS 4 + #define MAX_PARTITIONS_EX 10 + + #define FS_TYPE_UNK 0 + #define FS_TYPE_FAT16 1 + #define FS_TYPE_FAT32 2 + #define FS_TYPE_NTFS 3 + #define FS_TYPE_WBFS 4 + + typedef struct + { + int fs_type; + int wbfs_i; // seq wbfs part index + int fat_i; // seq fat part index + } PartInfo; + + typedef struct + { + int num; + u32 sector_size; + partitionEntry pentry[MAX_PARTITIONS_EX]; + int wbfs_n; + int fat_n; + PartInfo pinfo[MAX_PARTITIONS_EX]; + } PartList; /* Prototypes */ s32 Partition_GetEntries(partitionEntry *, u32 *); + s32 Partition_GetEntriesEx(partitionEntry *, u32 *, int *); + s32 Partition_GetList(PartList *plist); #ifdef __cplusplus } diff --git a/source/usbloader/splits.c b/source/usbloader/splits.c new file mode 100644 index 00000000..f60ce513 --- /dev/null +++ b/source/usbloader/splits.c @@ -0,0 +1,313 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "splits.h" + +#define off64_t off_t +#define FMT_llu "%llu" +#define FMT_lld "%lld" + +#define split_error(x) do { /* gprintf("\nsplit error: %s\n\n",x); */ } while(0) + +// 1 sector less than 4gb +//u64 OPT_split_size = (u64)4LL * 1024 * 1024 * 1024 - 512; +// 1 sector less than 2gb +u64 OPT_split_size = (u64)2LL * 1024 * 1024 * 1024 - 512; + +//split_info_t split; + +void split_get_fname(split_info_t *s, int idx, char *fname) +{ + strcpy(fname, s->fname); + if (idx == 0 && s->create_mode) { + strcat(fname, ".tmp"); + } else if (idx > 0) { + char *c = fname + strlen(fname) - 1; + *c = '0' + idx; + } +} + +int split_open_file(split_info_t *s, int idx) +{ + int fd = s->fd[idx]; + if (fd>=0) return fd; + char fname[1024]; + split_get_fname(s, idx, fname); + //char *mode = s->create_mode ? "wb+" : "rb+"; + int mode = s->create_mode ? (O_CREAT | O_RDWR) : O_RDWR ; + //printf("SPLIT OPEN %s %s %d\n", fname, mode, idx); //Wpad_WaitButtons(); + //f = fopen(fname, mode); + fd = open(fname, mode); + if (fd<0) return -1; + if (idx > 0 && s->create_mode) { + printf("%s Split: %d %s \n", + s->create_mode ? "Create" : "Read", + idx, fname); + } + s->fd[idx] = fd; + return fd; +} + +// faster as it uses larger chunks than ftruncate internally +int write_zero(int fd, off_t size) +{ + int buf[0x4000]; //64kb + int chunk; + int ret; + memset(buf, 0, sizeof(buf)); + while (size) { + chunk = size; + if (chunk > sizeof(buf)) chunk = sizeof(buf); + ret = write(fd, buf, chunk); + //printf("WZ %d %d / %lld \n", ret, chunk, size); + size -= chunk; + if (ret < 0) return ret; + } + return 0; +} + +int split_fill(split_info_t *s, int idx, u64 size) +{ + int fd = split_open_file(s, idx); + off64_t fsize = lseek(fd, 0, SEEK_END); + if (fsize < size) { + //printf("TRUNC %d "FMT_lld"\n", idx, size); Wpad_WaitButtons(); + //ftruncate(fd, size); + write_zero(fd, size - fsize); + return 1; + } + return 0; +} + +int split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill) +{ + int fd; + if (lba >= s->total_sec) { + fprintf(stderr, "SPLIT: invalid sector %u / %u\n", lba, (u32)s->total_sec); + return -1; + } + int idx; + idx = lba / s->split_sec; + if (idx >= s->max_split) { + fprintf(stderr, "SPLIT: invalid split %d / %d\n", idx, s->max_split - 1); + return -1; + } + fd = s->fd[idx]; + if (fd<0) { + // opening new, make sure all previous are full + int i; + for (i=0; isplit_size)) { + printf("FILL %d\n", i); + } + } + fd = split_open_file(s, idx); + } + if (fd<0) { + fprintf(stderr, "SPLIT %d: no file\n", idx); + return -1; + } + u32 sec = lba % s->split_sec; // inside file + off64_t off = (off64_t)sec * 512; + // num sectors till end of file + u32 to_end = s->split_sec - sec; + if (*sec_count > to_end) *sec_count = to_end; + if (s->create_mode) { + if (fill) { + // extend, so that read will be succesfull + split_fill(s, idx, off + 512 * (*sec_count)); + } else { + // fill up so that write continues from end of file + // shouldn't be necessary, but libfat looks buggy + // and this is faster + split_fill(s, idx, off); + } + } + lseek(fd, off, SEEK_SET); + return fd; +} + +int split_read_sector(void *_fp,u32 lba,u32 count,void*buf) +{ + split_info_t *s = _fp; + int fd; + u64 off = lba; + off *= 512ULL; + int i; + u32 chunk; + size_t ret; + //fprintf(stderr,"READ %d %d\n", lba, count); + for (i=0; i<(int)count; i+=chunk) { + chunk = count - i; + fd = split_get_file(s, lba+i, &chunk, 1); + if (fd<0) { + fprintf(stderr,"\n\n"FMT_lld" %d %p\n",off,count,_fp); + split_error("error seeking in disc partition"); + return 1; + } + //ret = fread(buf+i*512, 512ULL, chunk, f); + ret = read(fd, buf+i*512, chunk * 512); + if (ret != chunk * 512) { + fprintf(stderr, "error reading %u %u [%u] %u = %u\n", + lba, count, i, chunk, ret); + split_error("error reading disc"); + return 1; + } + } + return 0; +} + +int split_write_sector(void *_fp,u32 lba,u32 count,void*buf) +{ + split_info_t *s = _fp; + int fd; + u64 off = lba; + off*=512ULL; + int i; + u32 chunk; + size_t ret; + //printf("WRITE %d %d %p \n", lba, count, buf); + for (i=0; i<(int)count; i+=chunk) { + chunk = count - i; + fd = split_get_file(s, lba+i, &chunk, 0); + //if (chunk != count) + // fprintf(stderr, "WRITE CHUNK %d %d/%d\n", lba+i, chunk, count); + if (fd<0 || !chunk) { + fprintf(stderr,"\n\n"FMT_lld" %d %p\n",off,count,_fp); + split_error("error seeking in disc partition"); + return 1; + } + //if (fwrite(buf+i*512, 512ULL, chunk, f) != chunk) { + //printf("write %d %p %d \n", fd, buf+i*512, chunk * 512); + ret = write(fd, buf+i*512, chunk * 512); + //printf("write ret = %d \n", ret); + if (ret != chunk * 512) { + split_error("error writing disc"); + return 1; + } + } + return 0; +} + +void split_init(split_info_t *s, char *fname) +{ + int i; + char *p; + //fprintf(stderr, "SPLIT_INIT %s\n", fname); + memset(s, 0, sizeof(*s)); + for (i=0; ifd[i] = -1; + } + strcpy(s->fname, fname); + s->max_split = 1; + p = strrchr(fname, '.'); + if (p && (strcasecmp(p, ".wbfs") == 0)) { + s->max_split = MAX_SPLIT; + } +} + +void split_set_size(split_info_t *s, u64 split_size, u64 total_size) +{ + s->total_size = total_size; + s->split_size = split_size; + s->total_sec = total_size / 512; + s->split_sec = split_size / 512; +} + +void split_close(split_info_t *s) +{ + int i; + char fname[1024]; + char tmpname[1024]; + for (i=0; imax_split; i++) { + if (s->fd[i] >= 0) { + close(s->fd[i]); + } + } + if (s->create_mode) { + split_get_fname(s, -1, fname); + split_get_fname(s, 0, tmpname); + rename(tmpname, fname); + } + memset(s, 0, sizeof(*s)); +} + +int split_create(split_info_t *s, char *fname, + u64 split_size, u64 total_size, bool overwrite) +{ + int i; + int fd; + char sname[1024]; + int error = 0; + split_init(s, fname); + s->create_mode = 1; + // check if any file already exists + for (i=-1; imax_split; i++) { + split_get_fname(s, i, sname); + if (overwrite) { + remove(sname); + } else { + fd = open(sname, O_RDONLY); + if (fd >= 0) { + fprintf(stderr, "Error: file already exists: %s\n", sname); + close(fd); + error = 1; + } + } + } + if (error) { + split_init(s, ""); + return -1; + } + split_set_size(s, split_size, total_size); + return 0; +} + +int split_open(split_info_t *s, char *fname) +{ + int i; + u64 size = 0; + u64 total_size = 0; + u64 split_size = 0; + int fd; + split_init(s, fname); + for (i=0; imax_split; i++) { + fd = split_open_file(s, i); + if (fd<0) { + if (i==0) goto err; + break; + } + // check previous size - all splits except last must be same size + if (i > 0 && size != split_size) { + fprintf(stderr, "split %d: invalid size "FMT_lld"", i, size); + goto err; + } + // get size + //fseeko(f, 0, SEEK_END); + //size = ftello(f); + size = lseek(fd, 0, SEEK_END); + // check sector alignment + if (size % 512) { + fprintf(stderr, "split %d: size ("FMT_lld") not sector (512) aligned!", + i, size); + } + // first sets split size + if (i==0) { + split_size = size; + } + total_size += size; + } + split_set_size(s, split_size, total_size); + return 0; +err: + split_close(s); + return -1; +} + diff --git a/source/usbloader/splits.h b/source/usbloader/splits.h new file mode 100644 index 00000000..fe9da4a8 --- /dev/null +++ b/source/usbloader/splits.h @@ -0,0 +1,35 @@ + +#define MAX_SPLIT 10 + +typedef struct split_info +{ + char fname[1024]; + //FILE *f[MAX_SPLIT]; + int fd[MAX_SPLIT]; + //u64 fsize[MAX_SPLIT]; + u32 split_sec; + u32 total_sec; + u64 split_size; + u64 total_size; + int create_mode; + int max_split; +} split_info_t; + +// 1 sector less than 4gb +extern u64 OPT_split_size; + +void split_get_fname(split_info_t *s, int idx, char *fname); +//FILE *split_open_file(split_info_t *s, int idx); +//FILE *split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill); +int split_open_file(split_info_t *s, int idx); +int split_get_file(split_info_t *s, u32 lba, u32 *sec_count, int fill); +int split_fill(split_info_t *s, int idx, u64 size); +int split_read_sector(void *_fp,u32 lba,u32 count,void*buf); +int split_write_sector(void *_fp,u32 lba,u32 count,void*buf); +void split_init(split_info_t *s, char *fname); +void split_set_size(split_info_t *s, u64 split_size, u64 total_size); +void split_close(split_info_t *s); +int split_open(split_info_t *s, char *fname); +int split_create(split_info_t *s, char *fname, + u64 split_size, u64 total_size, bool overwrite); + diff --git a/source/usbloader/utils.h b/source/usbloader/utils.h index 3a4862bf..1ca05bf7 100644 --- a/source/usbloader/utils.h +++ b/source/usbloader/utils.h @@ -1,6 +1,10 @@ #ifndef _UTILS_H_ #define _UTILS_H_ +#ifdef __cplusplus +extern "C" { +#endif + /* Constants */ #define KB_SIZE 1024.0 #define MB_SIZE 1048576.0 @@ -12,4 +16,8 @@ /* Prototypes */ u32 swap32(u32); +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/usbloader/wbfs.c b/source/usbloader/wbfs.c index 84cee22b..f1938ac5 100644 --- a/source/usbloader/wbfs.c +++ b/source/usbloader/wbfs.c @@ -10,14 +10,25 @@ #include "video.h" #include "wdvd.h" #include "wbfs.h" +#include "wbfs_fat.h" +#include "fatmounter.h" +#include "partition.h" #include "libwbfs/libwbfs.h" /* Constants */ #define MAX_NB_SECTORS 32 +/* WBFS device */ +s32 wbfsDev = WBFS_MIN_DEVICE; + +// partition +int wbfs_part_fat = 0; +u32 wbfs_part_idx = 0; +u32 wbfs_part_lba = 0; + /* WBFS HDD */ -static wbfs_t *hdd = NULL; +wbfs_t *hdd = NULL; /* WBFS callbacks */ static rw_sector_callback_t readCallback = NULL; @@ -26,11 +37,39 @@ static s32 done = -1, total = -1; /* Variables */ static u32 nb_sectors, sector_size; -static void WBFS_Spinner(s32 x, s32 max) { + +void WBFS_Spinner(s32 x, s32 max) { done = x; total = max; } +wbfs_disc_t* WBFS_OpenDisc(u8 *discid) +{ + if (wbfs_part_fat) return WBFS_FAT_OpenDisc(discid); + + /* No device open */ + if (!hdd) + return NULL; + + /* Open disc */ + return wbfs_open_disc(hdd, discid); +} + +void WBFS_CloseDisc(wbfs_disc_t *disc) +{ + if (wbfs_part_fat) { + WBFS_FAT_CloseDisc(disc); + return; + } + + /* No device open */ + if (!hdd || !disc) + return; + + /* Close disc */ + wbfs_close_disc(disc); +} + void GetProgressValue(s32 * d, s32 * m) { *d = done; *m = total; @@ -226,82 +265,6 @@ s32 WBFS_Init(u32 device) { return 0; } -//s32 WBFS_Init(void) -//{ -// s32 ret; -// -// /* Initialize USB storage */ -// ret = USBStorage_Init(); -// if (ret < 0) -// return ret; -// -// /* Get USB capacity */ -// nb_sectors = USBStorage_GetCapacity(§or_size); -// if (!nb_sectors) -// return -1; -// -// return 0; -//} - -/* -s32 WBFS_Init(u32 device, u32 timeout) -{ - u32 cnt; - s32 ret; - - // Wrong timeout - if (!timeout) - return -1; - - // Try to mount device - for (cnt = 0; cnt < timeout; cnt++) { - switch (device) { - case WBFS_DEVICE_USB: { - // Initialize USB storage - ret = USBStorage_Init(); - - if (ret >= 0) { - // Setup callbacks - readCallback = __WBFS_ReadUSB; - writeCallback = __WBFS_WriteUSB; - - // Device info - nb_sectors = USBStorage_GetCapacity(§or_size); - - goto out; - } - } - - case WBFS_DEVICE_SDHC: { - // Initialize SDHC - ret = SDHC_Init(); - - if (ret) { - // Setup callbacks - readCallback = __WBFS_ReadSDHC; - writeCallback = __WBFS_WriteSDHC; - - // Device info - nb_sectors = 0; - sector_size = SDHC_SECTOR_SIZE; - - goto out; - } else - ret = -1; - } - - default: - return -1; - } - - // Sleep 1 second - sleep(1); - } - -out: - return ret; -} -*/ s32 WBFS_Open(void) { /* Close hard disk */ @@ -309,6 +272,7 @@ s32 WBFS_Open(void) { wbfs_close(hdd); /* Open hard disk */ + wbfs_part_fat = wbfs_part_idx = wbfs_part_lba = 0; hdd = wbfs_open_hd(readCallback, writeCallback, NULL, sector_size, nb_sectors, 0); if (!hdd) return -1; @@ -316,19 +280,134 @@ s32 WBFS_Open(void) { // Save the new sector size, so it will be used in read and write calls sector_size = 1 << hdd->head->hd_sec_sz_s; + wbfs_part_idx = 1; return 0; } -s32 WBFS_Close(void) +s32 WBFS_OpenPart(u32 part_fat, u32 part_idx, u32 part_lba, u32 part_size, char *partition) +{ + // close + WBFS_Close(); + if (part_fat) { + if (wbfsDev != WBFS_DEVICE_USB) return -1; + if (part_lba == fat_usb_sec) { + strcpy(wbfs_fat_drive, "USB:"); + } else { + if (WBFSDevice_Init(part_lba)) return -1; + strcpy(wbfs_fat_drive, "WBFS:"); + } + } else { + if (WBFS_OpenLBA(part_lba, part_size)) return -3; + } + + // success + wbfs_part_fat = part_fat; + wbfs_part_idx = part_idx; + wbfs_part_lba = part_lba; + + sprintf(partition, "%s%d", wbfs_part_fat ? "FAT" : "WBFS", wbfs_part_idx); + return 0; +} + +s32 WBFS_OpenNamed(char *partition) +{ + int i; + u32 part_idx = 0; + u32 part_fat = 0; + u32 part_lba = 0; + s32 ret = 0; + PartList plist; + + // close + WBFS_Close(); + + // parse partition option + if (strncasecmp(partition, "WBFS", 4) == 0) { + i = atoi(partition+4); + if (i < 1 || i > 4) goto err; + part_idx = i; + } else if (strncasecmp(partition, "FAT", 3) == 0) { + if (wbfsDev != WBFS_DEVICE_USB) goto err; + i = atoi(partition+3); + if (i < 1 || i > 9) goto err; + part_idx = i; + part_fat = 1; + } else { + goto err; + } + + // Get partition entries + ret = Partition_GetList(&plist); + if (ret || plist.num == 0) return -1; + + if (part_fat) { + if (part_idx > plist.fat_n) goto err; + for (i=0; i plist.wbfs_n) goto err; + for (i=0; i= plist.num) goto err; + // set partition lba sector + part_lba = plist.pentry[i].sector; + + if (WBFS_OpenPart(part_fat, part_idx, part_lba, plist.pentry[i].size, partition)) { + goto err; + } + // success + return 0; +err: + return -1; +} + +s32 WBFS_OpenLBA(u32 lba, u32 size) +{ + wbfs_t *part = NULL; + + /* Open partition */ + part = wbfs_open_partition(readCallback, writeCallback, NULL, sector_size, size, lba, 0); + if (!part) return -1; + + /* Close current hard disk */ + if (hdd) wbfs_close(hdd); + hdd = part; + + return 0; +} + +bool WBFS_Close(void) { /* Close hard disk */ - if (hdd) + if (hdd) { wbfs_close(hdd); + hdd = NULL; + } + + WBFSDevice_deInit(); + wbfs_part_fat = 0; + wbfs_part_idx = 0; + wbfs_part_lba = 0; + wbfs_fat_drive[0] = '\0'; return 0; } +bool WBFS_Mounted() +{ + return (hdd != NULL); +} + +bool WBFS_Selected() +{ + if (wbfs_part_fat && wbfs_part_lba && *wbfs_fat_drive) return true; + return WBFS_Mounted(); +} + s32 WBFS_Format(u32 lba, u32 size) { wbfs_t *partition = NULL; @@ -344,6 +423,8 @@ s32 WBFS_Format(u32 lba, u32 size) { } s32 WBFS_GetCount(u32 *count) { + if (wbfs_part_fat) return WBFS_FAT_GetCount(count); + /* No device open */ if (!hdd) return -1; @@ -355,6 +436,8 @@ s32 WBFS_GetCount(u32 *count) { } s32 WBFS_GetHeaders(void *outbuf, u32 cnt, u32 len) { + if (wbfs_part_fat) return WBFS_FAT_GetHeaders(outbuf, cnt, len); + u32 idx, size; s32 ret; @@ -378,10 +461,10 @@ s32 WBFS_CheckGame(u8 *discid) { wbfs_disc_t *disc = NULL; /* Try to open game disc */ - disc = wbfs_open_disc(hdd, discid); + disc = WBFS_OpenDisc(discid); if (disc) { /* Close disc */ - wbfs_close_disc(disc); + WBFS_CloseDisc(disc); return 1; } @@ -390,6 +473,8 @@ s32 WBFS_CheckGame(u8 *discid) { } s32 WBFS_AddGame(void) { + if (wbfs_part_fat) return WBFS_FAT_AddGame(); + s32 ret; /* No device open */ @@ -405,6 +490,8 @@ s32 WBFS_AddGame(void) { } s32 WBFS_RemoveGame(u8 *discid) { + if (wbfs_part_fat) return WBFS_FAT_RemoveGame(discid); + s32 ret; /* No device open */ @@ -424,28 +511,26 @@ s32 WBFS_GameSize(u8 *discid, f32 *size) { u32 sectors; - /* No device open */ - if (!hdd) - return -1; - /* Open disc */ - disc = wbfs_open_disc(hdd, discid); + disc = WBFS_OpenDisc(discid); if (!disc) return -2; /* Get game size in sectors */ - sectors = wbfs_sector_used(hdd, disc->header); - - /* Close disc */ - wbfs_close_disc(disc); + sectors = wbfs_sector_used(disc->p, disc->header); /* Copy value */ - *size = (hdd->wbfs_sec_sz / GB_SIZE) * sectors; + *size = (disc->p->wbfs_sec_sz / GB_SIZE) * sectors; + + /* Close disc */ + WBFS_CloseDisc(disc); return 0; } s32 WBFS_DiskSpace(f32 *used, f32 *free) { + if (wbfs_part_fat) return WBFS_FAT_DiskSpace(used, free); + f32 ssize; u32 cnt; @@ -467,6 +552,8 @@ s32 WBFS_DiskSpace(f32 *used, f32 *free) { } s32 WBFS_RenameGame(u8 *discid, const void *newname) { + if (wbfs_part_fat) return -1; + s32 ret; /* No USB device open */ @@ -480,6 +567,8 @@ s32 WBFS_RenameGame(u8 *discid, const void *newname) { } s32 WBFS_ReIDGame(u8 *discid, const void *newID) { + if (wbfs_part_fat) return -1; + s32 ret; /* No USB device open */ @@ -493,7 +582,11 @@ s32 WBFS_ReIDGame(u8 *discid, const void *newID) { } f32 WBFS_EstimeGameSize(void) { + if (wbfs_part_fat) { + u64 comp; + WBFS_FAT_DVD_Size(&comp, NULL); + return comp; + } return wbfs_estimate_disc(hdd, __WBFS_ReadDVD, NULL, ONLY_GAME_PARTITION); - } diff --git a/source/usbloader/wbfs.h b/source/usbloader/wbfs.h index 5d19818d..eaa55dda 100644 --- a/source/usbloader/wbfs.h +++ b/source/usbloader/wbfs.h @@ -13,14 +13,19 @@ extern "C" { }; /* Macros */ -#define WBFS_MIN_DEVICE 1 -#define WBFS_MAX_DEVICE 2 + #define WBFS_MIN_DEVICE 1 + #define WBFS_MAX_DEVICE 2 + + extern s32 wbfsDev; + extern int wbfs_part_fat; + extern u32 wbfs_part_idx; + extern u32 wbfs_part_lba; + extern char wbfs_fat_drive[16]; /* Prototypes */ void GetProgressValue(s32 * d, s32 * m); s32 WBFS_Init(u32); s32 WBFS_Open(void); - s32 WBFS_Close(void); s32 WBFS_Format(u32, u32); s32 WBFS_GetCount(u32 *); s32 WBFS_GetHeaders(void *, u32, u32); @@ -38,6 +43,15 @@ extern "C" { s32 __WBFS_ReadUSB(void *fp, u32 lba, u32 count, void *iobuf); s32 __WBFS_WriteUSB(void *fp, u32 lba, u32 count, void *iobuf); + s32 WBFS_OpenPart(u32 part_fat, u32 part_idx, u32 part_lba, u32 part_size, char *partition); + s32 WBFS_OpenNamed(char *partition); + s32 WBFS_OpenLBA(u32 lba, u32 size); + wbfs_disc_t* WBFS_OpenDisc(u8 *discid); + void WBFS_CloseDisc(wbfs_disc_t *disc); + bool WBFS_Close(); + bool WBFS_Mounted(); + bool WBFS_Selected(); + #ifdef __cplusplus } diff --git a/source/usbloader/wbfs_fat.c b/source/usbloader/wbfs_fat.c new file mode 100644 index 00000000..c1475d3a --- /dev/null +++ b/source/usbloader/wbfs_fat.c @@ -0,0 +1,339 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "libwbfs/libwbfs.h" +#include "sdhc.h" +#include "usbstorage.h" +#include "utils.h" +#include "video.h" +#include "wbfs.h" +#include "wdvd.h" +#include "splits.h" +#include "fat.h" +#include "partition.h" +#include "wpad.h" +#include "wbfs_fat.h" +#include "disc.h" +#include "settings/cfg.h" + +// WBFS FAT by oggzee + +#define D_S(A) A, sizeof(A) + +char wbfs_fat_drive[16]; +char wbfs_fat_dir[16] = "/wbfs"; + +int wbfs_fat_vfs_have = 0; +int wbfs_fat_vfs_lba = 0; +struct statvfs wbfs_fat_vfs; + +split_info_t split; + +static u32 fat_sector_size = 512; + +void WBFS_Spinner(s32 x, s32 max); +s32 __WBFS_ReadDVD(void *fp, u32 lba, u32 len, void *iobuf); + +s32 _WBFS_FAT_GetHeadersCount(void *outbuf, u32 *count, u32 len) +{ + DIR *dir; + struct dirent *dent; + char *p; + int ret, cnt = 0; + char path[100]; + wbfs_t *part = NULL; + u32 size; + u8 *ptr; + struct discHdr tmpHdr; + int hdrsize; + struct stat st; + //dbg_time1(); + + strcpy(path, wbfs_fat_drive); + strcat(path, wbfs_fat_dir); + dir = opendir(path); + if (!dir) { + *count = 0; + return 0; + } + while ((dent = readdir(dir)) != NULL) { + if (outbuf && cnt >= *count) break; + if ((char)dent->d_name[0] == '.') continue; + p = strrchr(dent->d_name, '.'); + if (!p) continue; + if (strcasecmp(p, ".wbfs") != 0) continue; + if (strlen(dent->d_name) != 11) continue; // GAMEID.wbfs + u8 id[8]; + memcpy(id, dent->d_name, 6); + id[6] = 0; + + strcpy(path, wbfs_fat_drive); + strcat(path, wbfs_fat_dir); + strcat(path, "/"); + strcat(path, dent->d_name); + stat(path, &st); + // size must be at least 1MB to be considered a valid wbfs file + if (st.st_size < 1024*1024) continue; + if (!outbuf) { + // just counting + cnt++; + continue; + } + ptr = ((u8 *)outbuf) + (cnt * len); + hdrsize = len; + + char *title = cfg_get_title(id); + if (title) { + memset(&tmpHdr, 0, sizeof(tmpHdr)); + memcpy(tmpHdr.id, id, 6); + strncpy(tmpHdr.title, title, sizeof(tmpHdr.title)); + tmpHdr.magic = 0x5D1C9EA3; + memcpy(ptr, &tmpHdr, hdrsize); + cnt++; + continue; + } + + // no title found, read it from wbfs file directly + FILE *fp = fopen(path, "rb"); + if (fp != NULL) { + fseek(fp, 512, SEEK_SET); + fread(&tmpHdr, sizeof(struct discHdr), 1, fp); + fclose(fp); + + if (tmpHdr.magic == 0x5D1C9EA3 && (memcmp(tmpHdr.id, id, 6) == 0)) { + memcpy(ptr, &tmpHdr, hdrsize); + cnt++; + continue; + } + } + + // no title found, read it from wbfs file + // but this is a little bit slower + // open 'partition' file + part = WBFS_FAT_OpenPart(id); + if (!part) { + continue; + } + + /* Get header */ + ret = wbfs_get_disc_info(part, 0, ptr, hdrsize, &size); + if (ret == 0) cnt++; + WBFS_FAT_ClosePart(part); + } + *count = cnt; + closedir(dir); + //dbg_time2("\nFAT HDRS"); + //Wpad_WaitButtons(); + return 0; +} + + +s32 WBFS_FAT_GetCount(u32 *count) +{ + *count = 0; + _WBFS_FAT_GetHeadersCount(NULL, count, 0); + return 0; +} + +s32 WBFS_FAT_GetHeaders(void *outbuf, u32 cnt, u32 len) +{ + _WBFS_FAT_GetHeadersCount(outbuf, &cnt, len); + return 0; +} + +wbfs_disc_t* WBFS_FAT_OpenDisc(u8 *discid) +{ + wbfs_t *part = WBFS_FAT_OpenPart(discid); + if (!part) return NULL; + return wbfs_open_disc(part, discid); +} + +void WBFS_FAT_CloseDisc(wbfs_disc_t* disc) +{ + if (!disc) return; + wbfs_t *part = disc->p; + wbfs_close_disc(disc); + WBFS_FAT_ClosePart(part); + return; +} + +s32 WBFS_FAT_DiskSpace(f32 *used, f32 *free) +{ + f32 size; + int ret; + + *used = 0; + *free = 0; + // statvfs is slow, so cache values + if (!wbfs_fat_vfs_have || wbfs_fat_vfs_lba != wbfs_part_lba) { + ret = statvfs(wbfs_fat_drive, &wbfs_fat_vfs); + + if (ret) return 0; + wbfs_fat_vfs_have = 1; + wbfs_fat_vfs_lba = wbfs_part_lba; + } + + /* FS size in GB */ + size = (f32)wbfs_fat_vfs.f_frsize * (f32)wbfs_fat_vfs.f_blocks / GB_SIZE; + *free = (f32)wbfs_fat_vfs.f_frsize * (f32)wbfs_fat_vfs.f_bfree / GB_SIZE; + *used = size - *free; + + + return 0; +} + +static int nop_read_sector(void *_fp,u32 lba,u32 count,void*buf) +{ + return 0; +} + +static int nop_write_sector(void *_fp,u32 lba,u32 count,void*buf) +{ + return 0; +} + +void WBFS_FAT_fname(u8 *id, char *fname, int len) +{ + snprintf(fname, len, "%s%s/%.6s.wbfs", wbfs_fat_drive, wbfs_fat_dir, id); +} + +wbfs_t* WBFS_FAT_OpenPart(u8 *id) +{ + char fname[100]; + wbfs_t *part = NULL; + int ret; + + // wbfs 'partition' file + WBFS_FAT_fname(id, fname, sizeof(fname)); + ret = split_open(&split, fname); + if (ret) return NULL; + part = wbfs_open_partition( + split_read_sector, + nop_write_sector, //readonly //split_write_sector, + &split, fat_sector_size, split.total_sec, 0, 0); + if (!part) { + split_close(&split); + } + return part; +} + +wbfs_t* WBFS_FAT_CreatePart(u8 *id) +{ + char fname[100]; + wbfs_t *part = NULL; + u64 size = (u64)143432*2*0x8000ULL; + u32 n_sector = size / 512; + int ret; + + snprintf(D_S(fname), "%s%s", wbfs_fat_drive, wbfs_fat_dir); + mkdir(fname, 0777); + WBFS_FAT_fname(id, fname, sizeof(fname)); + ret = split_create(&split, fname, OPT_split_size, size, true); + if (ret) return NULL; + + // force create first file + u32 scnt = 0; + int fd = split_get_file(&split, 0, &scnt, 0); + if (fd<0) { + split_close(&split); + return NULL; + } + + part = wbfs_open_partition( + split_read_sector, + split_write_sector, + &split, fat_sector_size, n_sector, 0, 1); + if (!part) { + split_close(&split); + } + return part; +} + +void WBFS_FAT_ClosePart(wbfs_t* part) +{ + if (!part) return; + split_info_t *s = (split_info_t*)part->callback_data; + wbfs_close(part); + if (s) split_close(s); +} + +s32 WBFS_FAT_RemoveGame(u8 *discid) +{ + char fname[100]; + // wbfs 'partition' file + WBFS_FAT_fname(discid, fname, sizeof(fname)); + split_create(&split, fname, 0, 0, true); + split_close(&split); + + // Reset FAT stats + wbfs_fat_vfs_have = 0; + return 0; +} + +s32 WBFS_FAT_AddGame(void) +{ + static struct discHdr header ATTRIBUTE_ALIGN(32); + s32 ret; + wbfs_t *part = NULL; + + //write_test(); return -1; + + // read ID from DVD + Disc_ReadHeader(&header); + // create wbfs 'partition' file + part = WBFS_FAT_CreatePart(header.id); + if (!part) return -1; + /* Add game to device */ + extern wbfs_t *hdd; + wbfs_t *old_hdd = hdd; + hdd = part; // used by spinner + ret = wbfs_add_disc(part, __WBFS_ReadDVD, NULL, WBFS_Spinner, ONLY_GAME_PARTITION, 0); + hdd = old_hdd; + wbfs_trim(part); + WBFS_FAT_ClosePart(part); + + // Reset FAT stats + wbfs_fat_vfs_have = 0; + if (ret < 0) return ret; + + return 0; +} + +s32 WBFS_FAT_DVD_Size(u64 *comp_size, u64 *real_size) +{ + s32 ret; + u32 comp_sec = 0, last_sec = 0; + + wbfs_t *part = NULL; + u64 size = (u64)143432*2*0x8000ULL; + u32 n_sector = size / fat_sector_size; + u32 wii_sec_sz; + + // init a temporary dummy part + // as a placeholder for wbfs_size_disc + part = wbfs_open_partition( + nop_read_sector, nop_write_sector, + NULL, fat_sector_size, n_sector, 0, 1); + if (!part) return -1; + wii_sec_sz = part->wii_sec_sz; + + /* Add game to device */ + ret = wbfs_size_disc(part, __WBFS_ReadDVD, NULL, ONLY_GAME_PARTITION, &comp_sec, &last_sec); + wbfs_close(part); + if (ret < 0) + return ret; + + if (comp_size != NULL) *comp_size = (u64)wii_sec_sz * comp_sec; + if (real_size != NULL) *real_size = (u64)wii_sec_sz * last_sec; + + return 0; +} + diff --git a/source/usbloader/wbfs_fat.h b/source/usbloader/wbfs_fat.h new file mode 100644 index 00000000..aa4ba415 --- /dev/null +++ b/source/usbloader/wbfs_fat.h @@ -0,0 +1,15 @@ +#ifndef _WBFS_FAT_H +#define _WBFS_FAT_H + +wbfs_t* WBFS_FAT_OpenPart(u8 *id); +void WBFS_FAT_ClosePart(wbfs_t* part); +s32 WBFS_FAT_GetCount(u32 *count); +s32 WBFS_FAT_GetHeaders(void *outbuf, u32 cnt, u32 len); +wbfs_disc_t* WBFS_FAT_OpenDisc(u8 *discid); +void WBFS_FAT_CloseDisc(wbfs_disc_t* disc); +s32 WBFS_FAT_DiskSpace(f32 *used, f32 *free); +s32 WBFS_FAT_RemoveGame(u8 *discid); +s32 WBFS_FAT_AddGame(void); +s32 WBFS_FAT_DVD_Size(u64 *comp_size, u64 *real_size); + +#endif diff --git a/source/usbloader/wdvd.c b/source/usbloader/wdvd.c index 870c1cd2..e588b9a1 100644 --- a/source/usbloader/wdvd.c +++ b/source/usbloader/wdvd.c @@ -306,7 +306,7 @@ s32 WDVD_DisableReset(u8 val) { } /** Hermes **/ -s32 WDVD_SetUSBMode(const u8 *id) { +s32 WDVD_SetUSBMode(const u8 *id, s32 partition) { s32 ret; memset(inbuf, 0, sizeof(inbuf)); @@ -315,10 +315,12 @@ s32 WDVD_SetUSBMode(const u8 *id) { inbuf[0] = IOCTL_DI_SETUSBMODE << 24; inbuf[1] = (id) ? 1 : 0; - /* Copy ID */ if (id) { memcpy(&inbuf[2], id, 6); + if (IOS_GetVersion() != 249) { + inbuf[5] = partition; + } } ret = IOS_Ioctl(di_fd, IOCTL_DI_SETUSBMODE, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf)); diff --git a/source/usbloader/wdvd.h b/source/usbloader/wdvd.h index 9b3d017a..83fcf4cb 100644 --- a/source/usbloader/wdvd.h +++ b/source/usbloader/wdvd.h @@ -22,7 +22,7 @@ extern "C" { s32 WDVD_WaitForDisc(void); s32 WDVD_GetCoverStatus(u32 *); s32 WDVD_DisableReset(u8); - s32 WDVD_SetUSBMode(const u8 *); + s32 WDVD_SetUSBMode(const u8 *, s32 partition); #ifdef __cplusplus } diff --git a/source/wad/title.h b/source/wad/title.h index b207f3c1..acde9a2c 100644 --- a/source/wad/title.h +++ b/source/wad/title.h @@ -8,8 +8,8 @@ Copyright (C) 2008 tona and/or waninkoko #include #include #include -#include #include +#include // Turn upper and lower into a full title ID #define TITLE_ID(x,y) (((u64)(x) << 32) | (y))