/**************************************************************************** * Theme_Downloader * USB Loader GX 2009 * * Theme downloader for USB Loader GX * * Theme_Downloader.cpp ***************************************************************************/ #include #include #include "language/gettext.h" #include "libwiigui/gui.h" #include "prompts/PromptWindows.h" #include "prompts/ProgressWindow.h" #include "homebrewboot/HomebrewBrowse.h" #include "network/networkops.h" #include "themes/Theme_List.h" #include "themes/CTheme.h" #include "menu.h" #include "filelist.h" #include "listfiles.h" #include "sys.h" #include "network/http.h" #include "ZipFile.h" #include "gecko.h" /*** Extern functions ***/ extern void ResumeGui(); extern void HaltGui(); /*** Extern variables ***/ extern GuiWindow * mainWindow; extern GuiSound * bgMusic; extern GuiImage * bgImg; extern u8 shutdown; extern u8 reset; int DownloadTheme(const char *url, const char *title) { if (!url) return 0; char filename[255]; memset(filename, 0, sizeof(filename)); int filesize = download_request(url, (char *) &filename); if (filesize <= 0) { WindowPrompt(tr( "Download request failed." ), 0, tr( "OK" )); return 0; } char path[300]; char filepath[300]; snprintf(path, sizeof(path), "%s%s", Settings.theme_downloadpath, title); subfoldercreate(path); snprintf(filepath, sizeof(filepath), "%s/%s", path, filename); FILE *file = fopen(filepath, "wb"); if (!file) { WindowPrompt(tr( "Download failed." ), tr( "Can't create file" ), tr( "OK" )); return 0; } u32 done = 0; int blocksize = 1024 * 5; u8 *buffer = new u8[blocksize]; while (done < (u32) filesize) { if ((u32) blocksize > filesize - done) blocksize = filesize - done; ShowProgress(tr( "Downloading file" ), 0, (char*) filename, done, filesize, true); int ret = network_read(buffer, blocksize); if (ret < 0) { free(buffer); fclose(file); remove(path); ProgressStop(); WindowPrompt(tr( "Download failed." ), tr( "Transfer failed." ), tr( "OK" )); return 0; } else if (ret == 0) break; fwrite(buffer, 1, blocksize, file); done += ret; } delete[] buffer; fclose(file); ProgressStop(); if (done != (u32) filesize) { remove(filepath); WindowPrompt(tr( "Download failed." ), tr( "Connection lost..." ), tr( "OK" )); return 0; } ZipFile zipfile(filepath); int result = zipfile.ExtractAll(path); if (result) { remove(filepath); int choice = WindowPrompt(tr( "Successfully extracted theme." ), tr( "Do you want to apply it now?" ), tr( "Yes" ), tr( "No" )); if (choice) { char real_themepath[1024]; sprintf(real_themepath, "%s", Settings.theme_path); if (SearchFile(path, "GXtheme.cfg", real_themepath) == true) { char *ptr = strrchr(real_themepath, '/'); if (ptr) { ptr++; ptr[0] = '\0'; } snprintf(Settings.theme_path, sizeof(Settings.theme_path), "%s", real_themepath); Settings.Save(); Settings.Load(); result = 2; } else WindowPrompt(tr( "ERROR: Can't set up theme." ), tr( "GXtheme.cfg not found in any subfolder." ), tr( "OK" )); } } else WindowPrompt(tr( "Failed to extract." ), tr( "Unsupported format, try to extract manually." ), tr( "OK" )); return result; } static int Theme_Prompt(const char *title, const char *author, GuiImageData *thumbimageData, const char *downloadlink) { gprintf("\nTheme_Prompt(%s ,%s, , %s)", title, author, downloadlink); bool leave = false; int result = 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); // GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, Settings.sfxvolume); char imgPath[100]; snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", Settings.theme_path); GuiImageData btnOutline(imgPath, button_dialogue_box_png); snprintf(imgPath, sizeof(imgPath), "%stheme_dialogue_box.png", Settings.theme_path); GuiImageData dialogBox(imgPath, theme_dialogue_box_png); GuiImage dialogBoxImg(&dialogBox); GuiWindow promptWindow(dialogBox.GetWidth(), dialogBox.GetHeight()); promptWindow.SetAlignment(ALIGN_CENTRE, ALIGN_MIDDLE); promptWindow.SetPosition(0, -10); GuiTrigger trigA; trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); GuiTrigger trigB; trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); GuiText titleTxt(tr( "Theme Title:" ), 18, Theme.prompttext); titleTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP); titleTxt.SetPosition(230, 30); GuiText titleTxt2(title, 18, Theme.prompttext); titleTxt2.SetAlignment(ALIGN_LEFT, ALIGN_TOP); titleTxt2.SetPosition(230, 50); titleTxt2.SetMaxWidth(dialogBox.GetWidth() - 220, WRAP); GuiText authorTxt(tr( "Author:" ), 18, Theme.prompttext); authorTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP); authorTxt.SetPosition(230, 100); GuiText authorTxt2(author, 18, Theme.prompttext); authorTxt2.SetAlignment(ALIGN_LEFT, ALIGN_TOP); authorTxt2.SetPosition(230, 120); authorTxt2.SetMaxWidth(dialogBox.GetWidth() - 220, DOTTED); GuiText downloadBtnTxt(tr( "Download" ), 22, Theme.prompttext); downloadBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30); GuiImage downloadBtnImg(&btnOutline); if (Settings.wsprompt == yes) { downloadBtnTxt.SetWidescreen(Settings.widescreen); downloadBtnImg.SetWidescreen(Settings.widescreen); } GuiButton downloadBtn(&downloadBtnImg, &downloadBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 170, &trigA, &btnSoundOver, btnClick2, 1); downloadBtn.SetLabel(&downloadBtnTxt); downloadBtn.SetScale(0.9); GuiText backBtnTxt(tr( "Back" ), 22, Theme.prompttext); backBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30); GuiImage backBtnImg(&btnOutline); if (Settings.wsprompt == yes) { backBtnTxt.SetWidescreen(Settings.widescreen); backBtnImg.SetWidescreen(Settings.widescreen); } GuiButton backBtn(&backBtnImg, &backBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 220, &trigA, &btnSoundOver, btnClick2, 1); backBtn.SetLabel(&backBtnTxt); backBtn.SetTrigger(&trigB); backBtn.SetScale(0.9); GuiImage ThemeImage(thumbimageData); ThemeImage.SetAlignment(ALIGN_LEFT, ALIGN_TOP); ThemeImage.SetPosition(20, 10); ThemeImage.SetScale(0.8); ThemeImage.SetScale(0.8); promptWindow.Append(&dialogBoxImg); promptWindow.Append(&ThemeImage); promptWindow.Append(&titleTxt); promptWindow.Append(&titleTxt2); promptWindow.Append(&authorTxt); promptWindow.Append(&authorTxt2); promptWindow.Append(&downloadBtn); promptWindow.Append(&backBtn); HaltGui(); promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_IN, 50); mainWindow->SetState(STATE_DISABLED); mainWindow->Append(&promptWindow); mainWindow->ChangeFocus(&promptWindow); ResumeGui(); while (!leave) { VIDEO_WaitVSync(); if (shutdown == 1) Sys_Shutdown(); else if (reset == 1) Sys_Reboot(); if (downloadBtn.GetState() == STATE_CLICKED) { int choice = WindowPrompt(tr( "Do you want to download this theme?" ), title, tr( "Yes" ), tr( "Cancel" )); if (choice) { result = DownloadTheme(downloadlink, title); if (result == 2) leave = true; } mainWindow->SetState(STATE_DISABLED); promptWindow.SetState(STATE_DEFAULT); mainWindow->ChangeFocus(&promptWindow); downloadBtn.ResetState(); } else if (backBtn.GetState() == STATE_CLICKED) { leave = true; backBtn.ResetState(); } } promptWindow.SetEffect(EFFECT_SLIDE_TOP | EFFECT_SLIDE_OUT, 50); while (promptWindow.GetEffect() > 0) usleep(50); HaltGui(); mainWindow->Remove(&promptWindow); mainWindow->SetState(STATE_DEFAULT); ResumeGui(); return result; } int Theme_Downloader() { int pagesize = 4; int menu = MENU_NONE; bool listchanged = false; char THEME_LINK[70]; sprintf(THEME_LINK, "http://wii.spiffy360.com/themes.php?xml=1&category=1&adult=%d", Settings.godmode); //gprintf("\nTHEME_LINK: %s", THEME_LINK); //const char THEME_LINK_ADULT[70] = "http://wii.spiffy360.com/themes.php?xml=1&category=1&adult=1"; /*** Sound Variables ***/ 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); GuiSound btnClick1(button_click_pcm, button_click_pcm_size, Settings.sfxvolume); /*** Image Variables ***/ char imgPath[150]; snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", Settings.theme_path); GuiImageData btnOutline(imgPath, button_dialogue_box_png); snprintf(imgPath, sizeof(imgPath), "%stheme_box.png", Settings.theme_path); GuiImageData theme_box_Data(imgPath, theme_box_png); snprintf(imgPath, sizeof(imgPath), "%ssettings_background.png", Settings.theme_path); GuiImageData bgData(imgPath, settings_background_png); snprintf(imgPath, sizeof(imgPath), "%sstartgame_arrow_left.png", Settings.theme_path); GuiImageData arrow_left(imgPath, startgame_arrow_left_png); snprintf(imgPath, sizeof(imgPath), "%sstartgame_arrow_right.png", Settings.theme_path); GuiImageData arrow_right(imgPath, startgame_arrow_right_png); snprintf(imgPath, sizeof(imgPath), "%sWifi_btn.png", Settings.theme_path); GuiImageData wifiImgData(imgPath, Wifi_btn_png); snprintf(imgPath, sizeof(imgPath), "%spageindicator.png", Settings.theme_path); GuiImageData PageindicatorImgData(imgPath, pageindicator_png); GuiImage background(&bgData); /*** Trigger Variables ***/ 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 trigB; trigB.SetButtonOnlyTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); GuiTrigger trigL; trigL.SetButtonOnlyTrigger(-1, WPAD_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_LEFT, PAD_BUTTON_LEFT); GuiTrigger trigR; trigR.SetButtonOnlyTrigger(-1, WPAD_BUTTON_RIGHT | WPAD_CLASSIC_BUTTON_RIGHT, PAD_BUTTON_RIGHT); GuiTrigger trigMinus; trigMinus.SetButtonOnlyTrigger(-1, WPAD_BUTTON_MINUS | WPAD_CLASSIC_BUTTON_MINUS, 0); GuiTrigger trigPlus; trigPlus.SetButtonOnlyTrigger(-1, WPAD_BUTTON_PLUS | WPAD_CLASSIC_BUTTON_PLUS, 0); GuiText titleTxt(tr( "Theme Downloader" ), 28, ( GXColor ) { 0, 0, 0, 255}); titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); titleTxt.SetPosition(0, 40); GuiImageData *ImageData[pagesize]; GuiImage *Image[pagesize]; GuiImage *theme_box_img[pagesize]; GuiButton *MainButton[pagesize]; GuiText *MainButtonTxt[pagesize]; Theme_List *ThemeList = NULL; /*** Buttons ***/ for (int i = 0; i < pagesize; i++) { ImageData[i] = NULL; Image[i] = NULL; MainButtonTxt[i] = NULL; theme_box_img[i] = new GuiImage(&theme_box_Data); MainButton[i] = new GuiButton(theme_box_Data.GetWidth(), theme_box_Data.GetHeight()); MainButton[i]->SetAlignment(ALIGN_LEFT, ALIGN_TOP); MainButton[i]->SetSoundOver(&btnSoundOver); MainButton[i]->SetSoundClick(&btnClick1); MainButton[i]->SetImage(theme_box_img[i]); MainButton[i]->SetEffectGrow(); MainButton[i]->SetTrigger(&trigA); } /*** Positions ***/ MainButton[0]->SetPosition(90, 75); MainButton[1]->SetPosition(340, 75); MainButton[2]->SetPosition(90, 230); MainButton[3]->SetPosition(340, 230); GuiText backBtnTxt(tr( "Back" ), 22, Theme.prompttext); backBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30); GuiImage backBtnImg(&btnOutline); if (Settings.wsprompt == yes) { backBtnTxt.SetWidescreen(Settings.widescreen); backBtnImg.SetWidescreen(Settings.widescreen); } GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, btnClick2, 1); backBtn.SetLabel(&backBtnTxt); backBtn.SetTrigger(&trigB); GuiButton HomeBtn(1, 1); HomeBtn.SetTrigger(&trigHome); GuiImage GoLeftImg(&arrow_left); GuiButton GoLeftBtn(GoLeftImg.GetWidth(), GoLeftImg.GetHeight()); GoLeftBtn.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); GoLeftBtn.SetPosition(25, -25); GoLeftBtn.SetImage(&GoLeftImg); GoLeftBtn.SetSoundOver(&btnSoundOver); GoLeftBtn.SetSoundClick(btnClick2); GoLeftBtn.SetEffectGrow(); GoLeftBtn.SetTrigger(&trigA); GoLeftBtn.SetTrigger(&trigL); GoLeftBtn.SetTrigger(&trigMinus); GuiImage GoRightImg(&arrow_right); GuiButton GoRightBtn(GoRightImg.GetWidth(), GoRightImg.GetHeight()); GoRightBtn.SetAlignment(ALIGN_RIGHT, ALIGN_MIDDLE); GoRightBtn.SetPosition(-25, -25); GoRightBtn.SetImage(&GoRightImg); GoRightBtn.SetSoundOver(&btnSoundOver); GoRightBtn.SetSoundClick(btnClick2); GoRightBtn.SetEffectGrow(); GoRightBtn.SetTrigger(&trigA); GoRightBtn.SetTrigger(&trigR); GoRightBtn.SetTrigger(&trigPlus); GuiImage PageindicatorImg(&PageindicatorImgData); GuiText PageindicatorTxt((char *) NULL, 22, ( GXColor ) { 0, 0, 0, 255}); GuiButton PageIndicatorBtn(PageindicatorImg.GetWidth(), PageindicatorImg.GetHeight()); PageIndicatorBtn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP); PageIndicatorBtn.SetPosition(110, 400); PageIndicatorBtn.SetImage(&PageindicatorImg); PageIndicatorBtn.SetLabel(&PageindicatorTxt); PageIndicatorBtn.SetSoundOver(&btnSoundOver); PageIndicatorBtn.SetSoundClick(&btnClick1); PageIndicatorBtn.SetTrigger(&trigA); PageIndicatorBtn.SetEffectGrow(); GuiImage wifiImg(&wifiImgData); if (Settings.wsprompt == yes) { wifiImg.SetWidescreen(Settings.widescreen); } GuiButton wifiBtn(wifiImg.GetWidth(), wifiImg.GetHeight()); wifiBtn.SetImage(&wifiImg); wifiBtn.SetPosition(500, 400); wifiBtn.SetSoundOver(&btnSoundOver); wifiBtn.SetSoundClick(&btnClick1); wifiBtn.SetEffectGrow(); wifiBtn.SetTrigger(&trigA); GuiWindow w(screenwidth, screenheight); HaltGui(); w.Append(&background); mainWindow->Append(&w); ResumeGui(); if (!IsNetworkInit()) NetworkInitPrompt(); char url[300]; int currentpage = 1; int currenttheme = 0; HaltGui(); w.RemoveAll(); w.Append(&background); w.Append(&titleTxt); w.Append(&backBtn); w.Append(&GoLeftBtn); w.Append(&GoRightBtn); w.Append(&PageIndicatorBtn); w.Append(&wifiBtn); w.Append(&HomeBtn); ResumeGui(); ShowProgress(tr( "Downloading Page List:" ), "", (char *) tr( "Please wait..." ), 0, pagesize); ThemeList = new Theme_List(THEME_LINK); int ThemesOnPage = ThemeList->GetThemeCount(); if (!ThemesOnPage) { WindowPrompt(tr( "No themes found on the site." ), 0, "OK"); menu = MENU_SETTINGS; } while (menu == MENU_NONE) { HaltGui(); w.RemoveAll(); w.Append(&background); w.Append(&titleTxt); w.Append(&backBtn); w.Append(&GoLeftBtn); w.Append(&GoRightBtn); w.Append(&PageIndicatorBtn); w.Append(&wifiBtn); w.Append(&HomeBtn); ResumeGui(); sprintf(url, "%i", currentpage); PageindicatorTxt.SetText(url); int n = 0; for (int i = currenttheme; (i < (currenttheme + pagesize)); i++) { ShowProgress(tr( "Downloading image:" ), 0, (char *) ThemeList->GetThemeTitle(i), n, pagesize); if (MainButtonTxt[n]) delete MainButtonTxt[n]; if (ImageData[n]) delete ImageData[n]; if (Image[n]) delete Image[n]; MainButtonTxt[n] = NULL; ImageData[n] = NULL; Image[n] = NULL; if (i < ThemesOnPage) { MainButtonTxt[n] = new GuiText(ThemeList->GetThemeTitle(i), 18, ( GXColor ) { 0, 0, 0, 255}); MainButtonTxt[n]->SetAlignment(ALIGN_CENTER, ALIGN_TOP); MainButtonTxt[n]->SetPosition(0, 10); MainButtonTxt[n]->SetMaxWidth(theme_box_Data.GetWidth() - 10, DOTTED); sprintf(url, "%s", ThemeList->GetImageLink(i)); char filepath[300]; snprintf(filepath, sizeof(filepath), "%s/tmp/%s.jpg", Settings.theme_downloadpath, ThemeList->GetThemeTitle(i)); FILE * storefile = fopen(filepath, "rb"); if (!storefile) { struct block file = downloadfile(url); char storepath[300]; snprintf(storepath, sizeof(storepath), "%s/tmp/", Settings.theme_downloadpath); subfoldercreate(storepath); if (file.data) { storefile = fopen(filepath, "wb"); fwrite(file.data, 1, file.size, storefile); fclose(storefile); } ImageData[n] = new GuiImageData(file.data, file.size); free(file.data); } else { fseek(storefile, 0, SEEK_END); u32 filesize = ftell(storefile); u8 *buffer = (u8*) malloc(filesize); rewind(storefile); fread(buffer, 1, filesize, storefile); fclose(storefile); ImageData[n] = new GuiImageData(buffer, filesize); free(buffer); buffer = NULL; } Image[n] = new GuiImage(ImageData[n]); Image[n]->SetScale(0.4); Image[n]->SetPosition(50, -45); MainButton[n]->SetIcon(Image[n]); MainButton[n]->SetLabel(MainButtonTxt[n]); } n++; } ProgressStop(); HaltGui(); for (int i = 0; i < pagesize; i++) { if (MainButtonTxt[i]) w.Append(MainButton[i]); } ResumeGui(); listchanged = false; while (!listchanged) { VIDEO_WaitVSync(); if (shutdown == 1) Sys_Shutdown(); else if (reset == 1) Sys_Reboot(); else if (wifiBtn.GetState() == STATE_CLICKED) { Initialize_Network(); wifiBtn.ResetState(); } else if (backBtn.GetState() == STATE_CLICKED) { listchanged = true; menu = MENU_SETTINGS; backBtn.ResetState(); break; } else if (GoRightBtn.GetState() == STATE_CLICKED) { listchanged = true; currenttheme += pagesize; currentpage++; if (currenttheme >= ThemesOnPage) { currentpage = 1; currenttheme = 0; } GoRightBtn.ResetState(); } else if (GoLeftBtn.GetState() == STATE_CLICKED) { listchanged = true; currenttheme -= pagesize; currentpage--; if (currenttheme < 0) { currentpage = roundup((ThemesOnPage + 1.0f) / pagesize); currenttheme = currentpage * pagesize - pagesize; } GoLeftBtn.ResetState(); } for (int i = 0; i < pagesize; i++) { if (MainButton[i]->GetState() == STATE_CLICKED) { snprintf(url, sizeof(url), "%s", ThemeList->GetDownloadLink(currenttheme + i)); int ret = Theme_Prompt(ThemeList->GetThemeTitle(currenttheme + i), ThemeList->GetThemeAuthor(currenttheme + i), ImageData[i], url); MainButton[i]->ResetState(); if (ret == 2) { listchanged = true; menu = MENU_THEMEDOWNLOADER; } } } } } w.SetEffect(EFFECT_FADE, -20); while (w.GetEffect() > 0) usleep(100); HaltGui(); mainWindow->Remove(&w); for (int i = 0; i < pagesize; i++) { if (MainButton[i]) delete MainButton[i]; if (theme_box_img[i]) delete theme_box_img[i]; if (ImageData[i]) delete ImageData[i]; if (Image[i]) delete Image[i]; if (MainButtonTxt[i]) delete MainButtonTxt[i]; } if (ThemeList) delete ThemeList; ThemeList = NULL; ResumeGui(); return menu; }