From 441a203678af466ccc589012f29703c5cbf86542 Mon Sep 17 00:00:00 2001 From: "e.bovendeur" Date: Thu, 10 Dec 2009 20:27:36 +0000 Subject: [PATCH] * Added BETA upgrades option (to download the latest revisions from google code) * Added Wii Parental Control support * Added gui numpad * Changed GuiText to support password character * Added lock/unlock icon in the titlebar (to unlock Parental Control) * Added new wbfs_fat from Oggzee (further speed improvement) --- HBC/META.XML | 4 +- gui.pnproj | 2 +- gui.pnps | 2 +- source/filelist.h | 6 + source/images/lock.png | Bin 0 -> 4641 bytes source/images/unlock.png | Bin 0 -> 4329 bytes source/libwiigui/gui.h | 39 +++++ source/libwiigui/gui_text.cpp | 29 +++- source/lstub.c | 25 +-- source/lstub.h | 3 +- source/main.cpp | 20 +-- source/menu/menu_disclist.cpp | 100 +++++++++++- source/network/networkops.cpp | 28 ++-- source/network/update.cpp | 82 ++++++++++ source/network/update.h | 34 +++++ source/prompts/PromptWindows.cpp | 97 +++++++++++- source/prompts/PromptWindows.h | 1 + source/settings/Settings.cpp | 26 ++++ source/settings/cfg.c | 112 +++++++++++--- source/settings/cfg.h | 25 ++- source/settings/newtitles.cpp | 10 +- source/usbloader/getentries.cpp | 25 +++ source/usbloader/wbfs.c | 21 ++- source/usbloader/wbfs_fat.c | 252 +++++++++++++++---------------- source/xml/xml.c | 33 ++++ source/xml/xml.h | 2 + 26 files changed, 774 insertions(+), 204 deletions(-) create mode 100644 source/images/lock.png create mode 100644 source/images/unlock.png create mode 100644 source/network/update.cpp create mode 100644 source/network/update.h diff --git a/HBC/META.XML b/HBC/META.XML index 09d1023a..506c4307 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,8 +2,8 @@ USB Loader GX USB Loader GX Team - 1.0 r850 - 200912050746 + 1.0 r851 + 200912082034 Loads games from USB-devices USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times. The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller. diff --git a/gui.pnproj b/gui.pnproj index d829b811..26b6b717 100644 --- a/gui.pnproj +++ b/gui.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/gui.pnps b/gui.pnps index 4b727dd7..24e1cecf 100644 --- a/gui.pnps +++ b/gui.pnps @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/source/filelist.h b/source/filelist.h index 4e2716bd..fa4f31c1 100644 --- a/source/filelist.h +++ b/source/filelist.h @@ -540,4 +540,10 @@ extern const u32 dvd_png_size; extern const u8 new_png[]; extern const u32 new_png_size; +extern const u8 lock_png[]; +extern const u32 lock_png_size; + +extern const u8 unlock_png[]; +extern const u32 unlock_png_size; + #endif diff --git a/source/images/lock.png b/source/images/lock.png new file mode 100644 index 0000000000000000000000000000000000000000..fc613766ff3714dd50cd80ddd9d9de0ffe923f6d GIT binary patch literal 4641 zcmV++65j2JP)004&%004{+008|`004nN004b?008NW002DY000@xb3BE2000U( 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 XlO1E}wDr^V00000NkvXXu0mjfRsYjz literal 0 HcmV?d00001 diff --git a/source/images/unlock.png b/source/images/unlock.png new file mode 100644 index 0000000000000000000000000000000000000000..241f1b371e392558d27aa273c1e780ff18e28822 GIT binary patch literal 4329 zcmV004&%004{+008|`004nN004b?008NW002DY000@xb3BE2000U( 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 XX8VwN)k@IE00000NkvXXu0mjf;94n6 literal 0 HcmV?d00001 diff --git a/source/libwiigui/gui.h b/source/libwiigui/gui.h index a3e428a6..9d9f8854 100644 --- a/source/libwiigui/gui.h +++ b/source/libwiigui/gui.h @@ -759,6 +759,9 @@ class GuiText : public GuiElement //!Sets the font //!\param f Font void SetFont(FreeTypeGX *f); + //!Sets a password character + //!\param p char + void SetPassChar(wchar_t p); //!Get the Horizontal Size of Text int GetTextWidth(); // not NULL set horizontal scale to 0.75 //added @@ -788,6 +791,7 @@ class GuiText : public GuiElement int firstLine; //!these are the first line and the number of lines drawn when the text is wrapped int numLines;//! default is -1 and it means that all lines are drawn int totalLines; //!this is the total # of lines when in wrap mode + wchar_t passChar; //!this is the password character }; //!Display, manage, and manipulate tooltips in the GUI. @@ -1000,6 +1004,41 @@ class GuiKeyboard : public GuiWindow GuiTrigger * trigB; }; +//!On-screen keyboard +class GuiNumpad : public GuiWindow +{ + public: + GuiNumpad(char * t, u32 max); + ~GuiNumpad(); + void Update(GuiTrigger * t); + char kbtextstr[256]; + protected: + u32 kbtextmaxlen; + char keys[10]; + GuiText * kbText; + GuiImage * keyTextboxImg; + + GuiText * keyBackText; + GuiImage * keyBackImg; + GuiImage * keyBackOverImg; + GuiButton * keyBack; + GuiText * keyClearText; + GuiImage * keyClearImg; + GuiImage * keyClearOverImg; + GuiButton * keyClear; + GuiButton * keyBtn[10]; + GuiImage * keyImg[10]; + GuiImage * keyImgOver[10]; + GuiText * keyTxt[10]; + GuiImageData * keyTextbox; + GuiImageData * keyMedium; + GuiImageData * keyMediumOver; + GuiSound * keySoundOver; + GuiSound * keySoundClick; + GuiTrigger * trigA; + GuiTrigger * trigB; +}; + typedef struct _optionlist { int length; char name[MAX_OPTIONS][60]; diff --git a/source/libwiigui/gui_text.cpp b/source/libwiigui/gui_text.cpp index 7c9c5f56..b3fa8e92 100644 --- a/source/libwiigui/gui_text.cpp +++ b/source/libwiigui/gui_text.cpp @@ -38,6 +38,7 @@ GuiText::GuiText(const char * t, int s, GXColor c) firstLine = 1; numLines = -1; totalLines = 1; + passChar = 0; alignmentHor = ALIGN_CENTRE; alignmentVert = ALIGN_MIDDLE; @@ -130,8 +131,15 @@ void GuiText::SetText(const char * t) delete [] text; text = NULL; - if(t) + if(t) { text = FreeTypeGX::charToWideChar((char *)t); + + if (passChar != 0) { + for (u8 i = 0; i < wcslen(text); i++) { + text[i] = passChar; + } + } + } scrollPos2 = 0; scrollDelay = 0; } @@ -158,7 +166,15 @@ void GuiText::SetText(const wchar_t * t) { int len = wcslen(t); text = new wchar_t[len+1]; - if(text) wcscpy(text, t); + if(text) { + wcscpy(text, t); + } + + if (passChar != 0) { + for (u8 i = 0; i < wcslen(text); i++) { + text[i] = passChar; + } + } } scrollPos2 = 0; scrollDelay = 0; @@ -236,6 +252,15 @@ void GuiText::SetAlignment(int hor, int vert) alignmentHor = hor; alignmentVert = vert; } +/** + * Set a password character + */ +void GuiText::SetPassChar(wchar_t p) +{ + LOCK(this); + passChar = p; +} + /** * Set the Font */ diff --git a/source/lstub.c b/source/lstub.c index 5ae4121f..b00d1f8f 100644 --- a/source/lstub.c +++ b/source/lstub.c @@ -88,16 +88,7 @@ void loadStub() u64 getStubDest() { - char * sig = (char *)0x80001804; - if (!( - sig[0] == 'S' && - sig[1] == 'T' && - sig[2] == 'U' && - sig[3] == 'B' && - sig[4] == 'H' && - sig[5] == 'A' && - sig[6] == 'X' && - sig[7] == 'X')) + if (!hbcStubAvailable()) return 0; @@ -119,3 +110,17 @@ u64 getStubDest() return retu; } +u8 hbcStubAvailable() +{ + char * sig = (char *)0x80001804; + return ( + sig[0] == 'S' && + sig[1] == 'T' && + sig[2] == 'U' && + sig[3] == 'B' && + sig[4] == 'H' && + sig[5] == 'A' && + sig[6] == 'X' && + sig[7] == 'X') ? 1 : 0; +} + diff --git a/source/lstub.h b/source/lstub.h index a342ac10..51ab3317 100644 --- a/source/lstub.h +++ b/source/lstub.h @@ -27,7 +27,8 @@ void loadStub(); //!otherwise returns the ID set to return to u64 getStubDest(); - +//returns 0 or 1 depending on wether the stub is available +u8 hbcStubAvailable(); #ifdef __cplusplus diff --git a/source/main.cpp b/source/main.cpp index 28b47b13..09016033 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -16,10 +16,11 @@ #include #include #include -//#include -//extern "C" { //not sure if this is in the libogc that the buildbot is using so it isnt used yet -//extern void __exception_setreload(int t); -//} + +#include +extern "C" { //not sure if this is in the libogc that the buildbot is using so it isnt used yet +extern void __exception_setreload(int t); +} #include #include @@ -51,6 +52,7 @@ #include "usbloader/partition_usbloader.h" #include "usbloader/usbstorage.h" #include "memory/mem2.h" +#include "lstub.h" extern bool geckoinit; extern bool textVideoInit; @@ -175,16 +177,16 @@ void InitTextVideo () { } - int main(int argc, char *argv[]) { - InitTextVideo(); + if (hbcStubAvailable()) { + InitTextVideo(); + } -//DEBUG_Init(GDBSTUB_DEVICE_USB, 1); +// DEBUG_Init(GDBSTUB_DEVICE_USB, 1); //_break(); - - //see note above __exception_setreload(5);//auto reset is code dump nobody gives us codedump info anyways. +// __exception_setreload(5);//auto reset is code dump nobody gives us codedump info anyways. setlocale(LC_ALL, "en.UTF-8"); geckoinit = InitGecko(); if (geckoinit)InitTextVideo(); diff --git a/source/menu/menu_disclist.cpp b/source/menu/menu_disclist.cpp index dce03421..e6aa661d 100644 --- a/source/menu/menu_disclist.cpp +++ b/source/menu/menu_disclist.cpp @@ -34,7 +34,7 @@ extern GuiImageData * pointer[4]; extern bool altdoldefault; extern GuiImage * bgImg; -GuiButton *Toolbar[8]; +GuiButton *Toolbar[9]; int idiotFlag=-1; char idiotChar[50]; @@ -155,6 +155,16 @@ int MenuDiscList() { GuiImageData imgarrangeCarousel(imgPath, arrangeCarousel_png); snprintf(imgPath, sizeof(imgPath), "%sarrangeCarousel_gray.png", CFG.theme_path); GuiImageData imgarrangeCarousel_gray(imgPath, NULL); + + snprintf(imgPath, sizeof(imgPath), "%slock.png", CFG.theme_path); + GuiImageData imgLock(imgPath, lock_png); + snprintf(imgPath, sizeof(imgPath), "%slock_gray.png", CFG.theme_path); + GuiImageData imgLock_gray(imgPath, NULL); + snprintf(imgPath, sizeof(imgPath), "%sunlock.png", CFG.theme_path); + GuiImageData imgUnlock(imgPath, unlock_png); + snprintf(imgPath, sizeof(imgPath), "%sunlock_gray.png", CFG.theme_path); + GuiImageData imgUnlock_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); @@ -355,6 +365,42 @@ int MenuDiscList() { 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); + bool canUnlock = (Settings.parentalcontrol == 0 && Settings.parental.enabled == 1); + + GuiTooltip lockBtnTT(canUnlock ? tr("Unlock Parental Control") : tr("Parental Control disabled")); + if (Settings.wsprompt == yes) + lockBtnTT.SetWidescreen(CFG.widescreen); + lockBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage lockBtnImg(&imgLock); + lockBtnImg.SetWidescreen(CFG.widescreen); + GuiImage lockBtnImg_g(&imgLock_gray); + if(lockBtnImg_g.GetImage() == NULL) { lockBtnImg_g = lockBtnImg; lockBtnImg_g.SetGrayscale(); } + lockBtnImg_g.SetWidescreen(CFG.widescreen); + GuiButton lockBtn(&lockBtnImg_g, &lockBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_lock_x, THEME.gamelist_lock_y, &trigA, &btnSoundOver, btnClick2,1, &lockBtnTT, 15, 52, 1, 3); + lockBtn.SetAlpha(180); + + GuiTooltip unlockBtnTT(tr("Enable Parental Control")); + if (Settings.wsprompt == yes) + unlockBtnTT.SetWidescreen(CFG.widescreen); + unlockBtnTT.SetAlpha(THEME.tooltipAlpha); + GuiImage unlockBtnImg(&imgUnlock); + unlockBtnImg.SetWidescreen(CFG.widescreen); + GuiImage unlockBtnImg_g(&imgUnlock_gray); + if(unlockBtnImg_g.GetImage() == NULL) { unlockBtnImg_g = unlockBtnImg; unlockBtnImg_g.SetGrayscale(); } + unlockBtnImg_g.SetWidescreen(CFG.widescreen); + + if (canUnlock && Settings.parental.is_unlocked) + { + lockBtn.SetImage(&unlockBtnImg_g); + lockBtn.SetImageOver(&unlockBtnImg_g); + lockBtn.SetToolTip(&unlockBtnTT, 15, 52, 1, 3); + } + +/* + GuiButton unlockBtn(&unlockBtnImg_g, &unlockBtnImg_g, ALIGN_LEFT, ALIGN_TOP, THEME.gamelist_lock_x, THEME.gamelist_lock_y, &trigA, &btnSoundOver, btnClick2,1, &lockBtnTT, 15, 52, 1, 3); + unlockBtn.SetAlpha(180); +*/ + GuiTooltip dvdBtnTT(tr("Mount DVD drive")); if (Settings.wsprompt == yes) dvdBtnTT.SetWidescreen(CFG.widescreen); @@ -415,14 +461,16 @@ int MenuDiscList() { carouselBtn.SetImageOver(&carouselBtnImg); carouselBtn.SetAlpha(255); } + if (Settings.gameDisplay==list) { - favoriteBtn.SetPosition(THEME.gamelist_favorite_x, THEME.gamelist_favorite_y); + 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); + lockBtn.SetPosition(THEME.gamelist_lock_x, THEME.gamelist_lock_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); @@ -432,6 +480,7 @@ int MenuDiscList() { 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); + lockBtn.SetPosition(THEME.gamegrid_lock_x, THEME.gamegrid_lock_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); @@ -441,6 +490,7 @@ int MenuDiscList() { 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); + lockBtn.SetPosition(THEME.gamecarousel_lock_x, THEME.gamecarousel_lock_y); dvdBtn.SetPosition(THEME.gamecarousel_dvd_x, THEME.gamecarousel_dvd_y); } @@ -462,8 +512,6 @@ int MenuDiscList() { 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); @@ -541,8 +589,10 @@ int MenuDiscList() { Toolbar[5] = &gridBtn; w.Append(&carouselBtn); Toolbar[6] = &carouselBtn; + w.Append(&lockBtn); + Toolbar[7] = &lockBtn; w.Append(&dvdBtn); - Toolbar[7] = &dvdBtn; + Toolbar[8] = &dvdBtn; w.SetUpdateCallback(DiscListWinUpdateCallback); // End Toolbar @@ -1042,6 +1092,46 @@ int MenuDiscList() { } } } + else if (lockBtn.GetState() == STATE_CLICKED) { + gprintf("\n\tlockBtn clicked"); + lockBtn.ResetState(); + if (!canUnlock) { + WindowPrompt(tr("Parental Control"), tr("You don't have Parental Control enabled. If you wish to use Parental Control, enable it in the Wii Settings."), tr("OK")); + } else { + if (Settings.parental.is_unlocked) { + if (WindowPrompt(tr("Parental Control"), tr("Are you sure you want to enable Parent Control?"), tr("Yes"), tr("No")) == 1) { + Settings.parental.is_unlocked = 0; + lockBtn.SetImage(&lockBtnImg_g); + lockBtn.SetImageOver(&lockBtnImg_g); + lockBtn.SetToolTip(&lockBtnTT, 15, 52, 1, 3); + + // Retrieve the gamelist again + menu = MENU_DISCLIST; + break; + } + } else { + // Require the user to enter the PIN code + char pin[5]; + memset(&pin, 0, 5); + int ret = OnScreenNumpad((char *) &pin, 5); + + if (ret == 1) { + if (memcmp(pin, Settings.parental.pin, 4) == 0) { + Settings.parental.is_unlocked = 1; + lockBtn.SetImage(&unlockBtnImg_g); + lockBtn.SetImageOver(&unlockBtnImg_g); + lockBtn.SetToolTip(&unlockBtnTT, 15, 52, 1, 3); + + // Retrieve the gamelist again + menu = MENU_DISCLIST; + break; + } else { + WindowPrompt(tr("Parental Control"), tr("Invalid PIN code"), tr("OK")); + } + } + } + } + } else if (dvdBtn.GetState() == STATE_CLICKED) { gprintf("\n\tdvdBtn Clicked"); mountMethodOLD = (mountMethod==3?mountMethod:0); diff --git a/source/network/networkops.cpp b/source/network/networkops.cpp index 68b991ee..a718e638 100644 --- a/source/network/networkops.cpp +++ b/source/network/networkops.cpp @@ -18,6 +18,7 @@ #include "http.h" #include "svnrev.h" #include "buildtype.h" +#include "update.h" #define PORT 4299 @@ -297,24 +298,27 @@ int CheckUpdate() { int revnumber = 0; int currentrev = atoi(GetRev()); + if (Settings.beta_upgrades) { + revnumber = CheckForBetaUpdate(); + } else { #ifdef FULLCHANNEL - struct block file = downloadfile("http://www.techjawa.com/usbloadergx/wadrev.txt"); + struct block file = downloadfile("http://www.techjawa.com/usbloadergx/wadrev.txt"); #else - struct block file = downloadfile("http://www.techjawa.com/usbloadergx/rev.txt"); + struct block file = downloadfile("http://www.techjawa.com/usbloadergx/rev.txt"); #endif - char revtxt[10]; + char revtxt[10]; - u8 i; - if (file.data != NULL) { - for (i=0; i<9 || i < file.size; i++) - revtxt[i] = file.data[i]; - revtxt[i] = 0; - revnumber = atoi(revtxt); - free(file.data); - } + u8 i; + if (file.data != NULL) { + for (i=0; i<9 || i < file.size; i++) + revtxt[i] = file.data[i]; + revtxt[i] = 0; + revnumber = atoi(revtxt); + free(file.data); + } + } if (revnumber > currentrev) - //if(revnumber > 1)//for testing updates return revnumber; else return -1; diff --git a/source/network/update.cpp b/source/network/update.cpp new file mode 100644 index 00000000..53b1fa70 --- /dev/null +++ b/source/network/update.cpp @@ -0,0 +1,82 @@ + /*************************************************************************** + * Copyright (C) 2009 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + * update.cpp + * + * Update operations + * for Wii-Xplorer 2009 + ***************************************************************************/ +#include +#include +#include + +#include "http.h" +#include "networkops.h" +#include "URL_List.h" + +/**************************************************************************** + * Checking if an Update is available + ***************************************************************************/ +int CheckForBetaUpdate() +{ + int revnumber = 0; + + URL_List URLs("http://code.google.com/p/usbloader-gui/downloads/list"); + + int urlcount = URLs.GetURLCount(); + + for(int i = 0; i < urlcount; i++) + { + char *tmp = URLs.GetURL(i); + if(tmp) + { + char *fileext = strrchr(tmp, '.'); + if(fileext) + { + if(strcasecmp(fileext, ".dol") == 0 || strcasecmp(fileext, ".wad") == 0) + { + char *DownloadLink = (char *) malloc(strlen(tmp)+1); + sprintf(DownloadLink, "%s", tmp); + + int rev = 0; + char revtxt[80]; + char *filename = strrchr(DownloadLink, '/')+2; + u8 n = 0; + for (n = 0; n < strlen(filename)-2; n++) + revtxt[n] = filename[n]; + revtxt[n] = 0; + rev = atoi(revtxt); + + if(rev > revnumber) { + revnumber = rev; + } + if(DownloadLink) + free(DownloadLink); + DownloadLink = NULL; + } + } + } + } + + return revnumber; +} diff --git a/source/network/update.h b/source/network/update.h new file mode 100644 index 00000000..8283c8cc --- /dev/null +++ b/source/network/update.h @@ -0,0 +1,34 @@ + /*************************************************************************** + * Copyright (C) 2009 + * by Dimok + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any + * damages arising from the use of this software. + * + * Permission is granted to anyone to use this software for any + * purpose, including commercial applications, and to alter it and + * redistribute it freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you + * must not claim that you wrote the original software. If you use + * this software in a product, an acknowledgment in the product + * documentation would be appreciated but is not required. + * + * 2. Altered source versions must be plainly marked as such, and + * must not be misrepresented as being the original software. + * + * 3. This notice may not be removed or altered from any source + * distribution. + * + * update.h + * + * Update operations + * for Wii-Xplorer 2009 + ***************************************************************************/ +#ifndef _UPDATEOPS_H_ +#define _UPDATEOPS_H_ + +int CheckForBetaUpdate(); + +#endif diff --git a/source/prompts/PromptWindows.cpp b/source/prompts/PromptWindows.cpp index b1db8f91..9c235301 100644 --- a/source/prompts/PromptWindows.cpp +++ b/source/prompts/PromptWindows.cpp @@ -63,6 +63,79 @@ extern char game_partition[6]; extern void ResumeGui(); extern void HaltGui(); +/**************************************************************************** + * OnScreenNumpad + * + * Opens an on-screen numpad window, with the data entered being stored + * into the specified variable. + ***************************************************************************/ +int OnScreenNumpad(char * var, u32 maxlen) { + int save = -1; + + GuiNumpad numpad(var, maxlen); + + 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", CFG.theme_path); + GuiImageData btnOutline(imgPath, button_dialogue_box_png); + + GuiTrigger trigA; + trigA.SetSimpleTrigger(-1, WPAD_BUTTON_A | WPAD_CLASSIC_BUTTON_A, PAD_BUTTON_A); + GuiTrigger trigB; + trigB.SetSimpleTrigger(-1, WPAD_BUTTON_B | WPAD_CLASSIC_BUTTON_B, PAD_BUTTON_B); + + GuiText okBtnTxt(tr("OK"), 22, THEME.prompttext); + GuiImage okBtnImg(&btnOutline); + if (Settings.wsprompt == yes) { + okBtnTxt.SetWidescreen(CFG.widescreen); + okBtnImg.SetWidescreen(CFG.widescreen); + } + GuiButton okBtn(&okBtnImg,&okBtnImg, 0, 4, 5, 15, &trigA, &btnSoundOver, btnClick2,1); + okBtn.SetLabel(&okBtnTxt); + GuiText cancelBtnTxt(tr("Cancel"), 22, THEME.prompttext); + GuiImage cancelBtnImg(&btnOutline); + if (Settings.wsprompt == yes) { + cancelBtnTxt.SetWidescreen(CFG.widescreen); + cancelBtnImg.SetWidescreen(CFG.widescreen); + } + GuiButton cancelBtn(&cancelBtnImg,&cancelBtnImg, 1, 4, -5, 15, &trigA, &btnSoundOver, btnClick2,1); + cancelBtn.SetLabel(&cancelBtnTxt); + cancelBtn.SetTrigger(&trigB); + + numpad.Append(&okBtn); + numpad.Append(&cancelBtn); + + HaltGui(); + mainWindow->SetState(STATE_DISABLED); + mainWindow->Append(&numpad); + mainWindow->ChangeFocus(&numpad); + ResumeGui(); + + while (save == -1) { + VIDEO_WaitVSync(); + + if (okBtn.GetState() == STATE_CLICKED) + save = 1; + else if (cancelBtn.GetState() == STATE_CLICKED) + save = 0; + } + + if (save == 1) { + snprintf(var, maxlen, "%s", numpad.kbtextstr); + } + + HaltGui(); + mainWindow->Remove(&numpad); + mainWindow->SetState(STATE_DEFAULT); + ResumeGui(); + gprintf("\t%s",(save == 1?"saved":"discarded")); + return save; +} + /**************************************************************************** * OnScreenKeyboard * @@ -1203,7 +1276,7 @@ int GameWindowPrompt() { promptWindow.Append(&diskImg2); promptWindow.Append(&btn1); - + short changed = -1; GuiImageData * diskCover = NULL; GuiImageData * diskCover2 = NULL; @@ -2658,7 +2731,16 @@ int ProgressUpdateWindow() { promptWindow.Append(&progressbarOutlineImg); promptWindow.Append(&prTxt); msgTxt.SetTextf("%s Rev%i wad.", tr("Downloading"), newrev); - s32 filesize = download_request("http://www.techjawa.com/usbloadergx/ULNR.file");//for some reason it didn't download completely when saved as a wad. + s32 filesize; + if (Settings.beta_upgrades) { + char url[255]; + memset(&url, 0, 255); + sprintf((char *) &url, "http://usbloader-gui.googlecode.com/files/r%d.wad", newrev); + filesize = download_request((char *) &url); + } else { + filesize = download_request("http://www.techjawa.com/usbloadergx/ULNR.file");//for some reason it didn't download completely when saved as a wad. + } + if (filesize > 0) { pfile = fopen(dolpath, "wb");//here we save the txt as a wad @@ -2941,7 +3023,16 @@ int ProgressUpdateWindow() { promptWindow.Append(&progressbarOutlineImg); promptWindow.Append(&prTxt); msgTxt.SetTextf("%s Rev%i", tr("Update to"), newrev); - s32 filesize = download_request("http://www.techjawa.com/usbloadergx/boot.dol"); + + s32 filesize; + if (Settings.beta_upgrades) { + char url[255]; + memset(&url, 0, 255); + sprintf((char *) &url, "http://usbloader-gui.googlecode.com/files/r%d.dol", newrev); + filesize = download_request((char *) &url); + } else { + filesize = download_request("http://www.techjawa.com/usbloadergx/boot.dol"); + } if (filesize > 0) { FILE * pfile; pfile = fopen(dolpath, "wb"); diff --git a/source/prompts/PromptWindows.h b/source/prompts/PromptWindows.h index 3620412d..fea4acfb 100644 --- a/source/prompts/PromptWindows.h +++ b/source/prompts/PromptWindows.h @@ -16,6 +16,7 @@ int WindowPrompt(const char *title, const char *msg = NULL, const char *btn1Labe void WindowCredits(); int OnScreenKeyboard(char * var, u32 maxlen, int min); +int OnScreenNumpad(char * var, u32 maxlen); int WindowExitPrompt(); int GameWindowPrompt(); int DiscWait(const char *title, const char *msg, const char *btn1Label, const char *btn2Label, int IsDeviceWait); diff --git a/source/settings/Settings.cpp b/source/settings/Settings.cpp index 3d065f89..7fcefc63 100644 --- a/source/settings/Settings.cpp +++ b/source/settings/Settings.cpp @@ -49,6 +49,7 @@ static const char *opts_language[settings_language_max] = {trNOOP("Console Defau static const char *opts_cios[settings_ios_max] = {"IOS 249","IOS 222", "IOS 223", "IOS 250"}; static const char *opts_parentalcontrol[5] = {trNOOP("0 (Everyone)"),trNOOP("1 (Child 7+)"),trNOOP("2 (Teen 12+)"),trNOOP("3 (Mature 16+)"),trNOOP("4 (Adults Only 18+)")}; static const char *opts_error002[settings_error002_max] = {trNOOP("No"),trNOOP("Yes"),trNOOP("Anti")}; +static const char *opts_partitions[settings_partitions_max] = {trNOOP("Game partition"),trNOOP("All partitions")}; bool IsValidPartition(int fs_type, int cios) { if (cios == 249 || cios == 250) { @@ -840,6 +841,14 @@ int MenuSettings() options2.SetValue(Idx,"%s",tr(opts_off_on[Settings.autonetwork])); } + if(ret == ++Idx || firstRun) + { + if(firstRun) options2.SetName(Idx, "%s", tr("BETA revisions")); + if(ret == Idx && ++Settings.beta_upgrades >= settings_off_on_max) + Settings.beta_upgrades = 0; + options2.SetValue(Idx,"%s",tr(opts_off_on[Settings.beta_upgrades])); + } + if(ret == ++Idx || firstRun) { if(firstRun) options2.SetName(Idx, "%s",tr("Titles from WiiTDB")); @@ -1048,6 +1057,23 @@ int MenuSettings() options2.SetValue(Idx,"%s",tr(opts_error002[Settings.error002])); } + if(ret == ++Idx || firstRun) + { + if(firstRun) options2.SetName(Idx, "%s",tr("Install partitions")); + if(ret == Idx && ++Settings.partitions_to_install >= settings_partitions_max) + Settings.partitions_to_install = 0; + options2.SetValue(Idx,"%s",tr(opts_partitions[Settings.partitions_to_install])); + } + + if(ret == ++Idx || firstRun) + { + if(firstRun) options2.SetName(Idx, "%s",tr("Install 1:1 Copy")); + if(ret == Idx) { + Settings.fullcopy = Settings.fullcopy == 0 ? 1 : 0; + } + options2.SetValue(Idx,"%s",tr(opts_no_yes[Settings.fullcopy])); + } + firstRun = false; } } diff --git a/source/settings/cfg.c b/source/settings/cfg.c index 5c4cc6db..5e8e6cb9 100644 --- a/source/settings/cfg.c +++ b/source/settings/cfg.c @@ -268,55 +268,61 @@ void CFG_Default(int widescreen) { // -1 = non forced Mode THEME.pagesize = 9; - THEME.gamelist_favorite_x = CFG.widescreen ? 288 : 260; + THEME.gamelist_favorite_x = CFG.widescreen ? 256 : 220; THEME.gamelist_favorite_y = 13; - THEME.gamelist_search_x = CFG.widescreen ? 320 : 300; + THEME.gamelist_search_x = CFG.widescreen ? 288 : 260; THEME.gamelist_search_y = 13; - THEME.gamelist_abc_x = CFG.widescreen ? 352 : 340; + THEME.gamelist_abc_x = CFG.widescreen ? 320 : 300; THEME.gamelist_abc_y = 13; - THEME.gamelist_count_x = CFG.widescreen ? 384 : 380; + THEME.gamelist_count_x = CFG.widescreen ? 352 : 340; THEME.gamelist_count_y = 13; - THEME.gamelist_list_x = CFG.widescreen ? 416 : 420; + THEME.gamelist_list_x = CFG.widescreen ? 384 : 380; THEME.gamelist_list_y = 13; - THEME.gamelist_grid_x = CFG.widescreen ? 448 : 460; + THEME.gamelist_grid_x = CFG.widescreen ? 416 : 420; THEME.gamelist_grid_y = 13; - THEME.gamelist_carousel_x = CFG.widescreen ? 480 : 500; + THEME.gamelist_carousel_x = CFG.widescreen ? 448 : 460; THEME.gamelist_carousel_y = 13; + THEME.gamelist_lock_x = CFG.widescreen ? 480 : 500; + THEME.gamelist_lock_y = 13; THEME.gamelist_dvd_x = CFG.widescreen ? 512 : 540; THEME.gamelist_dvd_y = 13; - THEME.gamegrid_favorite_x = CFG.widescreen ? 208 : 180; + THEME.gamegrid_favorite_x = CFG.widescreen ? 192 : 160; THEME.gamegrid_favorite_y = 13; - THEME.gamegrid_search_x = CFG.widescreen ? 240 : 220; + THEME.gamegrid_search_x = CFG.widescreen ? 224 : 200; THEME.gamegrid_search_y = 13; - THEME.gamegrid_abc_x = CFG.widescreen ? 272 : 260; + THEME.gamegrid_abc_x = CFG.widescreen ? 256 : 240; THEME.gamegrid_abc_y = 13; - THEME.gamegrid_count_x = CFG.widescreen ? 304 : 300; + THEME.gamegrid_count_x = CFG.widescreen ? 288 : 280; THEME.gamegrid_count_y = 13; - THEME.gamegrid_list_x = CFG.widescreen ? 336 : 340; + THEME.gamegrid_list_x = CFG.widescreen ? 320 : 320; THEME.gamegrid_list_y = 13; - THEME.gamegrid_grid_x = CFG.widescreen ? 368 : 380; + THEME.gamegrid_grid_x = CFG.widescreen ? 352 : 360; THEME.gamegrid_grid_y = 13; - THEME.gamegrid_carousel_x = CFG.widescreen ? 400 : 420; + THEME.gamegrid_carousel_x = CFG.widescreen ? 384 : 400; THEME.gamegrid_carousel_y = 13; - THEME.gamegrid_dvd_x = CFG.widescreen ? 432 : 460; + THEME.gamegrid_lock_x = CFG.widescreen ? 416 : 440; + THEME.gamegrid_lock_y = 13; + THEME.gamegrid_dvd_x = CFG.widescreen ? 448 : 480; THEME.gamegrid_dvd_y = 13; - THEME.gamecarousel_favorite_x = CFG.widescreen ? 208 : 180; + THEME.gamecarousel_favorite_x = CFG.widescreen ? 192 : 160; THEME.gamecarousel_favorite_y = 13; - THEME.gamecarousel_search_x = CFG.widescreen ? 240 : 220; + THEME.gamecarousel_search_x = CFG.widescreen ? 224 : 200; THEME.gamecarousel_search_y = 13; - THEME.gamecarousel_abc_x = CFG.widescreen ? 272 : 260; + THEME.gamecarousel_abc_x = CFG.widescreen ? 256 : 240; THEME.gamecarousel_abc_y = 13; - THEME.gamecarousel_count_x = CFG.widescreen ? 304 : 300; + THEME.gamecarousel_count_x = CFG.widescreen ? 288 : 280; THEME.gamecarousel_count_y = 13; - THEME.gamecarousel_list_x = CFG.widescreen ? 336 : 340; + THEME.gamecarousel_list_x = CFG.widescreen ? 320 : 320; THEME.gamecarousel_list_y = 13; - THEME.gamecarousel_grid_x = CFG.widescreen ? 368 : 380; + THEME.gamecarousel_grid_x = CFG.widescreen ? 352 : 360; THEME.gamecarousel_grid_y = 13; - THEME.gamecarousel_carousel_x = CFG.widescreen ? 400 : 420; + THEME.gamecarousel_carousel_x = CFG.widescreen ? 384 : 400; THEME.gamecarousel_carousel_y = 13; - THEME.gamecarousel_dvd_x = CFG.widescreen ? 432 : 460; + THEME.gamecarousel_lock_x = CFG.widescreen ? 416 : 440; + THEME.gamecarousel_lock_y = 13; + THEME.gamecarousel_dvd_x = CFG.widescreen ? 448 : 480; THEME.gamecarousel_dvd_y = 13; } @@ -357,6 +363,27 @@ void Global_Default(void) { Settings.partition = -1; Settings.marknewtitles = 1; Settings.FatInstallToDir = 0; + Settings.partitions_to_install = install_game_only; + Settings.fullcopy = 0; + Settings.beta_upgrades = 0; + + memset(&Settings.parental, 0, sizeof(struct SParental)); + + char buf[0x4a]; + CONF_Init(); + s32 res = CONF_Get("IPL.PC", buf, 0x4A); + if (res > 0) { + if (buf[2] != 0x14) { + Settings.parental.enabled = 1; + Settings.parental.rating = buf[2]; + } + Settings.parental.question = buf[7]; + memcpy(Settings.parental.pin, buf + 3, 4); + memcpy(Settings.parental.answer, buf + 8, 32); + } + if (Settings.parental.enabled == 0) { + Settings.parental.is_unlocked = 1; + } } @@ -419,6 +446,16 @@ u8 get_block(struct discHdr *header) { return cfg_get_block(header->id); } +s8 get_pegi_block(struct discHdr *header) { + switch(get_block(header)) { + case 1: return 7; + case 2: return 12; + case 3: return 16; + case 4: return 18; + default: return -1; + } +} + // trim leading and trailing whitespace // copy at max n or at max size-1 char* trim_n_copy(char *dest, char *src, int n, int size) { @@ -698,6 +735,10 @@ void theme_set(char *name, char *val) { else CFG_COORDS2(gamegrid_carousel) else CFG_COORDS2(gamecarousel_carousel) + else CFG_COORDS2(gamelist_lock) + else CFG_COORDS2(gamegrid_lock) + else CFG_COORDS2(gamecarousel_lock) + else CFG_COORDS2(gamelist_dvd) else CFG_COORDS2(gamegrid_dvd) else CFG_COORDS2(gamecarousel_dvd) @@ -804,6 +845,11 @@ void theme_set(char *name, char *val) { // old themes have no dvd_coords // place the dvdIcon to the right side of the carouselIcon if(!CFG.widescreen) x+= CFG.widescreen ? 32 : 40; + THEME.gamelist_lock_x = x; + THEME.gamegrid_lock_x = THEME.gamecarousel_lock_x = x-WorkAroundBarOffset; + THEME.gamelist_lock_y = THEME.gamegrid_lock_y = THEME.gamecarousel_lock_y = y; + + x+= CFG.widescreen ? 32 : 40; THEME.gamelist_dvd_x = x; THEME.gamegrid_dvd_x = THEME.gamecarousel_dvd_x = x-WorkAroundBarOffset; THEME.gamelist_dvd_y = THEME.gamegrid_dvd_y = THEME.gamecarousel_dvd_y = y; @@ -844,6 +890,8 @@ void theme_set(char *name, char *val) { { THEME.gamegrid_carousel_x += WorkAroundBarOffset - o; THEME.gamecarousel_carousel_x += WorkAroundBarOffset - o; + THEME.gamegrid_lock_x += WorkAroundBarOffset - o; + THEME.gamecarousel_lock_x += WorkAroundBarOffset - o; THEME.gamegrid_dvd_x += WorkAroundBarOffset - o; THEME.gamecarousel_dvd_x += WorkAroundBarOffset - o; } @@ -1060,6 +1108,21 @@ void global_cfg_set(char *name, char *val) { if (sscanf(val, "%d", &i) == 1) { Settings.FatInstallToDir = i; } + } else if (strcmp(name, "partitions") == 0) { + int i; + if (sscanf(val, "%d", &i) == 1) { + Settings.partitions_to_install = i; + } + } else if (strcmp(name, "fullcopy") == 0) { + int i; + if (sscanf(val, "%d", &i) == 1) { + Settings.fullcopy = i; + } + } else if (strcmp(name, "beta_upgrades") == 0) { + int i; + if (sscanf(val, "%d", &i) == 1) { + Settings.beta_upgrades = i; + } } cfg_bool("godmode", &Settings.godmode); @@ -1307,6 +1370,9 @@ bool cfg_save_global() { // save global settings fprintf(f, "partition = %d\n", Settings.partition); fprintf(f, "marknewtitles = %d\n", Settings.marknewtitles); fprintf(f, "fatInstallToDir = %d\n", Settings.FatInstallToDir); + fprintf(f, "partitions = %d\n", Settings.partitions_to_install); + fprintf(f, "fullcopy = %d\n", Settings.fullcopy); + fprintf(f, "beta_upgrades = %d\n", Settings.beta_upgrades); fclose(f); return true; } diff --git a/source/settings/cfg.h b/source/settings/cfg.h index 67e9652d..66fa399d 100644 --- a/source/settings/cfg.h +++ b/source/settings/cfg.h @@ -145,6 +145,8 @@ extern "C" { short gamelist_carousel_y; short gamelist_dvd_x; short gamelist_dvd_y; + short gamelist_lock_x; + short gamelist_lock_y; // Toolbar Icons in GameGrid short gamegrid_favorite_x; short gamegrid_favorite_y; @@ -162,6 +164,8 @@ extern "C" { short gamegrid_carousel_y; short gamegrid_dvd_x; short gamegrid_dvd_y; + short gamegrid_lock_x; + short gamegrid_lock_y; // Toolbar Icons in GameCarousel short gamecarousel_favorite_x; short gamecarousel_favorite_y; @@ -179,7 +183,8 @@ extern "C" { short gamecarousel_carousel_y; short gamecarousel_dvd_x; short gamecarousel_dvd_y; - + short gamecarousel_lock_x; + short gamecarousel_lock_y; }; extern struct CFG CFG; @@ -370,6 +375,19 @@ extern "C" { scrollMarquee, settings_scrolleffect_max // always the last entry }; + enum { + install_game_only, + install_all, + settings_partitions_max // always the last entry + }; + struct SParental { + u8 enabled; + u8 rating; + u8 pin[4]; + u8 question; + wchar_t answer[32]; // IS WCHAR! + u8 is_unlocked; + }; struct SSettings { u8 video; u8 language; @@ -427,6 +445,10 @@ extern "C" { u8 marknewtitles; char BcaCodepath[100]; u8 FatInstallToDir; + u8 partitions_to_install; + u8 fullcopy; + u8 beta_upgrades; + struct SParental parental; }; extern struct SSettings Settings; @@ -441,6 +463,7 @@ extern "C" { void title_set(char *id, char *title); void titles_default(); u8 get_block(struct discHdr *header); + s8 get_pegi_block(struct discHdr *header); void CFG_Cleanup(void); diff --git a/source/settings/newtitles.cpp b/source/settings/newtitles.cpp index ec4f4dc8..d1ca11dc 100644 --- a/source/settings/newtitles.cpp +++ b/source/settings/newtitles.cpp @@ -80,6 +80,10 @@ NewTitles::~NewTitles() void NewTitles::CheckGame(u8 *titleid) { + if (titleid == NULL || strlen((char *) titleid) == 0) { + return; + } + Title *t = firstTitle; while (t != NULL) { // Loop all titles, search for the correct titleid @@ -109,6 +113,10 @@ void NewTitles::CheckGame(u8 *titleid) bool NewTitles::IsNew(u8 *titleid) { + if (titleid == NULL || strlen((char *) titleid) == 0) { + return false; + } + Title *t = firstTitle; while (t != NULL) { @@ -162,7 +170,7 @@ void NewTitles::Save() FILE *fp = fopen(path, "w"); if (fp != NULL) { Title *t = firstTitle; - while (t != NULL) { + while (t != NULL && strlen((char *) t->titleId) > 0) { fprintf(fp, "%s:%ld\n", t->titleId, t->timestamp); t = (Title *) t->next; } diff --git a/source/usbloader/getentries.cpp b/source/usbloader/getentries.cpp index 0b6ab246..12ca5d0e 100644 --- a/source/usbloader/getentries.cpp +++ b/source/usbloader/getentries.cpp @@ -177,6 +177,19 @@ int __Menu_GetPrevFilter(int t, wchar_t* gameFilter, u32 gameFiltered, wchar_t * if(get_block(header) >= Settings.parentalcontrol) continue; + /* Other parental control method */ + if (Settings.parentalcontrol == 0 && Settings.parental.is_unlocked == 0 && Settings.parental.enabled == 1) + { + // Check game rating in WiiTDB, since the default Wii parental control setting is enabled + s32 rating = GetRatingForGame((char *) header->id); + + if ((rating != -1 && rating > Settings.parental.rating) || + (rating == -1 && get_pegi_block(header) > Settings.parental.rating)) + { + continue; + } + } + wchar_t *wname = FreeTypeGX::charToWideChar(get_title(header)); if(wname) nameList.push_back(wname); } @@ -492,6 +505,18 @@ int __Menu_GetGameList(int t, wchar_t* gameFilter, discHdr ** PgameList, u32 *Pg if (get_block(header) >= Settings.parentalcontrol) continue; } + + /* Other parental control method */ + if (Settings.parentalcontrol == 0 && Settings.parental.is_unlocked == 0 && Settings.parental.enabled == 1) + { + // Check game rating in WiiTDB, since the default Wii parental control setting is enabled + s32 rating = GetRatingForGame((char *) header->id); + if ((rating != -1 && rating > Settings.parental.rating) || + (rating == -1 && get_pegi_block(header) > Settings.parental.rating)) + { + continue; + } + } if(gameFilter && *gameFilter && t==0) { u32 filter_len = wcslen(gameFilter); diff --git a/source/usbloader/wbfs.c b/source/usbloader/wbfs.c index 2dbecc80..85b5a9a8 100644 --- a/source/usbloader/wbfs.c +++ b/source/usbloader/wbfs.c @@ -13,6 +13,7 @@ #include "wbfs_fat.h" #include "fatmounter.h" #include "partition_usbloader.h" +#include "settings/cfg.h" #include "libwbfs/libwbfs.h" @@ -482,7 +483,17 @@ s32 WBFS_AddGame(void) { return -1; /* Add game to device */ - ret = wbfs_add_disc(hdd, __WBFS_ReadDVD, NULL, WBFS_Spinner, ONLY_GAME_PARTITION, 0); + partition_selector_t part_sel; + int copy_1_1 = 0; + + if (Settings.fullcopy) { + part_sel = ALL_PARTITIONS; + copy_1_1 = 1; + } else { + part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS; + } + + ret = wbfs_add_disc(hdd, __WBFS_ReadDVD, NULL, WBFS_Spinner, part_sel, copy_1_1); if (ret < 0) return ret; @@ -596,5 +607,11 @@ f32 WBFS_EstimeGameSize(void) { return comp; } - return wbfs_estimate_disc(hdd, __WBFS_ReadDVD, NULL, ONLY_GAME_PARTITION); + partition_selector_t part_sel; + if (Settings.fullcopy) { + part_sel = ALL_PARTITIONS; + } else { + part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS; + } + return wbfs_estimate_disc(hdd, __WBFS_ReadDVD, NULL, part_sel); } diff --git a/source/usbloader/wbfs_fat.c b/source/usbloader/wbfs_fat.c index 8e638fb1..6cf6f0a0 100644 --- a/source/usbloader/wbfs_fat.c +++ b/source/usbloader/wbfs_fat.c @@ -1,3 +1,5 @@ +// WBFS FAT by oggzee + #include #include #include @@ -19,15 +21,10 @@ #include "splits.h" #include "fat.h" #include "partition_usbloader.h" +#include "settings/cfg.h" #include "wpad.h" #include "wbfs_fat.h" -#include "disc.h" -#include "settings/cfg.h" - -// WBFS FAT by oggzee - -// max fat fname = 256 #define MAX_FAT_PATH 1024 #define D_S(A) A, sizeof(A) @@ -42,104 +39,103 @@ split_info_t split; static u32 fat_sector_size = 512; +static struct discHdr *fat_hdr_list = NULL; +static int fat_hdr_count = 0; + 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) +bool is_gameid(char *id) { - DIR *dir; - struct dirent *dent; - char *p; - int ret, cnt = 0; + int i; + for (i=0; i<6; i++) { + if (!isalnum(id[i])) return false; + } + return true; +} + +s32 _WBFS_FAT_GetHeadersCount() +{ + DIR_ITER *dir_iter; char path[MAX_FAT_PATH]; - wbfs_t *part = NULL; - u32 size; - u8 *ptr; + char fname[MAX_FAT_PATH]; + char fpath[MAX_FAT_PATH]; struct discHdr tmpHdr; - int hdrsize; struct stat st; + wbfs_t *part = NULL; u8 id[8]; + int ret; + char *p; + u32 size; int is_dir; + //dbg_time1(); + if(fat_hdr_list){ + free(fat_hdr_list); + fat_hdr_list=NULL; + } + + fat_hdr_count = 0; + strcpy(path, wbfs_fat_drive); strcat(path, wbfs_fat_dir); - dir = opendir(path); - //printf("opendir: %s %p\n", path, dir); Wpad_WaitButtons(); - if (!dir) { - *count = 0; - return 0; - } - while ((dent = readdir(dir)) != NULL) { - //printf("found: %s\n", dent->d_name); - if (outbuf && cnt >= *count) break; - if ((char)dent->d_name[0] == '.') continue; - if (strlen(dent->d_name) < 8) continue; // "GAMEID_x" + dir_iter = diropen(path); + if (!dir_iter) return 0; + + while (dirnext(dir_iter, fname, &st) == 0) { + if ((char)fname[0] == '.') continue; + if (strlen(fname) < 8) continue; // "GAMEID_x" - memcpy(id, dent->d_name, 6); + memcpy(id, fname, 6); id[6] = 0; - strcpy(path, wbfs_fat_drive); - strcat(path, wbfs_fat_dir); - strcat(path, "/"); - strcat(path, dent->d_name); - stat(path, &st); - is_dir = S_ISDIR(st.st_mode); - //printf("path: %s %d\n", path, is_dir); if (is_dir) { // usb:/wbfs/GAMEID_TITLE/GAMEID.wbfs - if (dent->d_name[6] != '_') continue; - strcat(path, "/"); - strcat(path, (char*)id); - strcat(path, ".wbfs"); - //printf("path2: %s\n", path); - if (stat(path, &st) == -1) continue; + if (fname[6] != '_') continue; + snprintf(fpath, sizeof(fpath), "%s/%s/%s.wbfs", path, fname, id); + // if more than 50 games, skip second stat to improve speed + if (fat_hdr_count < 50) { + do_stat2: + if (stat(fpath, &st) == -1) continue; + } else { + // just check if gameid is valid (alphanum) + if (!is_gameid((char*)id)) goto do_stat2; + st.st_size = 1024*1024; + } } else { // usb:/wbfs/GAMEID.wbfs - p = strrchr(dent->d_name, '.'); + p = strrchr(fname, '.'); if (!p) continue; if (strcasecmp(p, ".wbfs") != 0) continue; - if (strlen(dent->d_name) != 11) continue; // GAMEID.wbfs + if (strlen(fname) != 11) continue; // GAMEID.wbfs } - //printf("found: %s %d MB\n", path, (int)(st.st_size/1024/1024)); // 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; // if we have titles.txt entry use that char *title = cfg_get_title(id); // if directory, and no titles.txt get title from dir name if (!title && is_dir) { - title = &dent->d_name[7]; + title = &fname[7]; } if (title) { memset(&tmpHdr, 0, sizeof(tmpHdr)); memcpy(tmpHdr.id, id, 6); strncpy(tmpHdr.title, title, sizeof(tmpHdr.title)-1); tmpHdr.magic = 0x5D1C9EA3; - memcpy(ptr, &tmpHdr, hdrsize); - cnt++; - continue; + goto add_hdr; } // else read it from wbfs file directly - FILE *fp = fopen(path, "rb"); + FILE *fp = fopen(fpath, "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; + goto add_hdr; } } // no title found, read it from wbfs file @@ -147,19 +143,19 @@ s32 _WBFS_FAT_GetHeadersCount(void *outbuf, u32 *count, u32 len) // open 'partition' file part = WBFS_FAT_OpenPart(id); if (!part) { - printf("bad wbfs file: %s\n", dent->d_name); - sleep(2); continue; } /* Get header */ - ret = wbfs_get_disc_info(part, 0, ptr, hdrsize, &size); - if (ret == 0) cnt++; + ret = wbfs_get_disc_info(part, 0, (u8*)&tmpHdr, sizeof(struct discHdr), &size); WBFS_FAT_ClosePart(part); + if (ret) continue; + // add tmpHdr to list: + add_hdr: + fat_hdr_count++; + fat_hdr_list = realloc(fat_hdr_list, fat_hdr_count * sizeof(struct discHdr)); + memcpy(&fat_hdr_list[fat_hdr_count-1], &tmpHdr, sizeof(struct discHdr)); } - *count = cnt; - closedir(dir); - //dbg_time2("\nFAT HDRS"); - //Wpad_WaitButtonsCommon(); + dirclose(dir_iter); return 0; } @@ -167,13 +163,38 @@ s32 _WBFS_FAT_GetHeadersCount(void *outbuf, u32 *count, u32 len) s32 WBFS_FAT_GetCount(u32 *count) { *count = 0; - _WBFS_FAT_GetHeadersCount(NULL, count, 0); + _WBFS_FAT_GetHeadersCount(); + if (fat_hdr_count && fat_hdr_list) { + // for compacter mem - move up as it will be freed later + int size = fat_hdr_count * sizeof(struct discHdr); + struct discHdr *buf = malloc(size); + if (buf) { + memcpy(buf, fat_hdr_list, size); + if (fat_hdr_list) { + free(fat_hdr_list); + } + fat_hdr_list = buf; + } + } + *count = fat_hdr_count; return 0; } s32 WBFS_FAT_GetHeaders(void *outbuf, u32 cnt, u32 len) { - _WBFS_FAT_GetHeadersCount(outbuf, &cnt, len); + int i; + int slen = len; + if (slen > sizeof(struct discHdr)) { + slen = sizeof(struct discHdr); + } + for (i=0; iid, get_title(header)); - fclose(f); - printf("Info file: %s\n", fname); -} - - int WBFS_FAT_find_fname(u8 *id, char *fname, int len) { struct stat st; WBFS_FAT_fname(id, fname, len, NULL); if (stat(fname, &st) == 0) return 1; // direct file not found, check subdirs - DIR *dir; - struct dirent *dent; + DIR_ITER *dir_iter; char path[MAX_FAT_PATH]; + char name[MAX_FAT_PATH]; strcpy(path, wbfs_fat_drive); strcat(path, wbfs_fat_dir); - dir = opendir(path); - //printf("opendir: %s %p\n", path, dir); Wpad_WaitButtons(); - if (!dir) { + dir_iter = diropen(path); + if (!dir_iter) { goto err; } - while ((dent = readdir(dir)) != NULL) { - char *name = (char*)dent->d_name; + while (dirnext(dir_iter, name, &st) == 0) { if (name[0] == '.') continue; if (name[6] != '_') continue; if (strncmp(name, (char*)id, 6) != 0) continue; if (strlen(name) < 8) continue; snprintf(fname, len, "%s/%s/%.6s.wbfs", path, name, id); if (stat(fname, &st) == 0) { - closedir(dir); + dirclose(dir_iter); return 2; } } - closedir(dir); + dirclose(dir_iter); // not found err: *fname = 0; @@ -350,12 +349,10 @@ wbfs_t* WBFS_FAT_CreatePart(u8 *id, char *path) u32 n_sector = size / 512; int ret; - //printf("CREATE PART %s %lld %d\n", id, size, n_sector); snprintf(D_S(fname), "%s%s", wbfs_fat_drive, wbfs_fat_dir); mkdir(fname, 0777); // base usb:/wbfs mkdir(path, 0777); // game subdir WBFS_FAT_fname(id, fname, sizeof(fname), path); - printf("Writing to %s\n", fname); ret = split_create(&split, fname, OPT_split_size, size, true); if (ret) return NULL; @@ -363,8 +360,6 @@ wbfs_t* WBFS_FAT_CreatePart(u8 *id, char *path) u32 scnt = 0; int fd = split_get_file(&split, 0, &scnt, 0); if (fd<0) { - printf("ERROR creating file\n"); - sleep(2); split_close(&split); return NULL; } @@ -400,16 +395,16 @@ s32 WBFS_FAT_RemoveGame(u8 *discid) // game is in subdir // remove optional .txt file - DIR *dir; - struct dirent *dent; + DIR_ITER *dir_iter; + struct stat st; char path[MAX_FAT_PATH]; + char name[MAX_FAT_PATH]; strncpy(path, fname, sizeof(path)); - char *p= strrchr(path, '/'); + char *p = strrchr(path, '/'); if (p) *p = 0; - dir = opendir(path); - if (!dir) return 0; - while ((dent = readdir(dir)) != NULL) { - char *name = (char*)dent->d_name; + dir_iter = diropen(path); + if (!dir_iter) return 0; + while (dirnext(dir_iter, name, &st) == 0) { if (name[0] == '.') continue; if (name[6] != '_') continue; if (strncmp(name, (char*)discid, 6) != 0) continue; @@ -420,10 +415,11 @@ s32 WBFS_FAT_RemoveGame(u8 *discid) remove(fname); break; } - closedir(dir); + dirclose(dir_iter); // remove game subdir //rmdir(path); if (unlink(path) == -1) { + return -1; } return 0; @@ -445,22 +441,16 @@ s32 WBFS_FAT_AddGame(void) part = WBFS_FAT_CreatePart(header.id, path); if (!part) return -1; /* Add game to device */ - partition_selector_t part_sel = ONLY_GAME_PARTITION; + partition_selector_t part_sel; int copy_1_1 = 0; -/* - switch (CFG.install_partitions) { - case CFG_INSTALL_GAME: - part_sel = ONLY_GAME_PARTITION; - break; - case CFG_INSTALL_ALL: - part_sel = ALL_PARTITIONS; - break; - case CFG_INSTALL_1_1: - part_sel = ALL_PARTITIONS; - copy_1_1 = 1; - break; + + if (Settings.fullcopy) { + part_sel = ALL_PARTITIONS; + copy_1_1 = 1; + } else { + part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS; } -*/ + extern wbfs_t *hdd; wbfs_t *old_hdd = hdd; hdd = part; // used by spinner @@ -468,8 +458,10 @@ s32 WBFS_FAT_AddGame(void) hdd = old_hdd; wbfs_trim(part); WBFS_FAT_ClosePart(part); + if (ret) { + return -1; + } if (ret < 0) return ret; - mk_title_txt(&header, path); return 0; } @@ -493,14 +485,13 @@ s32 WBFS_FAT_DVD_Size(u64 *comp_size, u64 *real_size) wii_sec_sz = part->wii_sec_sz; /* Add game to device */ - partition_selector_t part_sel = ONLY_GAME_PARTITION; -/* - if (CFG.install_partitions) { + partition_selector_t part_sel; + if (Settings.fullcopy) { part_sel = ALL_PARTITIONS; } else { - part_sel = ONLY_GAME_PARTITION; + part_sel = Settings.partitions_to_install == install_game_only ? ONLY_GAME_PARTITION : ALL_PARTITIONS; } -*/ + ret = wbfs_size_disc(part, __WBFS_ReadDVD, NULL, part_sel, &comp_sec, &last_sec); wbfs_close(part); if (ret < 0) @@ -558,4 +549,3 @@ s32 WBFS_FAT_ReIDGame(u8 *discid, const void *newID) return ret; } - diff --git a/source/xml/xml.c b/source/xml/xml.c index 471f631e..6c57ce6a 100644 --- a/source/xml/xml.c +++ b/source/xml/xml.c @@ -746,4 +746,37 @@ static char * get_text(mxml_node_t *node, char *buffer, int buflen) { /* O - Tex return (buffer); } +int GetRatingForGame(char *gameid) +{ + int retval=-1; + if (!xml_loaded || nodedata == NULL) + return -1; + /* index all IDs */ + nodeindex = mxmlIndexNew(nodedata,"id", NULL); + nodeid = mxmlIndexReset(nodeindex); + *element_text = 0; + /* search for game matching gameid */ + while (1) { + nodeid = mxmlIndexFind(nodeindex,"id", NULL); + if (nodeid != NULL) { + get_text(nodeid, element_text, sizeof(element_text)); + if (!strcmp(element_text,gameid)) { + break; + } + } else { + break; + } + } + + if (!strcmp(element_text,gameid)) { + char type[5], value[5], dest[5]; + + GetTextFromNode(nodeid, nodedata, "rating", "type", NULL, MXML_NO_DESCEND, type, sizeof(type)); + GetTextFromNode(nodeid, nodedata, "rating", "value", NULL, MXML_NO_DESCEND, value, sizeof(value)); + ConvertRating(value, type, "PEGI", dest, sizeof(dest)); + + retval = atoi(dest); + } + return retval; +} diff --git a/source/xml/xml.h b/source/xml/xml.h index a568f8fa..ba970881 100644 --- a/source/xml/xml.h +++ b/source/xml/xml.h @@ -65,6 +65,8 @@ extern "C" { char *MemInfo(); void GetTextFromNode(mxml_node_t *currentnode, mxml_node_t *topnode, char *nodename, char *attributename, char *value, int descend, char *dest, int destsize); + int GetRatingForGame(char *gameid); + #ifdef __cplusplus } #endif