usbloadergx/source/themes/Theme_Downloader.cpp
dimok321 ed2ac8f085 *Created a Theme Downloader with preview, downloading themes from http://wii.spiffy360.com/ (Thanks for hosting them)
NOTE: The images used right now for the theme loader are made out of our old images and if someone can make some new ones go ahead. The themes are downloaded to the path you can set up. The downloaded preview images are cached at "<set up theme downloadpath>/tmp/". The widescreenfix isn't implemented there yet because images will probably be changed.

*Started 3rd SettingsPage

*Added JPEG Loading GuiImageData function and 4x4RGBA converter by r-win from WiiXplorer

*Added ZipFile Class from WiiXplorer

*Added StringToMD5 and MD5ToString to MD5 functions and made it undependable of platform
2009-10-21 19:32:46 +00:00

664 lines
22 KiB
C++

/****************************************************************************
* Theme_Downloader
* USB Loader GX 2009
*
* Theme downloader for USB Loader GX
*
* Theme_Downloader.cpp
***************************************************************************/
#include <string.h>
#include <unistd.h>
#include "language/gettext.h"
#include "libwiigui/gui.h"
#include "prompts/PromptWindows.h"
#include "prompts/ProgressWindow.h"
#include "network/networkops.h"
#include "themes/Theme_List.h"
#include "menu.h"
#include "filelist.h"
#include "listfiles.h"
#include "sys.h"
#include "network/http.h"
#include "ZipFile.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;
bool DownloadTheme(const char *url, const char *title)
{
if(!url)
return false;
int filesize = download_request(url);
if(filesize <= 0)
{
WindowPrompt(tr("Download request failed."), 0, tr("OK"));
return false;
}
char path[300];
char filepath[300];
snprintf(path, sizeof(path), "%s%s", Settings.theme_downloadpath, title);
subfoldercreate(path);
snprintf(filepath, sizeof(filepath), "%s/%s.zip", path, title);
FILE *file = fopen(filepath, "wb");
if(!file)
{
WindowPrompt(tr("Download failed."), tr("Can't create file"), tr("OK"));
return false;
}
u32 done = 0;
int blocksize = 1024;
u8 *buffer = (u8*) malloc(blocksize);
while(done < (u32) filesize)
{
if((u32) blocksize > filesize-done)
blocksize = filesize-done;
ShowProgress(tr("Downloading file:"), 0, (char*) title, 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 false;
}
fwrite(buffer, 1, blocksize, file);
done += ret;
}
free(buffer);
fclose(file);
ProgressStop();
ZipFile zipfile(filepath);
bool result = zipfile.ExtractAll(path);
if(result)
{
remove(filepath);
WindowPrompt(tr("Successfully extracted theme."), title, tr("OK"));
}
else
WindowPrompt(tr("Failed to extract."), tr("Unsupported format, try to extract manually."), tr("OK"));
return result;
}
static void Theme_Prompt(const char *title, const char *author, GuiImageData *thumbimageData, const char *downloadlink)
{
bool leave = false;
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
char imgPath[100];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
snprintf(imgPath, sizeof(imgPath), "%stheme_dialogue_box.png", CFG.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("Themetitle:"), 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, GuiText::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, GuiText::DOTTED);
GuiText downloadBtnTxt(tr("Download") , 22, THEME.prompttext);
downloadBtnTxt.SetMaxWidth(btnOutline.GetWidth()-30);
GuiImage downloadBtnImg(&btnOutline);
if (Settings.wsprompt == yes)
{
downloadBtnTxt.SetWidescreen(CFG.widescreen);
downloadBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton downloadBtn(&downloadBtnImg,&downloadBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 170, &trigA, &btnSoundOver, &btnClick,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(CFG.widescreen);
backBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton backBtn(&backBtnImg,&backBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 220, &trigA, &btnSoundOver, &btnClick,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)
{
DownloadTheme(downloadlink, title);
}
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();
}
int Theme_Downloader()
{
int pagesize = 4;
int menu = MENU_NONE;
bool pagechanged = false;
bool listchanged = false;
char THEME_LINK[30] = "http://wii.spiffy360.com/";
/*** Sound Variables ***/
GuiSound btnSoundOver(button_over_pcm, button_over_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiSound btnClick(button_click2_pcm, button_click2_pcm_size, SOUND_PCM, Settings.sfxvolume);
GuiSound btnClick1(button_click_pcm, button_click_pcm_size, SOUND_PCM, Settings.sfxvolume);
/*** Image Variables ***/
char imgPath[150];
snprintf(imgPath, sizeof(imgPath), "%sbutton_dialogue_box.png", CFG.theme_path);
GuiImageData btnOutline(imgPath, button_dialogue_box_png);
snprintf(imgPath, sizeof(imgPath), "%stheme_box.png", CFG.theme_path);
GuiImageData theme_box_Data(imgPath, theme_box_png);
snprintf(imgPath, sizeof(imgPath), "%ssettings_background.png", CFG.theme_path);
GuiImageData bgData(imgPath, settings_background_png);
snprintf(imgPath, sizeof(imgPath), "%sstartgame_arrow_left.png", CFG.theme_path);
GuiImageData arrow_left(imgPath, startgame_arrow_left_png);
snprintf(imgPath, sizeof(imgPath), "%sstartgame_arrow_right.png", CFG.theme_path);
GuiImageData arrow_right(imgPath, startgame_arrow_right_png);
snprintf(imgPath, sizeof(imgPath), "%sWifi_btn.png", CFG.theme_path);
GuiImageData wifiImgData(imgPath, Wifi_btn_png);
snprintf(imgPath, sizeof(imgPath), "%spageindicator.png", CFG.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 *Theme = 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(CFG.widescreen);
backBtnImg.SetWidescreen(CFG.widescreen);
}
GuiButton backBtn(&backBtnImg,&backBtnImg, 2, 3, -180, 400, &trigA, &btnSoundOver, &btnClick,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(&btnClick);
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(&btnClick);
GoRightBtn.SetEffectGrow();
GoRightBtn.SetTrigger(&trigA);
GoRightBtn.SetTrigger(&trigR);
GoRightBtn.SetTrigger(&trigPlus);
GuiImage PageindicatorImg(&PageindicatorImgData);
GuiText PageindicatorTxt(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 Pageindicator2Img(&PageindicatorImgData);
GuiText Pageindicator2Txt(NULL, 22, (GXColor) { 0, 0, 0, 255});
GuiButton PageIndicator2Btn(Pageindicator2Img.GetWidth(), Pageindicator2Img.GetHeight());
PageIndicator2Btn.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
PageIndicator2Btn.SetPosition(150, 400);
PageIndicator2Btn.SetImage(&Pageindicator2Img);
PageIndicator2Btn.SetLabel(&Pageindicator2Txt);
PageIndicator2Btn.SetSoundOver(&btnSoundOver);
PageIndicator2Btn.SetSoundClick(&btnClick1);
PageIndicator2Btn.SetTrigger(&trigA);
PageIndicator2Btn.SetEffectGrow();
GuiImage wifiImg(&wifiImgData);
if (Settings.wsprompt == yes)
{
wifiImg.SetWidescreen(CFG.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;
int currentloaderpage = 1;
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(&PageIndicator2Btn);
w.Append(&wifiBtn);
w.Append(&HomeBtn);
ResumeGui();
ShowProgress(tr("Downloading pagelist:"), 0, (char *) "please wait...", 0, pagesize);
snprintf(url, sizeof(url), "%sthemes.php?creator=&sort=1&page=%i", THEME_LINK, currentpage);
if(Theme)
{
delete Theme;
Theme = NULL;
}
Theme = new Theme_List(url);
sprintf(url, "%i", currentpage);
PageindicatorTxt.SetText(url);
int SitePageCount = Theme->GetSitepageCount();
int ThemesOnPage = Theme->GetThemeCount();
pagechanged = false;
if(!ThemesOnPage)
{
WindowPrompt(tr("No themes found on the site."), 0, "OK");
pagechanged = true;
menu = MENU_SETTINGS;
}
while(!pagechanged)
{
HaltGui();
w.RemoveAll();
w.Append(&background);
w.Append(&titleTxt);
w.Append(&backBtn);
w.Append(&GoLeftBtn);
w.Append(&GoRightBtn);
w.Append(&PageIndicatorBtn);
w.Append(&PageIndicator2Btn);
w.Append(&wifiBtn);
w.Append(&HomeBtn);
ResumeGui();
sprintf(url, "%i", currentloaderpage);
Pageindicator2Txt.SetText(url);
int n = 0;
for(int i = currenttheme; (i < (currenttheme+pagesize)); i++)
{
ShowProgress(tr("Downloading image:"), 0, (char *) Theme->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(Theme->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, GuiText::DOTTED);
if(!Theme->IsDirectImageLink(i))
sprintf(url, "%s%s", THEME_LINK, Theme->GetImageLink(i));
else
sprintf(url, "%s", Theme->GetImageLink(i));
char filepath[300];
snprintf(filepath, sizeof(filepath), "%s/tmp/%s.png", Settings.theme_downloadpath, Theme->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;
pagechanged = true;
menu = MENU_SETTINGS;
backBtn.ResetState();
break;
}
else if (GoRightBtn.GetState() == STATE_CLICKED)
{
listchanged = true;
currenttheme += pagesize;
currentloaderpage++;
if(currenttheme >= ThemesOnPage)
{
pagechanged = true;
currentpage++;
if(currentpage > SitePageCount)
currentpage = 1;
currenttheme = 0;
currentloaderpage = 1;
}
GoRightBtn.ResetState();
}
else if (GoLeftBtn.GetState() == STATE_CLICKED)
{
listchanged = true;
currenttheme -= pagesize;
currentloaderpage--;
if(currenttheme < 0)
{
pagechanged = true;
currentpage--;
if(currentpage < 1)
currentpage = SitePageCount;
currenttheme = 0;
currentloaderpage = 1;
}
GoLeftBtn.ResetState();
}
for(int i = 0; i < pagesize; i++)
{
if(MainButton[i]->GetState() == STATE_CLICKED)
{
snprintf(url, sizeof(url), "%s%s", THEME_LINK, Theme->GetDownloadLink(currenttheme+i));
Theme_Prompt(Theme->GetThemeTitle(currenttheme+i), Theme->GetThemeAuthor(currenttheme+i), ImageData[i], url);
MainButton[i]->ResetState();
}
}
}
}
}
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(Theme)
delete Theme;
Theme = NULL;
ResumeGui();
return menu;
}