usbloadergx/source/themes/Theme_Downloader.cpp
dimok321 d62e41d601 *Removed ntfs/fat source and added them as custom libs (makes them easier to update later)
*Added sources of the custom libs to the branches
*Fixed crash when switching from list layout to grid/carousel layout
*Removed 1:1 copy option because its meaningless and almost the same as installing all partitions
*Fixed install partition selection. This option needs a reset. Go to settings and reselect your option for this.
*Fixed schinese and tchinese language modes (filename bugs. has to be schinese.lang and tchinese.lang like on SVN)
*Fixed bug in sound buffer circle
*Fixed incorrect behaviour of x-flip when selecting system like (thx Cyan for the patch)
*Accept ios revision 65535 for Waninkokos IOSes (thx to PPSainity for pointing it out)
*Merged the new theming style branch into trunk. Just as a reminder: ALL old themes will not work until the themers did port it to the new style!
*Removed old theme style completely

Theme example:
The example file of the theme is the Default.them file. It can be found in the SVN trunk.

Change in loading of themes:
When selecting a theme now a list of all .them files in a folder is displayed. The image folder of that theme has to be in the same folder as the .them file. The image path is defined in the head of the .them file in the line with "Image-Folder: Example\n".
2010-12-26 17:02:14 +00:00

628 lines
20 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 "homebrewboot/HomebrewBrowse.h"
#include "network/networkops.h"
#include "themes/Theme_List.h"
#include "themes/CTheme.h"
#include "menu.h"
#include "filelist.h"
#include "FileOperations/fileops.h"
#include "sys.h"
#include "network/http.h"
#include "ZipFile.h"
#include "gecko.h"
/*** Extern variables ***/
extern u8 shutdown;
extern u8 reset;
extern int connection;
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);
CreateSubfolder(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(connection, 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, <DATA>, %s)", title, author, downloadlink);
bool leave = false;
int result = 0;
GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png"));
GuiImageData dialogBox(Resources::GetFile("theme_dialogue_box.png"), Resources::GetFileSize("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, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
titleTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
titleTxt.SetPosition(230, 30);
GuiText titleTxt2(title, 18, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
titleTxt2.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
titleTxt2.SetPosition(230, 50);
titleTxt2.SetMaxWidth(dialogBox.GetWidth() - 220, WRAP);
GuiText authorTxt(tr( "Author:" ), 18, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
authorTxt.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
authorTxt.SetPosition(230, 100);
GuiText authorTxt2(author, 18, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
authorTxt2.SetAlignment(ALIGN_LEFT, ALIGN_TOP);
authorTxt2.SetPosition(230, 120);
authorTxt2.SetMaxWidth(dialogBox.GetWidth() - 220, DOTTED);
GuiText downloadBtnTxt(tr( "Download" ), 22, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
downloadBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30);
GuiImage downloadBtnImg(&btnOutline);
if (Settings.wsprompt)
{
downloadBtnTxt.SetWidescreen(Settings.widescreen);
downloadBtnImg.SetWidescreen(Settings.widescreen);
}
GuiButton downloadBtn(&downloadBtnImg, &downloadBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 170, &trigA, btnSoundOver,
btnSoundClick2, 1);
downloadBtn.SetLabel(&downloadBtnTxt);
downloadBtn.SetScale(0.9);
GuiText backBtnTxt(tr( "Back" ), 22, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
backBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30);
GuiImage backBtnImg(&btnOutline);
if (Settings.wsprompt)
{
backBtnTxt.SetWidescreen(Settings.widescreen);
backBtnImg.SetWidescreen(Settings.widescreen);
}
GuiButton backBtn(&backBtnImg, &backBtnImg, ALIGN_RIGHT, ALIGN_TOP, -5, 220, &trigA, btnSoundOver, btnSoundClick2, 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(100);
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);
/*** Image Variables ***/
GuiImageData btnOutline(Resources::GetFile("button_dialogue_box.png"), Resources::GetFileSize("button_dialogue_box.png"));
GuiImageData theme_box_Data(Resources::GetFile("theme_box.png"), Resources::GetFileSize("theme_box.png"));
GuiImageData bgData(Resources::GetFile("settings_background.png"), Resources::GetFileSize("settings_background.png"));
GuiImageData arrow_left(Resources::GetFile("startgame_arrow_left.png"), Resources::GetFileSize("startgame_arrow_left.png"));
GuiImageData arrow_right(Resources::GetFile("startgame_arrow_right.png"), Resources::GetFileSize("startgame_arrow_right.png"));
GuiImageData wifiImgData(Resources::GetFile("Wifi_btn.png"), Resources::GetFileSize("Wifi_btn.png"));
GuiImageData PageindicatorImgData(Resources::GetFile("pageindicator.png"), Resources::GetFileSize("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(btnSoundClick);
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, thColor("r=0 g=0 b=0 a=255 - prompt windows text color"));
backBtnTxt.SetMaxWidth(btnOutline.GetWidth() - 30);
GuiImage backBtnImg(&btnOutline);
if (Settings.wsprompt)
{
backBtnTxt.SetWidescreen(Settings.widescreen);
backBtnImg.SetWidescreen(Settings.widescreen);
}
GuiButton backBtn(&backBtnImg, &backBtnImg, 2, 3, -180, 400, &trigA, btnSoundOver, btnSoundClick2, 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(btnSoundClick2);
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(btnSoundClick2);
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(btnSoundClick);
PageIndicatorBtn.SetTrigger(&trigA);
PageIndicatorBtn.SetEffectGrow();
GuiImage wifiImg(&wifiImgData);
if (Settings.wsprompt)
{
wifiImg.SetWidescreen(Settings.widescreen);
}
GuiButton wifiBtn(wifiImg.GetWidth(), wifiImg.GetHeight());
wifiBtn.SetImage(&wifiImg);
wifiBtn.SetPosition(500, 400);
wifiBtn.SetSoundOver(btnSoundOver);
wifiBtn.SetSoundClick(btnSoundClick);
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);
CreateSubfolder(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 = ceil((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;
}