diff --git a/HBC/META.XML b/HBC/META.XML index 9d8c76f4..475045b4 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,8 +2,8 @@ USB Loader GX USB Loader GX Team - 1.0 r948 - 201009172243 + 1.0 r949 + 201009180855 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 94a1d5be..cfe7df13 100644 --- a/gui.pnproj +++ b/gui.pnproj @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/source/libwiigui/gui_gamebrowser.cpp b/source/libwiigui/gui_gamebrowser.cpp index 62ac1304..1d66fe67 100644 --- a/source/libwiigui/gui_gamebrowser.cpp +++ b/source/libwiigui/gui_gamebrowser.cpp @@ -14,6 +14,7 @@ #include "../settings/cfg.h" #include "../main.h" #include "settings/newtitles.h" +#include "usbloader/GameList.h" #include #include @@ -23,16 +24,14 @@ int txtscroll = 0; /** * Constructor for the GuiGameBrowser class. */ -GuiGameBrowser::GuiGameBrowser(int w, int h, struct discHdr * l, int gameCnt, const char *themePath, const u8 *imagebg, int selected, int offset) +GuiGameBrowser::GuiGameBrowser(int w, int h, const char *themePath, const u8 *imagebg, int selected, int offset) { width = w; height = h; - this->gameCnt = gameCnt; - gameList = l; pagesize = THEME.pagesize; - scrollbaron = (gameCnt > pagesize) ? 1 : 0; + scrollbaron = (gameList.size() > pagesize) ? 1 : 0; selectable = true; - listOffset = MAX(0,MIN(offset,(gameCnt-pagesize))); + listOffset = MAX(0,MIN(offset,(gameList.size()-pagesize))); selectedItem = selected - offset; focus = 1; // allow focus char imgPath[100]; @@ -129,13 +128,13 @@ GuiGameBrowser::GuiGameBrowser(int w, int h, struct discHdr * l, int gameCnt, co for(int i=0; i < pagesize; i++) { - gameTxt[i] = new GuiText(get_title(&gameList[i]), 20, THEME.gametext); + gameTxt[i] = new GuiText(get_title(gameList[i]), 20, THEME.gametext); gameTxt[i]->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); gameTxt[i]->SetPosition(24,0); gameTxt[i]->SetMaxWidth(maxTextWidth, DOTTED); - gameTxtOver[i] = new GuiText(get_title(&gameList[i]), 20, THEME.gametext); + gameTxtOver[i] = new GuiText(get_title(gameList[i]), 20, THEME.gametext); gameTxtOver[i]->SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE); gameTxtOver[i]->SetPosition(24,0); gameTxtOver[i]->SetMaxWidth(maxTextWidth, SCROLL_HORIZONTAL); @@ -211,7 +210,7 @@ GuiGameBrowser::~GuiGameBrowser() void GuiGameBrowser::SetFocus(int f) { LOCK(this); - if(!gameCnt) + if(!gameList.size()) return; focus = f; @@ -282,10 +281,10 @@ int GuiGameBrowser::FindMenuItem(int currentItem, int direction) { int nextItem = currentItem + direction; - if(nextItem < 0 || nextItem >= gameCnt) + if(nextItem < 0 || nextItem >= gameList.size()) return -1; - if(strlen(get_title(&gameList[nextItem])) > 0) + if(strlen(get_title(gameList[nextItem])) > 0) return nextItem; else return FindMenuItem(nextItem, direction); @@ -297,7 +296,7 @@ int GuiGameBrowser::FindMenuItem(int currentItem, int direction) void GuiGameBrowser::Draw() { LOCK(this); - if(!this->IsVisible() || !gameCnt) + if(!this->IsVisible() || !gameList.size()) return; bgGameImg->Draw(); @@ -336,13 +335,13 @@ void GuiGameBrowser::UpdateListEntries() game[i]->SetVisible(true); game[i]->SetState(STATE_DEFAULT); } - gameTxt[i]->SetText(get_title(&gameList[next])); + gameTxt[i]->SetText(get_title(gameList[next])); gameTxt[i]->SetPosition(24, 0); - gameTxtOver[i]->SetText(get_title(&gameList[next])); + gameTxtOver[i]->SetText(get_title(gameList[next])); gameTxtOver[i]->SetPosition(24, 0); if (Settings.marknewtitles) { - bool isNew = NewTitles::Instance()->IsNew(gameList[next].id); + bool isNew = NewTitles::Instance()->IsNew(gameList[next]->id); if (isNew) { gameTxt[i]->SetMaxWidth(maxTextWidth - (newGames->GetWidth() + 1), DOTTED); gameTxtOver[i]->SetMaxWidth(maxTextWidth - (newGames->GetWidth() + 1), SCROLL_HORIZONTAL); @@ -367,7 +366,7 @@ void GuiGameBrowser::UpdateListEntries() void GuiGameBrowser::Update(GuiTrigger * t) { LOCK(this); - if(state == STATE_DISABLED || !t || !gameCnt) + if(state == STATE_DISABLED || !t || !gameList.size()) return; int next, prev; @@ -413,7 +412,7 @@ void GuiGameBrowser::Update(GuiTrigger * t) } // pad and joystick navigation - if(!focus || !gameCnt) + if(!focus || !gameList.size()) return; // skip navigation if (scrollbaron == 1) @@ -527,27 +526,27 @@ void GuiGameBrowser::Update(GuiTrigger * t) position2 = 0; } - if(scrollbarBoxBtn->GetState() == STATE_HELD && scrollbarBoxBtn->GetStateChan() == t->chan && t->wpad.ir.valid && gameCnt > pagesize) + if(scrollbarBoxBtn->GetState() == STATE_HELD && scrollbarBoxBtn->GetStateChan() == t->chan && t->wpad.ir.valid && gameList.size() > pagesize) { // allow dragging of scrollbar box scrollbarBoxBtn->SetPosition(width/2-18+7,0); int position = t->wpad.ir.y - 32 - scrollbarBoxBtn->GetTop(); - listOffset = (position * gameCnt)/(25.2 * pagesize) - selectedItem; + listOffset = (position * gameList.size())/(25.2 * pagesize) - selectedItem; if(listOffset <= 0) { listOffset = 0; selectedItem = 0; } - else if(listOffset+pagesize >= gameCnt) + else if(listOffset+pagesize >= gameList.size()) { - listOffset = gameCnt - pagesize; + listOffset = gameList.size() - pagesize; selectedItem = pagesize-1; } } - int positionbar = (25.2 * pagesize)*(listOffset + selectedItem) / gameCnt; + int positionbar = (25.2 * pagesize)*(listOffset + selectedItem) / gameList.size(); if(positionbar > (24 * pagesize)) positionbar = (24 * pagesize); @@ -556,11 +555,11 @@ void GuiGameBrowser::Update(GuiTrigger * t) if(t->Right()) //skip pagesize # of games if right is pressed { - if(listOffset < gameCnt && gameCnt > pagesize) + if(listOffset < gameList.size() && gameList.size() > pagesize) { listOffset =listOffset+ pagesize; - if(listOffset+pagesize >= gameCnt) - listOffset = gameCnt-pagesize; + if(listOffset+pagesize >= gameList.size()) + listOffset = gameList.size()-pagesize; } } else if(t->Left()) @@ -623,12 +622,10 @@ void GuiGameBrowser::Update(GuiTrigger * t) updateCB(this); } -void GuiGameBrowser::Reload(struct discHdr * l, int count) +void GuiGameBrowser::Reload() { LOCK(this); - gameList = l; - gameCnt = count; - scrollbaron = (gameCnt > pagesize) ? 1 : 0; + scrollbaron = (gameList.size() > pagesize) ? 1 : 0; selectedItem = 0; listOffset = 0; focus = 1; diff --git a/source/libwiigui/gui_gamebrowser.h b/source/libwiigui/gui_gamebrowser.h index 88c71df7..33ab1069 100644 --- a/source/libwiigui/gui_gamebrowser.h +++ b/source/libwiigui/gui_gamebrowser.h @@ -7,7 +7,7 @@ class GuiGameBrowser : public GuiElement { public: - GuiGameBrowser(int w, int h, struct discHdr *l, int gameCnt, const char *themePath, const u8 *imagebg, int selected = 0, int offset = 0); + GuiGameBrowser(int w, int h, const char *themePath, const u8 *imagebg, int selected = 0, int offset = 0); ~GuiGameBrowser(); int FindMenuItem(int c, int d); int GetClickedOption(); @@ -17,7 +17,7 @@ class GuiGameBrowser : public GuiElement void Draw(); void Update(GuiTrigger * t); int GetOffset(); - void Reload(struct discHdr * l, int count); + void Reload(); //GuiText * optionVal[PAGESIZE]; protected: void UpdateListEntries(); @@ -27,9 +27,6 @@ class GuiGameBrowser : public GuiElement int pagesize; int maxTextWidth; - struct discHdr * gameList; - int gameCnt; - int * gameIndex; GuiButton ** game; GuiText ** gameTxt; diff --git a/source/libwiigui/gui_gamecarousel.cpp b/source/libwiigui/gui_gamecarousel.cpp index 4a3ac43b..4439ae75 100644 --- a/source/libwiigui/gui_gamecarousel.cpp +++ b/source/libwiigui/gui_gamecarousel.cpp @@ -13,6 +13,7 @@ #include #include "gui_image_async.h" #include "gui_gamecarousel.h" +#include "usbloader/GameList.h" #include "../settings/cfg.h" #include "../main.h" @@ -41,14 +42,12 @@ static GuiImageData *GameCarouselLoadCoverImage(void * Arg) /** * Constructor for the GuiGameCarousel class. */ -GuiGameCarousel::GuiGameCarousel(int w, int h, struct discHdr * l, int count, const char *themePath, const u8 *imagebg, int selected, int offset) : +GuiGameCarousel::GuiGameCarousel(int w, int h, const char *themePath, const u8 *imagebg, int selected, int offset) : noCover(nocover_png) { width = w; height = h; - gameCnt = count; - gameList = l; - pagesize = (gameCnt < 11) ? gameCnt : 11; + pagesize = (gameList.size() < 11) ? gameList.size() : 11; listOffset = 0; selectable = true; selectedItem = -1; @@ -122,12 +121,12 @@ noCover(nocover_png) //------------------------ // Index //------------------------ - gameIndex[i] = GetGameIndex(i, listOffset, gameCnt); + gameIndex[i] = GetGameIndex(i, listOffset, gameList.size()); //------------------------ // Image //------------------------ - coverImg[i] = new(std::nothrow) GuiImageAsync(GameCarouselLoadCoverImage, &gameList[gameIndex[i]], sizeof(struct discHdr), &noCover); + coverImg[i] = new(std::nothrow) GuiImageAsync(GameCarouselLoadCoverImage, gameList[gameIndex[i]], sizeof(struct discHdr), &noCover); if(coverImg[i]) coverImg[i]->SetWidescreen(CFG.widescreen); @@ -186,7 +185,7 @@ GuiGameCarousel::~GuiGameCarousel() void GuiGameCarousel::SetFocus(int f) { LOCK(this); - if(!gameCnt) return; + if(!gameList.size()) return; focus = f; @@ -255,7 +254,7 @@ int GuiGameCarousel::GetSelectedOption() void GuiGameCarousel::Draw() { LOCK(this); - if(!this->IsVisible() || !gameCnt) + if(!this->IsVisible() || !gameList.size()) return; for(int i=0; iDraw(); - if(gameCnt > 6) + if(gameList.size() > 6) { btnRight->Draw(); btnLeft->Draw(); @@ -282,7 +281,7 @@ void GuiGameCarousel::Draw() void GuiGameCarousel::Update(GuiTrigger * t) { LOCK(this); - if(state == STATE_DISABLED || !t || !gameCnt) + if(state == STATE_DISABLED || !t || !gameList.size()) return; btnRight->Update(t); @@ -317,7 +316,7 @@ void GuiGameCarousel::Update(GuiTrigger * t) if(selectedItem>=0) { game[selectedItem]->SetEffect(EFFECT_SCALE, 1, 130); - char *gameTitle = get_title(&gameList[gameIndex[selectedItem]]); + char *gameTitle = get_title(gameList[gameIndex[selectedItem]]); gamename->SetText(gameTitle); } else @@ -326,7 +325,7 @@ void GuiGameCarousel::Update(GuiTrigger * t) game[selectedItem_old]->SetEffect(EFFECT_SCALE, -1, 100); } // navigation - if(focus && gameCnt>6) + if(focus && gameList.size()>6) { int newspeed = 0; @@ -386,7 +385,7 @@ void GuiGameCarousel::Update(GuiTrigger * t) if(speed > 0) // rotate right { GuiButton *tmpButton; - listOffset = OFFSETLIMIT(listOffset - 1, gameCnt); // set the new listOffset + listOffset = OFFSETLIMIT(listOffset - 1, gameList.size()); // set the new listOffset // Save right Button + TollTip and destroy right Image + Image-Data delete coverImg[pagesize-1]; coverImg[pagesize-1] = NULL;game[pagesize-1]->SetImage(NULL); tmpButton = game[pagesize-1]; @@ -400,7 +399,7 @@ void GuiGameCarousel::Update(GuiTrigger * t) } // set saved Button & gameIndex to right gameIndex[0] = listOffset; - coverImg[0] = new GuiImageAsync(GameCarouselLoadCoverImage, &gameList[gameIndex[0]], sizeof(struct discHdr), &noCover); + coverImg[0] = new GuiImageAsync(GameCarouselLoadCoverImage, gameList[gameIndex[0]], sizeof(struct discHdr), &noCover); coverImg[0] ->SetWidescreen(CFG.widescreen); game[0] = tmpButton; @@ -418,7 +417,7 @@ void GuiGameCarousel::Update(GuiTrigger * t) else if(speed < 0) // rotate left { GuiButton *tmpButton; - listOffset = OFFSETLIMIT(listOffset + 1, gameCnt); // set the new listOffset + listOffset = OFFSETLIMIT(listOffset + 1, gameList.size()); // set the new listOffset // Save left Button + TollTip and destroy left Image + Image-Data delete coverImg[0]; coverImg[0] = NULL;game[0]->SetImage(NULL); tmpButton = game[0]; @@ -432,8 +431,8 @@ void GuiGameCarousel::Update(GuiTrigger * t) } // set saved Button & gameIndex to right int ii = pagesize-1; - gameIndex[ii] = OFFSETLIMIT(listOffset + ii, gameCnt); - coverImg[ii] = new GuiImageAsync(GameCarouselLoadCoverImage, &gameList[gameIndex[ii]], sizeof(struct discHdr), &noCover); + gameIndex[ii] = OFFSETLIMIT(listOffset + ii, gameList.size()); + coverImg[ii] = new GuiImageAsync(GameCarouselLoadCoverImage, gameList[gameIndex[ii]], sizeof(struct discHdr), &noCover); coverImg[ii] ->SetWidescreen(CFG.widescreen); game[ii] = tmpButton; diff --git a/source/libwiigui/gui_gamecarousel.h b/source/libwiigui/gui_gamecarousel.h index e4906893..05be2935 100644 --- a/source/libwiigui/gui_gamecarousel.h +++ b/source/libwiigui/gui_gamecarousel.h @@ -7,7 +7,7 @@ class GuiImageAsync; class GuiGameCarousel : public GuiElement { public: - GuiGameCarousel(int w, int h, struct discHdr * l, int gameCnt, const char *themePath, const u8 *imagebg, int selected = 0, int offset = 0); + GuiGameCarousel(int w, int h, const char *themePath, const u8 *imagebg, int selected = 0, int offset = 0); ~GuiGameCarousel(); int FindMenuItem(int c, int d); int GetClickedOption(); @@ -17,7 +17,7 @@ class GuiGameCarousel : public GuiElement void Draw(); void Update(GuiTrigger * t); int GetOffset(); - void Reload(struct discHdr * l, int count); + void Reload(); //GuiText * optionVal[PAGESIZE]; protected: GuiImageData noCover; @@ -28,9 +28,6 @@ class GuiGameCarousel : public GuiElement int speed; int clickedItem; - struct discHdr * gameList; - int gameCnt; - int * gameIndex; GuiButton ** game; GuiImageAsync ** coverImg; diff --git a/source/libwiigui/gui_gamegrid.cpp b/source/libwiigui/gui_gamegrid.cpp index 9432a752..05ef1d78 100644 --- a/source/libwiigui/gui_gamegrid.cpp +++ b/source/libwiigui/gui_gamegrid.cpp @@ -12,6 +12,7 @@ #include #include "gui_gamegrid.h" #include "gui_image_async.h" +#include "usbloader/GameList.h" #include "../settings/cfg.h" #include "../prompts/PromptWindows.h" #include "../language/gettext.h" @@ -280,7 +281,7 @@ static GuiImageData *GameGridLoadCoverImage(void * Arg) /** * Constructor for the GuiGamegrid class. */ -GuiGameGrid::GuiGameGrid(int w, int h, struct discHdr * l, int count, const char *themePath, const u8 *imagebg, int selected, int offset) : +GuiGameGrid::GuiGameGrid(int w, int h, const char *themePath, const u8 *imagebg, int selected, int offset) : noCover(nocoverFlat_png) { width = w; @@ -361,7 +362,7 @@ noCover(nocoverFlat_png) coverImg = NULL; game = NULL; - Reload(l, count, Settings.gridRows, 0); + Reload(Settings.gridRows, 0); } @@ -403,7 +404,7 @@ GuiGameGrid::~GuiGameGrid() void GuiGameGrid::SetFocus(int f) { LOCK(this); - if(!gameCnt) + if(!gameList.size()) return; focus = f; @@ -474,7 +475,7 @@ int GuiGameGrid::GetSelectedOption() void GuiGameGrid::Draw() { LOCK(this); - if(!this->IsVisible() || !gameCnt) + if(!this->IsVisible() || !gameList.size()) return; if(goLeft>0) @@ -527,7 +528,7 @@ void GuiGameGrid::Draw() for(int i=0; iDraw(); - if(gameCnt > pagesize-2*rows) + if(gameList.size() > pagesize-2*rows) { btnRight->Draw(); btnLeft->Draw(); @@ -552,14 +553,14 @@ void GuiGameGrid::ChangeRows(int n) { LOCK(this); if(n != rows) - Reload(gameList, gameCnt, n, -1); + Reload(n, -1); } void GuiGameGrid::Update(GuiTrigger * t) { LOCK(this); - if(state == STATE_DISABLED || !t || !gameCnt) + if(state == STATE_DISABLED || !t || !gameList.size()) return; if(!(game[0]->GetEffect() || game[0]->GetEffectOnOver())) @@ -589,7 +590,7 @@ void GuiGameGrid::Update(GuiTrigger * t) } // navigation - if(focus && gameCnt >= (pagesize-2*rows) && goLeft==0 && goRight==0) + if(focus && gameList.size() >= (pagesize-2*rows) && goLeft==0 && goRight==0) { // Left/Right Navigation @@ -631,7 +632,7 @@ void GuiGameGrid::Update(GuiTrigger * t) { GuiButton *tmpButton[rows]; GuiTooltip *tmpTooltip[rows]; - listOffset = OFFSETLIMIT(listOffset + rows, rows, gameCnt); // set the new listOffset + listOffset = OFFSETLIMIT(listOffset + rows, rows, gameList.size()); // set the new listOffset // Save left Tooltip & Button and destroy left Image + Image-Data for (int i=0; iSetWidescreen(CFG.widescreen); coverImg[ii] ->SetScale(VALUE4ROWS(rows, 1.0, 0.6, 0.26)); coverImg[ii] ->SetPosition(0,VALUE4ROWS(rows, 0, -50, -80)); } - titleTT[ii] ->SetText(get_title(&gameList[gameIndex[ii]])); + titleTT[ii] ->SetText(get_title(gameList[gameIndex[ii]])); } else { @@ -716,7 +717,7 @@ void GuiGameGrid::Update(GuiTrigger * t) { GuiButton *tmpButton[rows]; GuiTooltip *tmpTooltip[rows]; - listOffset = OFFSETLIMIT(listOffset - rows, rows, gameCnt); // set the new listOffset + listOffset = OFFSETLIMIT(listOffset - rows, rows, gameList.size()); // set the new listOffset // Save right Button & Tooltip and destroy right Image-Data for (int i=0; iSetWidescreen(CFG.widescreen); coverImg[i] ->SetScale(VALUE4ROWS(rows, 1.0, 0.6, 0.26)); coverImg[i] ->SetPosition(0,VALUE4ROWS(rows, 0, -50, -80)); } - titleTT[i] ->SetText(get_title(&gameList[gameIndex[i]])); + titleTT[i] ->SetText(get_title(gameList[gameIndex[i]])); } else { @@ -800,8 +801,8 @@ void GuiGameGrid::Update(GuiTrigger * t) if ((btnRowUp->GetState() == STATE_CLICKED)) { - if ((rows==1)&&(gameCnt>=18))this->ChangeRows(2); - else if ((rows==2)&&(gameCnt>=45))this->ChangeRows(3); + if ((rows==1)&&(gameList.size()>=18))this->ChangeRows(2); + else if ((rows==2)&&(gameList.size()>=45))this->ChangeRows(3); btnRowUp->ResetState(); return; } @@ -819,7 +820,7 @@ void GuiGameGrid::Update(GuiTrigger * t) } -void GuiGameGrid::Reload(struct discHdr * l, int count, int Rows, int ListOffset) +void GuiGameGrid::Reload(int Rows, int ListOffset) { LOCK(this); @@ -846,18 +847,16 @@ void GuiGameGrid::Reload(struct discHdr * l, int count, int Rows, int ListOffset // delete [] cover; delete [] titleTT; - gameList = l; - gameCnt = count; goLeft = 0; goRight = 0; rows = Rows > 3 ? 3 : (Rows < 1 ? 1 : Rows); - if ((count<45)&&(rows==3))rows=2; - if ((count<18)&&(rows==2))rows=1; + if ((gameList.size()<45)&&(rows==3))rows=2; + if ((gameList.size()<18)&&(rows==2))rows=1; if(ListOffset>=0) // if ListOffset < 0 then no change listOffset = ListOffset; - listOffset = OFFSETLIMIT(listOffset, rows, gameCnt); + listOffset = OFFSETLIMIT(listOffset, rows, gameList.size()); selectedItem = -1; clickedItem = -1; @@ -884,13 +883,13 @@ void GuiGameGrid::Reload(struct discHdr * l, int count, int Rows, int ListOffset //------------------------ // Index //------------------------ - gameIndex[i] = GetGameIndex(i, rows, listOffset, gameCnt); + gameIndex[i] = GetGameIndex(i, rows, listOffset, gameList.size()); //------------------------ // Tooltip //------------------------ if( gameIndex[i] != -1 ) - titleTT[i] = new GuiTooltip(get_title(&gameList[gameIndex[i]]), THEME.tooltipAlpha); + titleTT[i] = new GuiTooltip(get_title(gameList[gameIndex[i]]), THEME.tooltipAlpha); else titleTT[i] = new GuiTooltip(NULL, THEME.tooltipAlpha); @@ -908,7 +907,7 @@ void GuiGameGrid::Reload(struct discHdr * l, int count, int Rows, int ListOffset coverImg[i] = NULL; if( gameIndex[i] != -1 ) { - coverImg[i] = new GuiImageAsync(GameGridLoadCoverImage, &gameList[gameIndex[i]], sizeof(struct discHdr), &noCover); + coverImg[i] = new GuiImageAsync(GameGridLoadCoverImage, gameList[gameIndex[i]], sizeof(struct discHdr), &noCover); if(coverImg[i]) { coverImg[i]->SetWidescreen(CFG.widescreen); diff --git a/source/libwiigui/gui_gamegrid.h b/source/libwiigui/gui_gamegrid.h index 7ff01d9a..89625e6b 100644 --- a/source/libwiigui/gui_gamegrid.h +++ b/source/libwiigui/gui_gamegrid.h @@ -7,7 +7,7 @@ class GuiImageAsync; class GuiGameGrid : public GuiElement { public: - GuiGameGrid(int w, int h, struct discHdr * l, int gameCnt, const char *themePath, const u8 *imagebg, int selected = 0, int offset = 0); + GuiGameGrid(int w, int h, const char *themePath, const u8 *imagebg, int selected = 0, int offset = 0); ~GuiGameGrid(); int FindMenuItem(int c, int d); int GetClickedOption(); @@ -17,7 +17,7 @@ class GuiGameGrid : public GuiElement void Draw(); void Update(GuiTrigger * t); int GetOffset(); - void Reload(struct discHdr * l, int count, int Rows, int ListOffset); + void Reload(int Rows, int ListOffset); void ChangeRows(int n); protected: GuiImageData noCover; @@ -29,9 +29,6 @@ class GuiGameGrid : public GuiElement int goLeft; int goRight; - struct discHdr * gameList; - int gameCnt; - int * gameIndex; GuiButton ** game; GuiTooltip ** titleTT; diff --git a/source/libwiigui/gui_searchbar.cpp b/source/libwiigui/gui_searchbar.cpp index 8a7420e6..c31aa498 100644 --- a/source/libwiigui/gui_searchbar.cpp +++ b/source/libwiigui/gui_searchbar.cpp @@ -4,7 +4,7 @@ #include "../wpad.h" #include "../main.h" #include "../settings/cfg.h" -#include "../usbloader/getentries.h" +#include "../usbloader/GameList.h" extern GuiWindow * mainWindow; @@ -66,7 +66,7 @@ sndClick(button_click_pcm, button_click_pcm_size, Settings.sfxvolume) height = 10+42+y*42+10; - text.SetText(gameFilter); + text.SetText(gameList.GetCurrentFilter()); text.SetPosition(10, 15); text.SetAlignment(ALIGN_LEFT, ALIGN_TOP); text.SetWidescreen(CFG.widescreen); diff --git a/source/main.cpp b/source/main.cpp index dc72848a..170b880a 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -73,7 +73,7 @@ int main(int argc, char *argv[]) InitVideo(); setlocale(LC_ALL, "en.UTF-8"); geckoinit = InitGecko(); - __exception_setreload(5); + __exception_setreload(20); printf("\n\tStarting up"); diff --git a/source/menu.cpp b/source/menu.cpp index dda4acf2..6caef828 100644 --- a/source/menu.cpp +++ b/source/menu.cpp @@ -22,7 +22,7 @@ #include "settings/cfg.h" #include "themes/Theme_Downloader.h" #include "usbloader/disc.h" -#include "usbloader/getentries.h" +#include "usbloader/GameList.h" #include "wad/title.h" #include "xml/xml.h" #include "audio.h" @@ -64,7 +64,6 @@ static int ExitRequested = 0; /*** Extern variables ***/ -extern struct discHdr * gameList; extern u8 shutdown; extern u8 reset; extern s32 gameSelected, gameStart; @@ -354,7 +353,7 @@ int MainMenu(int menu) { if (mountMethod==3) { - struct discHdr *header = &gameList[gameSelected]; + struct discHdr *header = gameList[gameSelected]; char tmp[20]; u32 tid; sprintf(tmp,"%c%c%c%c",header->id[0],header->id[1],header->id[2],header->id[3]); @@ -385,16 +384,16 @@ int MainMenu(int menu) { if (strcmp(headlessID,"")!=0) { gprintf("\n\tHeadless mode (%s)",headlessID); - __Menu_GetEntries(1); - if (!gameCnt) + gameList.LoadUnfiltered(); + if (!gameList.size()) { gprintf(" ERROR : !gameCnt"); exit(0); } //gprintf("\n\tgameCnt:%d",gameCnt); - for(u32 i=0;iid[0],header->id[1],header->id[2],header->id[3],header->id[4],header->id[5]); if (strcmp(tmp,headlessID)==0) @@ -404,7 +403,7 @@ int MainMenu(int menu) { break; } //if the game was not found - if (i==gameCnt-1) + if (i==gameList.GameCount()-1) { gprintf(" not found (%d IDs checked)",i); exit(0); @@ -414,7 +413,7 @@ int MainMenu(int menu) { int ret = 0; - header = (mountMethod?dvdheader:&gameList[gameSelected]); + header = (mountMethod?dvdheader:gameList[gameSelected]); struct Game_CFG* game_cfg = CFG_get_game_opt(header->id); @@ -503,9 +502,6 @@ int MainMenu(int menu) { if (ret < 0) Sys_BackToLoader(); - if (gameList){ - free(gameList); - } if(dvdheader) delete dvdheader; diff --git a/source/menu/menu_check.cpp b/source/menu/menu_check.cpp index da61e674..9527ccfb 100644 --- a/source/menu/menu_check.cpp +++ b/source/menu/menu_check.cpp @@ -4,7 +4,6 @@ #include "menus.h" #include "wpad.h" #include "fatmounter.h" -#include "usbloader/getentries.h" #include "usbloader/wbfs.h" extern int load_from_fs; diff --git a/source/menu/menu_disclist.cpp b/source/menu/menu_disclist.cpp index 76283971..96d79652 100644 --- a/source/menu/menu_disclist.cpp +++ b/source/menu/menu_disclist.cpp @@ -1,7 +1,7 @@ #include "menus.h" #include "fatmounter.h" #include "usbloader/wdvd.h" -#include "usbloader/getentries.h" +#include "usbloader/GameList.h" #include "usbloader/wbfs.h" #include "patches/fst.h" #include "network/networkops.h" @@ -50,8 +50,8 @@ int MenuDiscList() { gprintf("\nMenuDiscList()"); //TakeScreenshot("SD:/screenshot1.png"); - __Menu_GetEntries(); - int offset = MIN(startat,gameCnt-1); + gameList.FilterList(); + int offset = MIN((int)startat,gameList.size()-1); startat = offset; //gprintf("\n\tstartat:%d offset:%d",startat,offset); int datag = 0; @@ -93,7 +93,7 @@ int MenuDiscList() { WBFS_DiskSpace(&used, &freespace); } - if (!gameCnt) { //if there is no list of games to display + if (!gameList.size()) { //if there is no list of games to display nolist = 1; } @@ -211,7 +211,7 @@ int MenuDiscList() { usedSpaceTxt.SetPosition(THEME.hddinfo_x, THEME.hddinfo_y); char GamesCnt[15]; - sprintf(GamesCnt,"%s: %i",(mountMethod!=3?tr("Games"):tr("Channels")), gameCnt); + sprintf(GamesCnt,"%s: %i",(mountMethod!=3?tr("Games"):tr("Channels")), gameList.size()); GuiText gamecntTxt(GamesCnt, 18, THEME.info); GuiButton gamecntBtn(100,18); @@ -439,9 +439,9 @@ int MenuDiscList() { favoriteBtn.SetAlpha(255); } static bool show_searchwindow = false; - if(gameFilter && *gameFilter) + if(*gameList.GetCurrentFilter()) { - if(show_searchwindow && gameCnt==1) + if(show_searchwindow && gameList.size()==1) show_searchwindow = false; if(!show_searchwindow) searchBtn.SetEffect(EFFECT_PULSE, 10, 105); @@ -449,11 +449,11 @@ int MenuDiscList() { searchBtn.SetImageOver(&searchBtnImg); searchBtn.SetAlpha(255); } - if (Settings.sort==all) { + if (Settings.sort==ALL) { abcBtn.SetImage(&abcBtnImg); abcBtn.SetImageOver(&abcBtnImg); abcBtn.SetAlpha(255); - } else if (Settings.sort==pcount) { + } else if (Settings.sort==PLAYCOUNT) { countBtn.SetImage(&countBtnImg); countBtn.SetImageOver(&countBtnImg); countBtn.SetAlpha(255); @@ -542,16 +542,16 @@ int MenuDiscList() { GuiGameGrid * gameGrid = NULL; GuiGameCarousel * gameCarousel = NULL; if (Settings.gameDisplay==list) { - gameBrowser = new GuiGameBrowser(THEME.gamelist_w, THEME.gamelist_h, gameList, gameCnt, CFG.theme_path, bg_options_png, startat, offset); + gameBrowser = new GuiGameBrowser(THEME.gamelist_w, THEME.gamelist_h, CFG.theme_path, bg_options_png, startat, offset); gameBrowser->SetPosition(THEME.gamelist_x, THEME.gamelist_y); gameBrowser->SetAlignment(ALIGN_LEFT, ALIGN_CENTRE); } else if (Settings.gameDisplay==grid) { - gameGrid = new GuiGameGrid(THEME.gamegrid_w,THEME.gamegrid_h, gameList, gameCnt, CFG.theme_path, bg_options_png, 0, 0); + gameGrid = new GuiGameGrid(THEME.gamegrid_w,THEME.gamegrid_h, CFG.theme_path, bg_options_png, 0, 0); gameGrid->SetPosition(THEME.gamegrid_x,THEME.gamegrid_y); gameGrid->SetAlignment(ALIGN_LEFT, ALIGN_CENTRE); } else if (Settings.gameDisplay==carousel) { - //GuiGameCarousel gameCarousel(THEME.gamecarousel_w, THEME.gamecarousel_h, gameList, gameCnt, CFG.theme_path, bg_options_png, startat, offset); - gameCarousel = new GuiGameCarousel(640, 400, gameList, gameCnt, CFG.theme_path, bg_options_png, startat, offset); + //GuiGameCarousel gameCarousel(THEME.gamecarousel_w, THEME.gamecarousel_h, gameList, gameList.size(), CFG.theme_path, bg_options_png, startat, offset); + gameCarousel = new GuiGameCarousel(640, 400, CFG.theme_path, bg_options_png, startat, offset); gameCarousel->SetPosition(THEME.gamecarousel_x,THEME.gamecarousel_y); gameCarousel->SetAlignment(ALIGN_LEFT, ALIGN_CENTRE); } @@ -631,7 +631,7 @@ int MenuDiscList() { GuiSearchBar *searchBar=NULL; if(show_searchwindow) { - searchBar = new GuiSearchBar(gameFilterNextList); + searchBar = new GuiSearchBar(gameList.GetAvailableSearchChars()); if(searchBar) mainWindow->Append(searchBar); } @@ -662,13 +662,13 @@ int MenuDiscList() { WDVD_GetCoverStatus(&covert);//for detecting if i disc has been inserted // if the idiot is showing favorites and don't have any - if (Settings.fave && !gameCnt) { + if (Settings.fave && !gameList.size()) { WindowPrompt(tr("No Favorites"),tr("You are choosing to display favorites and you do not have any selected."),tr("Back")); Settings.fave=!Settings.fave; if (isInserted(bootDevice)) { cfg_save_global(); } - __Menu_GetEntries(); + gameList.FilterList(); menu = MENU_DISCLIST; break; } @@ -927,7 +927,7 @@ int MenuDiscList() { if (isInserted(bootDevice)) { cfg_save_global(); } - __Menu_GetEntries(); + gameList.FilterList(); menu = MENU_DISCLIST; break; @@ -946,18 +946,18 @@ int MenuDiscList() { } if(show_searchwindow) { - if(gameFilter && *gameFilter) + if(*gameList.GetCurrentFilter()) { searchBtn.StopEffect(); searchBtn.SetEffectGrow(); } - searchBar = new GuiSearchBar(gameFilterNextList); + searchBar = new GuiSearchBar(gameList.GetAvailableSearchChars()); if(searchBar) mainWindow->Append(searchBar); } else { - if(gameFilter && *gameFilter) + if(*gameList.GetCurrentFilter()) searchBtn.SetEffect(EFFECT_PULSE, 10, 105); } searchBtn.ResetState(); @@ -967,15 +967,15 @@ int MenuDiscList() { else if (searchBar && (searchChar=searchBar->GetClicked())) { if(searchChar > 27) { - int len = gameFilter ? wcslen(gameFilter) : 0; + int len = gameList.GetCurrentFilter() ? wcslen(gameList.GetCurrentFilter()) : 0; wchar_t newFilter[len+2]; - if(gameFilter) - wcscpy(newFilter, gameFilter); + if(gameList.GetCurrentFilter()) + wcscpy(newFilter, gameList.GetCurrentFilter()); newFilter[len] = searchChar; newFilter[len+1] = 0; - __Menu_GetEntries(0, newFilter); + gameList.FilterList(newFilter); menu = MENU_DISCLIST; break; } @@ -989,7 +989,7 @@ int MenuDiscList() { delete searchBar; searchBar = NULL; } - if(gameFilter && *gameFilter) + if(*gameList.GetCurrentFilter()) { searchBtn.SetEffect(EFFECT_PULSE, 10, 105); searchBtn.SetImage(&searchBtnImg); @@ -1009,7 +1009,12 @@ int MenuDiscList() { } else if(searchChar == 8) // Backspace { - __Menu_GetEntries(0, gameFilterPrev); + int len = wcslen(gameList.GetCurrentFilter()); + wchar_t newFilter[len+1]; + if(gameList.GetCurrentFilter()) + wcscpy(newFilter, gameList.GetCurrentFilter()); + newFilter[len > 0 ? len-1 : 0] = 0; + gameList.FilterList(newFilter); menu = MENU_DISCLIST; break; } @@ -1018,12 +1023,12 @@ int MenuDiscList() { else if (abcBtn.GetState() == STATE_CLICKED) { gprintf("\n\tabcBtn clicked"); - if (Settings.sort != all) { - Settings.sort=all; + if (Settings.sort != ALL) { + Settings.sort=ALL; if (isInserted(bootDevice)) { cfg_save_global(); } - __Menu_GetEntries(); + gameList.FilterList(); menu = MENU_DISCLIST; break; @@ -1033,13 +1038,13 @@ int MenuDiscList() { else if (countBtn.GetState() == STATE_CLICKED) { gprintf("\n\tcountBtn Clicked"); - if (Settings.sort != pcount) { - Settings.sort=pcount; + if (Settings.sort != PLAYCOUNT) { + Settings.sort = PLAYCOUNT; //if(isSdInserted()) { if (isInserted(bootDevice)) { cfg_save_global(); } - __Menu_GetEntries(); + gameList.FilterList(); menu = MENU_DISCLIST; break; @@ -1102,10 +1107,10 @@ int MenuDiscList() { else if (gameInfo.GetState() == STATE_CLICKED && mountMethod!=3) { gprintf("\n\tgameinfo Clicked"); gameInfo.ResetState(); - if(selectImg1>=0 && selectImg1<(s32)gameCnt) { + if(selectImg1>=0 && selectImg1<(s32)gameList.size()) { gameSelected = selectImg1; rockout(); - struct discHdr *header = &gameList[selectImg1]; + struct discHdr *header = gameList[selectImg1]; snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]); choice = showGameInfo(IDfull); rockout(2); @@ -1196,10 +1201,10 @@ int MenuDiscList() { selectimg = gameSelected; char gameregion[7]; - if ((selectimg >= 0) && (selectimg < (s32) gameCnt)) { + if ((selectimg >= 0) && (selectimg < (s32) gameList.size())) { if (selectimg != selectedold) { selectedold = selectimg;//update displayed cover, game ID, and region if the selected game changes - struct discHdr *header = &gameList[selectimg]; + struct discHdr *header = gameList[selectimg]; snprintf (ID,sizeof(ID),"%c%c%c", header->id[0], header->id[1], header->id[2]); snprintf (IDfull,sizeof(IDfull),"%s%c%c%c", ID, header->id[3], header->id[4], header->id[5]); w.Remove(&DownloadBtn); @@ -1282,7 +1287,7 @@ int MenuDiscList() { if (idBtn.GetState() == STATE_CLICKED && mountMethod!=3) { gprintf("\n\tidBtn Clicked"); - struct discHdr * header = &gameList[gameBrowser->GetSelectedOption()]; + struct discHdr * header = gameList[gameBrowser->GetSelectedOption()]; //enter new game ID char entered[10]; snprintf(entered, sizeof(entered), "%s", IDfull); @@ -1299,7 +1304,7 @@ int MenuDiscList() { startat=gameBrowser->GetOffset(), offset=startat; } - if (((gameSelected >= 0) && (gameSelected < (s32)gameCnt)) + if (((gameSelected >= 0) && (gameSelected < (s32)gameList.size())) || mountMethod==1 || mountMethod==2) { if(searchBar) @@ -1309,8 +1314,8 @@ int MenuDiscList() { ResumeGui(); } rockout(); - struct discHdr *header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); - // struct discHdr *header = dvdheader:&gameList[gameSelected]); + struct discHdr *header = (mountMethod==1||mountMethod==2?dvdheader:gameList[gameSelected]); + // struct discHdr *header = dvdheader:gameList[gameSelected]); if (!mountMethod)//only get this stuff it we are booting a game from USB { WBFS_GameSize(header->id, &size); @@ -1326,7 +1331,7 @@ int MenuDiscList() { //check if alt Dol and gct file is present FILE *exeFile = NULL; char nipple[100]; - header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); //reset header + header = (mountMethod==1||mountMethod==2?dvdheader:gameList[gameSelected]); //reset header snprintf (IDfull,sizeof(IDfull),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]); struct Game_CFG* game_cfg = CFG_get_game_opt(header->id); @@ -1395,7 +1400,7 @@ int MenuDiscList() { returnHere = false; if (Settings.wiilight != wiilight_forInstall) wiilight(1); choice = GameWindowPrompt(); - // header = &gameList[gameSelected]; //reset header + // header = gameList[gameSelected]; //reset header if (choice == 1) { if (alternatedol == on) { @@ -1440,7 +1445,7 @@ int MenuDiscList() { ResumeGui(); //re-evaluate header now in case they changed games while on the game prompt - header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); + header = (mountMethod==1||mountMethod==2?dvdheader:gameList[gameSelected]); int settret = GameSettings(header); /* unneeded for now, kept in case database gets a separate language setting //menu = MENU_DISCLIST; // refresh titles (needed if the language setting has changed) @@ -1462,7 +1467,7 @@ int MenuDiscList() { else if (choice == 3 && !mountMethod) { //WBFS renaming wiilight(0); //re-evaluate header now in case they changed games while on the game prompt - header = &gameList[gameSelected]; + header = gameList[gameSelected]; //enter new game title char entered[60]; @@ -1471,7 +1476,8 @@ int MenuDiscList() { int result = OnScreenKeyboard(entered, 60,0); if (result == 1) { WBFS_RenameGame(header->id, entered); - __Menu_GetEntries(); + gameList.ReadGameList(); + gameList.FilterList(); menu = MENU_DISCLIST; } } else if (choice == 0) { @@ -1514,7 +1520,7 @@ int MenuDiscList() { // set alt dol default if (menu == MENU_EXIT && altdoldefault) { - struct discHdr *header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); + struct discHdr *header = (mountMethod==1||mountMethod==2?dvdheader:gameList[gameSelected]); struct Game_CFG* game_cfg = CFG_get_game_opt(header->id); // use default only if no alt dol was selected manually if (game_cfg) { @@ -1573,29 +1579,16 @@ void DiscListWinUpdateCallback(void * e) } } -void rockout(int f) { - - +void rockout(int f) +{ HaltGui(); - int num=(f==2?-1:gameSelected); char imgPath[100]; - if ((!(strcasestr(get_title(&gameList[num]),"guitar")|| - strcasestr(get_title(&gameList[num]),"band")|| - strcasestr(get_title(&gameList[num]),"rock")|| - f==1))||mountMethod) { - for (int i = 0; i < 4; i++) - delete pointer[i]; - snprintf(imgPath, sizeof(imgPath), "%splayer1_point.png", CFG.theme_path); - pointer[0] = new GuiImageData(imgPath, player1_point_png); - snprintf(imgPath, sizeof(imgPath), "%splayer2_point.png", CFG.theme_path); - pointer[1] = new GuiImageData(imgPath, player2_point_png); - snprintf(imgPath, sizeof(imgPath), "%splayer3_point.png", CFG.theme_path); - pointer[2] = new GuiImageData(imgPath, player3_point_png); - snprintf(imgPath, sizeof(imgPath), "%splayer4_point.png", CFG.theme_path); - pointer[3] = new GuiImageData(imgPath, player4_point_png); - } else { - + if (gameSelected >= 0 && gameSelected < gameList.size() && + (strcasestr(get_title(gameList[gameSelected]),"guitar") || + strcasestr(get_title(gameList[gameSelected]),"band") || + strcasestr(get_title(gameList[gameSelected]),"rock"))) + { for (int i = 0; i < 4; i++) delete pointer[i]; snprintf(imgPath, sizeof(imgPath), "%srplayer1_point.png", CFG.theme_path); @@ -1607,5 +1600,19 @@ void rockout(int f) { snprintf(imgPath, sizeof(imgPath), "%srplayer4_point.png", CFG.theme_path); pointer[3] = new GuiImageData(imgPath, rplayer4_point_png); } + else + { + + for (int i = 0; i < 4; i++) + delete pointer[i]; + snprintf(imgPath, sizeof(imgPath), "%splayer1_point.png", CFG.theme_path); + pointer[0] = new GuiImageData(imgPath, player1_point_png); + snprintf(imgPath, sizeof(imgPath), "%splayer2_point.png", CFG.theme_path); + pointer[1] = new GuiImageData(imgPath, player2_point_png); + snprintf(imgPath, sizeof(imgPath), "%splayer3_point.png", CFG.theme_path); + pointer[2] = new GuiImageData(imgPath, player3_point_png); + snprintf(imgPath, sizeof(imgPath), "%splayer4_point.png", CFG.theme_path); + pointer[3] = new GuiImageData(imgPath, player4_point_png); + } ResumeGui(); } diff --git a/source/menu/menu_install.cpp b/source/menu/menu_install.cpp index 8f21ea43..e416180a 100644 --- a/source/menu/menu_install.cpp +++ b/source/menu/menu_install.cpp @@ -3,7 +3,7 @@ #include "usbloader/wbfs.h" #include "usbloader/disc.h" #include "usbloader/utils.h" -#include "usbloader/getentries.h" +#include "usbloader/GameList.h" #include "prompts/ProgressWindow.h" float gamesize; @@ -115,7 +115,8 @@ int MenuInstall() { menu = MENU_DISCLIST; break; } else { - __Menu_GetEntries(); //get the entries again + gameList.ReadGameList(); //get the entries again + gameList.FilterList(); GuiSound * instsuccess = NULL; bgMusic->Pause(); instsuccess = new GuiSound(success_ogg, success_ogg_size, Settings.sfxvolume); diff --git a/source/prompts/PromptWindows.cpp b/source/prompts/PromptWindows.cpp index 68ecba30..c15a5a49 100644 --- a/source/prompts/PromptWindows.cpp +++ b/source/prompts/PromptWindows.cpp @@ -11,7 +11,7 @@ #include "usbloader/wdvd.h" #include "usbloader/partition_usbloader.h" #include "usbloader/usbstorage2.h" -#include "usbloader/getentries.h" +#include "usbloader/GameList.h" #include "language/gettext.h" #include "libwiigui/gui.h" #include "libwiigui/gui_diskcover.h" @@ -50,10 +50,8 @@ static char missingFiles[500][12]; /*** Extern variables ***/ extern GuiWindow * mainWindow; extern GuiSound * bgMusic; -extern u32 gameCnt; -extern s32 gameSelected, gameStart; +s32 gameSelected = 0, gameStart = 0; extern float gamesize; -extern struct discHdr * gameList; extern u8 shutdown; extern u8 reset; extern u8 mountMethod; @@ -1318,7 +1316,7 @@ int GameWindowPrompt() { } //load disc image based or what game is seleted - struct discHdr * header = (mountMethod==1||mountMethod==2?dvdheader:&gameList[gameSelected]); + struct discHdr * header = (mountMethod==1||mountMethod==2?dvdheader:gameList[gameSelected]); if(Settings.gamesoundvolume > 0) { if(gameSound) @@ -1556,7 +1554,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); changed = 1; btnClick2->Play(); - gameSelected = (gameSelected + 1) % gameCnt; + gameSelected = (gameSelected + 1) % gameList.size(); btnRight.ResetState(); break; } @@ -1565,7 +1563,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); changed = 2; btnClick2->Play(); - gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; + gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnLeft.ResetState(); break; } @@ -1574,7 +1572,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); changed = 2; btnClick2->Play(); - gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; + gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnRight.ResetState(); break; } @@ -1583,7 +1581,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); changed = 1; btnClick2->Play(); - gameSelected = (gameSelected + 1) % gameCnt; + gameSelected = (gameSelected + 1) % gameList.size(); btnLeft.ResetState(); break; } @@ -1592,7 +1590,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); changed = 2; btnClick2->Play(); - gameSelected = (gameSelected + 1) % gameCnt; + gameSelected = (gameSelected + 1) % gameList.size(); btnRight.ResetState(); break; } @@ -1601,7 +1599,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); changed = 1; btnClick2->Play(); - gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; + gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnLeft.ResetState(); break; } @@ -1610,7 +1608,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 50); changed = 1; btnClick2->Play(); - gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; + gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnRight.ResetState(); break; } @@ -1619,7 +1617,7 @@ int GameWindowPrompt() { promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 50); changed = 2; btnClick2->Play(); - gameSelected = (gameSelected + 1) % gameCnt; + gameSelected = (gameSelected + 1) % gameList.size(); btnLeft.ResetState(); break; } @@ -1628,7 +1626,7 @@ int GameWindowPrompt() { // diskImg.SetBetaRotateEffect(45, 90); changed = 3; btnClick2->Play(); - gameSelected = (gameSelected + 1) % gameCnt; + gameSelected = (gameSelected + 1) % gameList.size(); btnRight.ResetState(); break; } @@ -1638,7 +1636,7 @@ int GameWindowPrompt() { // promptWindow.SetEffect(EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 1/*50*/); changed = 4; btnClick2->Play(); - gameSelected = (gameSelected - 1 + gameCnt) % gameCnt; + gameSelected = (gameSelected - 1 + gameList.size()) % gameList.size(); btnLeft.ResetState(); break; } @@ -1917,18 +1915,18 @@ bool SearchMissingImages(int choice2) { ResumeGui(); //make sure that all games are added to the gamelist - __Menu_GetEntries(1); + gameList.LoadUnfiltered(); cntMissFiles = 0; - u32 i = 0; + int i = 0; char filename[11]; //add IDs of games that are missing covers to cntMissFiles bool found1 = false; bool found2 = false; bool found3 = false; - for (i = 0; i < gameCnt && cntMissFiles < 500; i++) { - struct discHdr* header = &gameList[i]; + for (i = 0; i < gameList.size() && cntMissFiles < 500; i++) { + struct discHdr* header = gameList[i]; if (choice2 != 3) { char *covers_path = choice2==1 ? Settings.covers2d_path : Settings.covers_path; @@ -1969,7 +1967,7 @@ bool SearchMissingImages(int choice2) { HaltGui(); mainWindow->Remove(&promptWindow); mainWindow->SetState(STATE_DEFAULT); - __Menu_GetEntries(); + gameList.FilterList(); ResumeGui(); gprintf(" = %i",cntMissFiles); diff --git a/source/prompts/TitleBrowser.cpp b/source/prompts/TitleBrowser.cpp index 8037a6b3..07eb8492 100644 --- a/source/prompts/TitleBrowser.cpp +++ b/source/prompts/TitleBrowser.cpp @@ -23,10 +23,9 @@ #include "audio.h" #include "wad/wad.h" #include "xml/xml.h" -#include "../wad/title.h" -#include "../usbloader/getentries.h" -#include "../usbloader/utils.h" -#include "../gecko.h" +#include "wad/title.h" +#include "usbloader/utils.h" +#include "gecko.h" #define typei 0x00010001 diff --git a/source/prompts/gameinfo.cpp b/source/prompts/gameinfo.cpp index 90457300..3da99b36 100644 --- a/source/prompts/gameinfo.cpp +++ b/source/prompts/gameinfo.cpp @@ -19,7 +19,7 @@ #include "listfiles.h" #include "prompts/PromptWindows.h" #include "gameinfo.h" -#include "usbloader/getentries.h" +#include "usbloader/GameList.h" #include "../gecko.h" @@ -28,8 +28,6 @@ extern u8 shutdown; extern u8 reset; extern struct gameXMLinfo gameinfo; extern struct gameXMLinfo gameinfo_reset; -extern u32 gameCnt; -extern struct discHdr * gameList; /*** Extern functions ***/ extern void ResumeGui(); @@ -1043,11 +1041,11 @@ bool save_gamelist(int txt) { // save gamelist return false; } //make sure that all games are added to the gamelist - __Menu_GetEntries(1); + gameList.LoadUnfiltered(); f32 size = 0.0; f32 freespace, used; - unsigned int i; + int i; WBFS_DiskSpace(&used, &freespace); @@ -1064,8 +1062,8 @@ bool save_gamelist(int txt) { // save gamelist fprintf(f, "%.2fGB %s %.2fGB %s\n\n",freespace,tr("of"),(freespace+used),tr("free")); fprintf(f, "ID Size(GB) Name\n"); - for (i = 0; i < gameCnt ; i++) { - struct discHdr* header = &gameList[i]; + for (i = 0; i < gameList.size() ; i++) { + struct discHdr* header = gameList[i]; WBFS_GameSize(header->id, &size); if (i<500) { fprintf(f, "%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2], header->id[3], header->id[4], header->id[5]); @@ -1078,8 +1076,8 @@ bool save_gamelist(int txt) { // save gamelist fprintf(f, "\"ID\",\"Size(GB)\",\"Name\"\n"); - for (i = 0; i < gameCnt ; i++) { - struct discHdr* header = &gameList[i]; + for (i = 0; i < gameList.size() ; i++) { + struct discHdr* header = gameList[i]; WBFS_GameSize(header->id, &size); if (i<500) { fprintf(f, "\"%c%c%c%c%c%c\",\"%.2f\",\"%s\"\n", header->id[0], header->id[1], header->id[2], header->id[3], header->id[4], header->id[5], size,get_title(header)); @@ -1091,7 +1089,7 @@ bool save_gamelist(int txt) { // save gamelist } fclose(f); - __Menu_GetEntries(); + gameList.FilterList(); mainWindow->SetState(STATE_DEFAULT); return true; } @@ -1139,22 +1137,23 @@ void MemInfoPrompt() } -void build_XML_URL(char *XMLurl, int XMLurlsize) { - __Menu_GetEntries(1); +void build_XML_URL(char *XMLurl, int XMLurlsize) +{ + gameList.LoadUnfiltered(); // NET_BUFFER_SIZE in http.c needs to be set to size of XMLurl + headerformat char url[3540]; char filename[10]; snprintf(url,sizeof(url),"http://wiitdb.com/wiitdb.zip?LANG=%s&ID=", Settings.db_language); - unsigned int i; - for (i = 0; i < gameCnt ; i++) { - struct discHdr* header = &gameList[i]; + int i; + for (i = 0; i < gameList.size(); i++) { + struct discHdr* header = gameList[i]; if (i<500) { snprintf(filename,sizeof(filename),"%c%c%c%c%c%c", header->id[0], header->id[1], header->id[2],header->id[3], header->id[4], header->id[5]); strncat(url,filename,6); - if ((i!=gameCnt-1)&&(i<500)) + if ((i!=gameList.size()-1)&&(i<500)) strncat(url, ",",1); } } strlcpy(XMLurl,url,XMLurlsize); - __Menu_GetEntries(); + gameList.FilterList(); } diff --git a/source/settings/Settings.cpp b/source/settings/Settings.cpp index c70396f3..21e2e13a 100644 --- a/source/settings/Settings.cpp +++ b/source/settings/Settings.cpp @@ -2,7 +2,6 @@ #include #include "usbloader/wbfs.h" -#include "usbloader/getentries.h" #include "language/gettext.h" #include "libwiigui/gui.h" #include "libwiigui/gui_customoptionbrowser.h" diff --git a/source/settings/cfg.c b/source/settings/cfg.c index e66fc208..04a8e786 100644 --- a/source/settings/cfg.c +++ b/source/settings/cfg.c @@ -1731,7 +1731,7 @@ bool cfg_load_global() { -struct Game_CFG* CFG_get_game_opt(u8 *id) { +struct Game_CFG* CFG_get_game_opt(const u8 *id) { int i; for (i=0; i -#include - -#include "cfg.h" -#include "newtitles.h" - -#define NEW_SECONDS 24 * 60 * 60 -#define GAMETITLES "gametitles.txt" - -NewTitles *NewTitles::instance = NULL; - -NewTitles* NewTitles::Instance() -{ - if (instance == NULL) { - instance = new NewTitles(); - } - return instance; -} - -void NewTitles::DestroyInstance() -{ - if (instance != NULL) - { - delete instance; - instance = NULL; - } -} - -NewTitles::NewTitles() -{ - firstTitle = lastTitle = NULL; - isDirty = isNewFile = false; - - // Read the text file - char path[255]; - strcpy(path, Settings.titlestxt_path); - path[strlen(Settings.titlestxt_path) - 1] = '/'; - strcat(path, GAMETITLES); - - char line[20]; - FILE *fp = fopen(path, "r"); - if (fp != NULL) { - while (fgets(line, sizeof(line), fp)) { - // This is one line - if (line[0] != '#' || line[0] != ';') { - Title *title = new Title(); - if (sscanf(line, "%6c:%ld", (u8 *) &title->titleId, &title->timestamp) == 2) { - if (firstTitle == NULL) { - firstTitle = title; - lastTitle = title; - } else { - lastTitle->next = title; - lastTitle = title; - } - } - else { - delete title; // Invalid title entry, ignore - } - } - } - - fclose(fp); - } else { - isNewFile = true; - } -} - -NewTitles::~NewTitles() -{ - Save(); - - Title *t = firstTitle; - while (t != NULL) { - Title *temp = (Title *) t->next; - delete t; - t = temp; - } - firstTitle = lastTitle = NULL; -} - -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 - if (strcmp((const char *) titleid, (const char *) t->titleId) == 0) { - return; // Game found, which is excellent - } - t = (Title *) t->next; - } - - // Not found, add it - t = new Title(); - strncpy((char *) t->titleId, (char *) titleid, 6); - t->timestamp = time(NULL); - if (isNewFile) { - t->timestamp -= (NEW_SECONDS + 1); // Mark all games as not new if this is a new file - } - - if (firstTitle == NULL) { - firstTitle = t; - lastTitle = t; - } else { - lastTitle -> next = t; - lastTitle = t; - } - isDirty = true; -} - -bool NewTitles::IsNew(u8 *titleid) -{ - if (titleid == NULL || strlen((char *) titleid) == 0) { - return false; - } - - Title *t = firstTitle; - - while (t != NULL) { - // Loop all titles, search for the correct titleid - if (strcmp((const char *) titleid, (const char *) t->titleId) == 0) { - // This title is less than 24 hours old - if ((time(NULL) - t->timestamp) < NEW_SECONDS) { - // Only count the game as new when it's never been played through GX - Game_NUM *gnum = CFG_get_game_num(titleid); - return gnum == NULL || gnum->count == 0; - } - return false; - } - t = (Title *) t->next; - } - // We should never get here, since all files should be added by now! - CheckGame(titleid); - - return !isNewFile; // If this is a new file, return false -} - -void NewTitles::Remove(u8 *titleid) -{ - Title *t = firstTitle, *prev = NULL; - while (t != NULL) { - if (strcmp((const char *) titleid, (const char *) t->titleId) == 0) { - if (prev == NULL) { - firstTitle = (Title *) t->next; - } else { - prev->next = t->next; - } - delete t; - isDirty = true; - - return; - } - prev = t; - t = (Title *) t->next; - } -} - -void NewTitles::Save() -{ - if (!isDirty) return; - - char path[255]; - strcpy(path, Settings.titlestxt_path); - path[strlen(Settings.titlestxt_path) - 1] = '/'; - strcat(path, GAMETITLES); - - FILE *fp = fopen(path, "w"); - if (fp != NULL) { - Title *t = firstTitle; - while (t != NULL && strlen((char *) t->titleId) > 0) { - fprintf(fp, "%s:%ld\n", t->titleId, t->timestamp); - t = (Title *) t->next; - } - fclose(fp); - } -} +#include +#include + +#include "cfg.h" +#include "newtitles.h" + +#define NEW_SECONDS 24 * 60 * 60 +#define GAMETITLES "gametitles.txt" + +NewTitles *NewTitles::instance = NULL; + +NewTitles* NewTitles::Instance() +{ + if (instance == NULL) { + instance = new NewTitles(); + } + return instance; +} + +void NewTitles::DestroyInstance() +{ + if (instance != NULL) + { + delete instance; + instance = NULL; + } +} + +NewTitles::NewTitles() +{ + firstTitle = lastTitle = NULL; + isDirty = isNewFile = false; + + // Read the text file + char path[255]; + strcpy(path, Settings.titlestxt_path); + path[strlen(Settings.titlestxt_path) - 1] = '/'; + strcat(path, GAMETITLES); + + char line[20]; + FILE *fp = fopen(path, "r"); + if (fp != NULL) { + while (fgets(line, sizeof(line), fp)) { + // This is one line + if (line[0] != '#' || line[0] != ';') { + Title *title = new Title(); + if (sscanf(line, "%6c:%ld", (u8 *) &title->titleId, &title->timestamp) == 2) { + if (firstTitle == NULL) { + firstTitle = title; + lastTitle = title; + } else { + lastTitle->next = title; + lastTitle = title; + } + } + else { + delete title; // Invalid title entry, ignore + } + } + } + + fclose(fp); + } else { + isNewFile = true; + } +} + +NewTitles::~NewTitles() +{ + Save(); + + Title *t = firstTitle; + while (t != NULL) { + Title *temp = (Title *) t->next; + delete t; + t = temp; + } + firstTitle = lastTitle = NULL; +} + +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 + if (strcmp((const char *) titleid, (const char *) t->titleId) == 0) { + return; // Game found, which is excellent + } + t = (Title *) t->next; + } + + // Not found, add it + t = new Title(); + strncpy((char *) t->titleId, (char *) titleid, 6); + t->timestamp = time(NULL); + if (isNewFile) { + t->timestamp -= (NEW_SECONDS + 1); // Mark all games as not new if this is a new file + } + + if (firstTitle == NULL) { + firstTitle = t; + lastTitle = t; + } else { + lastTitle -> next = t; + lastTitle = t; + } + isDirty = true; +} + +bool NewTitles::IsNew(u8 *titleid) +{ + if (titleid == NULL || strlen((char *) titleid) == 0) + return false; + + Title *t = firstTitle; + + while (t != NULL) { + // Loop all titles, search for the correct titleid + if (strcmp((const char *) titleid, (const char *) t->titleId) == 0) { + // This title is less than 24 hours old + if ((time(NULL) - t->timestamp) < NEW_SECONDS) { + // Only count the game as new when it's never been played through GX + Game_NUM *gnum = CFG_get_game_num(titleid); + return gnum == NULL || gnum->count == 0; + } + return false; + } + t = (Title *) t->next; + } + // We should never get here, since all files should be added by now! + CheckGame(titleid); + + return !isNewFile; // If this is a new file, return false +} + +void NewTitles::Remove(u8 *titleid) +{ + if (titleid == NULL || strlen((char *) titleid) == 0) + return; + + Title *t = firstTitle, *prev = NULL; + while (t != NULL) { + if (strcmp((const char *) titleid, (const char *) t->titleId) == 0) { + if (prev == NULL) { + firstTitle = (Title *) t->next; + } else { + prev->next = t->next; + } + delete t; + isDirty = true; + + return; + } + prev = t; + t = (Title *) t->next; + } +} + +void NewTitles::Save() +{ + if (!isDirty) return; + + char path[255]; + strcpy(path, Settings.titlestxt_path); + path[strlen(Settings.titlestxt_path) - 1] = '/'; + strcat(path, GAMETITLES); + + FILE *fp = fopen(path, "w"); + if (fp != NULL) { + Title *t = firstTitle; + while (t != NULL && strlen((char *) t->titleId) > 0) { + fprintf(fp, "%s:%ld\n", t->titleId, t->timestamp); + t = (Title *) t->next; + } + fclose(fp); + } +} diff --git a/source/usbloader/GameList.cpp b/source/usbloader/GameList.cpp new file mode 100644 index 00000000..590698fa --- /dev/null +++ b/source/usbloader/GameList.cpp @@ -0,0 +1,281 @@ + /**************************************************************************** + * Copyright (C) 2010 + * 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. + ***************************************************************************/ +#include +#include +#include +#include "usbloader/wbfs.h" +#include "settings/newtitles.h" +#include "settings/cfg.h" +#include "xml/xml.h" +#include "FreeTypeGX.h" +#include "GameList.h" +#include "memory.h" + +GameList gameList; + +GameList::GameList() +{ + +} + +void GameList::clear() +{ + FullGameList.clear(); + FilteredList.clear(); + //! Clear memory of the vector completely + std::vector().swap(FilteredList); + std::vector().swap(FullGameList); +} + +struct discHdr * GameList::at(int i) +{ + if(i < 0 || i >= (int) FilteredList.size()) + return NULL; + + return FilteredList[i]; +} + +int GameList::ReadGameList() +{ + FullGameList.clear(); + FilteredList.clear(); + + // Retrieve all stuff from WBFS + u32 cnt; + + int ret = WBFS_GetCount(&cnt); + if (ret < 0) + return -1; + + /* Buffer length */ + u32 len = sizeof(struct discHdr) * cnt; + + /* Allocate memory */ + struct discHdr *buffer = (struct discHdr *) allocate_memory(len); + if (!buffer) + return -1; + + /* Clear buffer */ + memset(buffer, 0, len); + + /* Get header list */ + ret = WBFS_GetHeaders(buffer, cnt, sizeof(struct discHdr)); + if (ret < 0) + { + if (buffer) + free(buffer); + return -1; + } + + FullGameList.resize(cnt); + memcpy(&FullGameList[0], buffer, len); + + free(buffer); + + return LoadUnfiltered(); +} + +static bool WCharSortCallback(const wchar_t char1, const wchar_t char2) +{ + return char2 > char1; +} + +int GameList::FilterList(const wchar_t * gameFilter) +{ + if(FullGameList.size() == 0) + ReadGameList(); + if(gameFilter) + GameFilter.assign(gameFilter); + + FilteredList.clear(); + AvailableSearchChars.clear(); + + for (u32 i = 0; i < FullGameList.size(); ++i) + { + struct discHdr *header = &FullGameList[i]; + + /* Register game */ + NewTitles::Instance()->CheckGame(header->id); + + /* Filters */ + if (Settings.fave) + { + struct Game_NUM* game_num = CFG_get_game_num(header->id); + if (!game_num || game_num->favorite==0) + continue; + } + + //ignore uLoader cfg "iso". i was told it is "__CFG_" but not confirmed + if (strncasecmp((char*)header->id, "__CFG_", 6) == 0) + continue; + + if (Settings.parentalcontrol && !Settings.godmode) + if (get_block(header) >= Settings.parentalcontrol) + continue; + + /* Other parental control method */ + if (Settings.parentalcontrol == 0 && Settings.godmode == 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 *gameName = charToWideChar(get_title(header)); + + if(gameName && *GameFilter.c_str()) + { + if(wcsnicmp(gameName, GameFilter.c_str(), GameFilter.size()) != 0) + { + delete [] gameName; + continue; + } + } + + if(gameName) + { + if(wcslen(gameName) > GameFilter.size() && AvailableSearchChars.find(gameName[GameFilter.size()]) == std::string::npos) + AvailableSearchChars.push_back(gameName[GameFilter.size()]); + delete [] gameName; + } + + FilteredList.push_back(header); + } + + NewTitles::Instance()->Save(); + + AvailableSearchChars.push_back(L'\0'); + + if(FilteredList.size() < 2) + AvailableSearchChars.clear(); + + SortList(); + + return FilteredList.size(); +} + +int GameList::LoadUnfiltered() +{ + if(FullGameList.size() == 0) + ReadGameList(); + + GameFilter.clear(); + AvailableSearchChars.clear(); + FilteredList.clear(); + + for (u32 i = 0; i < FullGameList.size(); ++i) + { + struct discHdr *header = &FullGameList[i]; + + /* Register game */ + NewTitles::Instance()->CheckGame(header->id); + + wchar_t *gameName = charToWideChar(get_title(header)); + if(gameName) + { + if(wcslen(gameName) > GameFilter.size() && AvailableSearchChars.find(gameName[GameFilter.size()]) == std::string::npos) + AvailableSearchChars.push_back(gameName[GameFilter.size()]); + delete [] gameName; + } + + FilteredList.push_back(header); + } + + NewTitles::Instance()->Save(); + + AvailableSearchChars.push_back(L'\0'); + + if(FilteredList.size() < 2) + AvailableSearchChars.clear(); + + SortList(); + + return FilteredList.size(); +} + +void GameList::SortList() +{ + if(FilteredList.size() < 2) + return; + + if (Settings.sort == PLAYCOUNT) + { + std::sort(FilteredList.begin(), FilteredList.end(), PlaycountSortCallback); + } + else if (Settings.fave) + { + std::sort(FilteredList.begin(), FilteredList.end(), FavoriteSortCallback); + } + else + { + std::sort(FilteredList.begin(), FilteredList.end(), NameSortCallback); + } + + if(AvailableSearchChars.size() > 1) + std::sort(AvailableSearchChars.begin(), AvailableSearchChars.end(), WCharSortCallback); + +} + +bool GameList::NameSortCallback(const struct discHdr *a, const struct discHdr *b) +{ + return (strcasecmp(get_title((struct discHdr *) a), get_title((struct discHdr *) b)) < 0); +} + +bool GameList::PlaycountSortCallback(const struct discHdr *a, const struct discHdr *b) +{ + struct Game_NUM* game_num1 = CFG_get_game_num(a->id); + struct Game_NUM* game_num2 = CFG_get_game_num(b->id); + int count1 = 0, count2 = 0; + + if(game_num1) + count1 = game_num1->count; + if(game_num2) + count2 = game_num2->count; + + if(count1 == count2) + return NameSortCallback(a, b); + + return (count1 > count2); +} + +bool GameList::FavoriteSortCallback(const struct discHdr *a, const struct discHdr *b) +{ + struct Game_NUM* game_num1 = CFG_get_game_num(a->id); + struct Game_NUM* game_num2 = CFG_get_game_num(b->id); + int fav1 = 0, fav2 = 0; + + if(game_num1) + fav1 = game_num1->favorite; + if(game_num2) + fav2 = game_num2->favorite; + + if(fav1 == fav2); + return NameSortCallback(a, b); + + return (fav1 > fav2); +} diff --git a/source/usbloader/GameList.h b/source/usbloader/GameList.h new file mode 100644 index 00000000..b5e6b113 --- /dev/null +++ b/source/usbloader/GameList.h @@ -0,0 +1,36 @@ +#ifndef GAME_LIST_H_ +#define GAME_LIST_H_ + +#include +#include "wstring.hpp" +#include "usbloader/disc.h" + +class GameList +{ + public: + GameList(); + int ReadGameList(); + int size() { return FilteredList.size(); }; + int GameCount() { return FullGameList.size(); }; + int FilterList(const wchar_t * gameFilter = NULL); + int LoadUnfiltered(); + struct discHdr * at(int i); + struct discHdr * operator[](int i) { return at(i); }; + const wchar_t * GetCurrentFilter() { return GameFilter.c_str(); }; + const wchar_t * GetAvailableSearchChars() { return AvailableSearchChars.c_str(); }; + void SortList(); + void clear(); + protected: + static bool NameSortCallback(const struct discHdr *a, const struct discHdr *b); + static bool PlaycountSortCallback(const struct discHdr *a, const struct discHdr *b); + static bool FavoriteSortCallback(const struct discHdr *a, const struct discHdr *b); + + wString AvailableSearchChars; + wString GameFilter; + std::vector FilteredList; + std::vector FullGameList; +}; + +extern GameList gameList; + +#endif diff --git a/source/usbloader/disc.h b/source/usbloader/disc.h index 2effe5c2..4986782f 100644 --- a/source/usbloader/disc.h +++ b/source/usbloader/disc.h @@ -6,52 +6,54 @@ #ifdef __cplusplus extern "C" { #endif - /* Disc header structure */ - struct discHdr { - /* Game ID */ - u8 id[6]; - /* Game version */ - u16 version; +/* Disc header structure */ +struct discHdr +{ + /* Game ID */ + u8 id[6]; - /* Audio streaming */ - u8 streaming; - u8 bufsize; + /* Game version */ + u16 version; - /* Padding */ - u8 is_ciso; - u8 unused1[13]; + /* Audio streaming */ + u8 streaming; + u8 bufsize; - /* Magic word */ - u32 magic; + /* Padding */ + u8 is_ciso; + u8 unused1[13]; - /* Padding */ - u8 unused2[4]; + /* Magic word */ + u32 magic; - /* Game title */ - char title[64]; + /* Padding */ + u8 unused2[4]; - /* Encryption/Hashing */ - u8 encryption; - u8 h3_verify; + /* Game title */ + char title[64]; - /* Padding */ - u8 unused3[30]; - } ATTRIBUTE_PACKED; + /* Encryption/Hashing */ + u8 encryption; + u8 h3_verify; - /* Prototypes */ - s32 Disc_Init(void); - s32 Disc_Open(void); - s32 Disc_Wait(void); - void __Disc_SetLowMem(void); - s32 Disc_SetUSB(const u8 *); - s32 Disc_ReadHeader(void *); - s32 Disc_IsWii(void); - s32 Disc_BootPartition(u64, u8, u8, u8, u8, u8, u8, u32); - s32 Disc_WiiBoot(u8, u8, u8, u8, u8, u8, u32); - s32 __Disc_FindPartition(u64 *outbuf); - void PatchCountryStrings(void *Address, int Size); - s32 __Disc_FindPartition(u64 *outbuf); + /* Padding */ + u8 unused3[30]; +} ATTRIBUTE_PACKED; + +/* Prototypes */ +s32 Disc_Init(void); +s32 Disc_Open(void); +s32 Disc_Wait(void); +void __Disc_SetLowMem(void); +s32 Disc_SetUSB(const u8 *); +s32 Disc_ReadHeader(void *); +s32 Disc_IsWii(void); +s32 Disc_BootPartition(u64, u8, u8, u8, u8, u8, u8, u32); +s32 Disc_WiiBoot(u8, u8, u8, u8, u8, u8, u32); +s32 __Disc_FindPartition(u64 *outbuf); +void PatchCountryStrings(void *Address, int Size); +s32 __Disc_FindPartition(u64 *outbuf); #ifdef __cplusplus } diff --git a/source/usbloader/getentries.cpp b/source/usbloader/getentries.cpp deleted file mode 100644 index 8d0fb44a..00000000 --- a/source/usbloader/getentries.cpp +++ /dev/null @@ -1,642 +0,0 @@ -#include - -#include "settings/cfg.h" -#include "usbloader/wbfs.h" -#include "main.h" -#include -#include "getentries.h" -#include "settings/newtitles.h" - -#include "../prompts/TitleBrowser.h" -#include "prompts/PromptWindows.h" - -#include "wad/wad.h" -#include "xml/xml.h" -#include "../wad/title.h" -#include -#include -#include - -#include "gecko.h" - -#include "listfiles.h" -#define typei 0x00010001 - -#define DEBUG_GAMELIST - -struct discHdr * gameList=NULL; -s32 gameSelected=0, gameStart=0; -u32 gameCnt=0; -wchar_t *gameFilter=NULL; -wchar_t *gameFilterNextList=NULL; -wchar_t *gameFilterPrev=NULL; - -struct discHdr * fullGameList = NULL; -s32 fullGameCnt = -1; - -extern u8 mountMethod; - -/**************************************************************************** - * wcsdup_new based on new wchar_t [...] - ***************************************************************************/ -static wchar_t *wcsdup_new(const wchar_t *src) -{ - int len = wcslen(src)+1; - wchar_t *dst = new wchar_t[len]; - if(dst) wcscpy(dst, src); - return dst; -} -static inline int wcsnicmp(const wchar_t *s1, const wchar_t *s2, int len) -{ - if (len <= 0) - return (0); - do - { - int r = towupper(*s1) - towupper(*s2++); - if (r) return r; - if (*s1++ == 0) - break; - } while (--len != 0); - - return (0); -} - - -/**************************************************************************** - * EntryCmp - ***************************************************************************/ -s32 __Menu_EntryCmp(const void *a, const void *b) -{ - struct discHdr *hdr1 = (struct discHdr *)a; - struct discHdr *hdr2 = (struct discHdr *)b; - - /* Compare strings */ - return stricmp(get_title(hdr1), get_title(hdr2)); -} - -s32 __Menu_EntryCmpCount(const void *a, const void *b) { - s32 ret; - - struct discHdr *hdr1 = (struct discHdr *)a; - - struct discHdr *hdr2 = (struct discHdr *)b; - - /* Compare Play Count */ - u16 count1 = 0; - u16 count2 = 0; - struct Game_NUM* game_num1 = CFG_get_game_num(hdr1->id); - struct Game_NUM* game_num2 = CFG_get_game_num(hdr2->id); - - if (game_num1) count1 = game_num1->count; - if (game_num2) count2 = game_num2->count; - - ret = (s32) (count2-count1); - if (ret == 0) return stricmp(get_title(hdr1), get_title(hdr2)); - - return ret; -} - -s32 __Menu_EntryCmpFavorite(const void *a, const void *b) { - s32 ret; - - struct discHdr *hdr1 = (struct discHdr *)a; - - struct discHdr *hdr2 = (struct discHdr *)b; - - /* Compare Favorite (rank) */ - u16 fav1 = 0; - u16 fav2 = 0; - struct Game_NUM* game_num1 = CFG_get_game_num(hdr1->id); - struct Game_NUM* game_num2 = CFG_get_game_num(hdr2->id); - - if (game_num1) fav1 = game_num1->favorite; - if (game_num2) fav2 = game_num2->favorite; - - ret = (s32) (fav2-fav1); - if (ret == 0) return stricmp(get_title(hdr1), get_title(hdr2)); - - return ret; -} - -void ResetGamelist() -{ - if (fullGameList != NULL) - { - fullGameCnt = -1; - free(fullGameList); - fullGameList = NULL; - } -} - -int GetFullHeaders(struct discHdr **headers, u32 *count) -{ - if (fullGameList == NULL || fullGameCnt == -1) - { -#ifdef DEBUG_GAMELIST - gprintf("\nRetrieving gamelist from WBFS"); -#endif - // Retrieve all stuff from WBFS - u32 cnt; - - int ret = WBFS_GetCount(&cnt); - if (ret < 0) - return ret; - - /* Buffer length */ - u32 len = sizeof(struct discHdr) * cnt; - - /* Allocate memory */ - struct discHdr *buffer = (struct discHdr *)memalign(32, len); - if (!buffer) - return -1; - - /* Clear buffer */ - memset(buffer, 0, len); - - /* Get header list */ - ret = WBFS_GetHeaders(buffer, cnt, sizeof(struct discHdr)); - if (ret < 0) { - if (buffer) free(buffer); - return ret; - } - - fullGameList = buffer; - fullGameCnt = cnt; - } - else{ -#ifdef DEBUG_GAMELIST - gprintf("\n\tRetrieving gamelist from cache"); -#endif - } - *count = fullGameCnt; - if (headers != NULL) - { - *headers = fullGameList; - } - - return 0; -} - -/**************************************************************************** - * Get PrevFilter - ***************************************************************************/ -int __Menu_GetPrevFilter(int t, wchar_t* gameFilter, u32 gameFiltered, wchar_t **PgameFilterPrev) -{ - - std::vector nameList; - - struct discHdr *buffer = NULL; // DO NOT FREE THIS BUFFER, IT'S A REFERENCE - u32 cnt, len, i; - - wchar_t *new_gameFilterPrev = wcsdup_new(gameFilter); - - if (GetFullHeaders(&buffer, &cnt)) - { - return -1; - } - - /* Fill nameList */ - for (i = 0; i < cnt; i++) - { - struct discHdr *header = &buffer[i]; - - /* Filter Favorite */ - if (Settings.fave && t==0) - { - struct Game_NUM* game_num = CFG_get_game_num(header->id); - if (!game_num || game_num->favorite==0) - continue; - } - /* Filter Pparental */ - if (Settings.parentalcontrol && !Settings.godmode && t==0) - if(get_block(header) >= Settings.parentalcontrol) - continue; - - /* Other parental control method */ - if (Settings.parentalcontrol == 0 && Settings.godmode == 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 = charToWideChar(get_title(header)); - if(wname) nameList.push_back(wname); - } - - /* Find Prev-Filter */ - len = wcslen(new_gameFilterPrev); - while(len) - { - cnt = 0; - new_gameFilterPrev[--len] = 0; - for(std::vector::iterator iter = nameList.begin(); iter < nameList.end(); iter++) - { - if(!wcsncmp(*iter, new_gameFilterPrev, len)) - cnt++; - } - if(cnt > gameFiltered) - break; - } - /* Clean name List */ - for(std::vector::iterator iter = nameList.begin(); iter < nameList.end(); iter++) - delete [] *iter; - - if(PgameFilterPrev) - *PgameFilterPrev = new_gameFilterPrev; - - return 0; -} -/**************************************************************************** - * Get GameFilter NextList - ***************************************************************************/ - -int int_cmp(const void *a, const void *b) { return *((u32*)a)-*((u32*)b); } - -int __Menu_GetGameFilter_NextList(discHdr *gameList, u32 gameCnt, wchar_t **PgameFilter, wchar_t **PgameFilterNextList) -{ - u32 filter_len = wcslen(*PgameFilter); - u32 i, lastChar=0; - bool autofill = filter_len > 0; // autofill only when gameFilter is not empty - wchar_t *p; - u32 *nextList = new u32[gameCnt]; if(nextList==NULL) return -1; - for(i=0; i filter_len) - { - if((filter_len == 0 || !wcsnicmp(*PgameFilter, gameName, filter_len))) - nextFilterChar = towupper(gameName[filter_len]); - } - else if(wcslen(gameName) == filter_len) - autofill = false; // no autofill when gameNameLen == filterLen - - nextList[i] = nextFilterChar; - } - qsort(nextList, gameCnt, sizeof(u32), int_cmp); - - *PgameFilterNextList = new wchar_t[gameCnt+1]; - if(*PgameFilterNextList == NULL) goto error; - - - p = *PgameFilterNextList; - lastChar = 0; - for(i=0; ititle,sizeof(header->title),"%s",tmp); - //break; - } - } - } - if (!found) { - if (getName00(header->title, TITLE_ID(i=0) - found=2; - - if (!found) { - if (getNameBN(header->title, TITLE_ID(i=0) - found=3; - - if (!found) - snprintf(header->title,sizeof(header->title),"%s (%08x)",text,iid[0]=text[0]; - header->id[1]=text[1]; - header->id[2]=text[2]; - header->id[3]=text[3]; - header->id[4]='1'; - header->id[5]=(i - -//not using these filters right now, but i left them in just in case - // Filters - /*if (Settings.fave) { - struct Game_NUM* game_num = CFG_get_game_num(header->id); - if (!game_num || game_num->favorite==0) - continue; - } - - if (Settings.parentalcontrol && !Settings.godmode) { - if (get_block(header) >= Settings.parentalcontrol) - continue; - }*/ - - if(gameFilter && *gameFilter) { - u32 filter_len = wcslen(gameFilter); - wchar_t *gameName = charToWideChar(get_title(header)); - if (!gameName || wcsnicmp(gameName, gameFilter, filter_len)) { - delete [] gameName; - continue; - } - } - if(i != cnt2) - buffer[cnt2] = buffer[i]; - cnt2++; - } - i++; - } - - if (f)fclose(f); - - Uninstall_FromTitle(TITLE_ID(1, 0)); - ISFS_Deinitialize(); - - if(cnt > cnt2) - { - cnt = cnt2; - buffer = (struct discHdr *)realloc(buffer, sizeof(struct discHdr) * cnt); - } - if (!buffer) - return -1; - - if (Settings.sort==pcount) { - qsort(buffer, cnt, sizeof(struct discHdr), __Menu_EntryCmpCount); - } else if (Settings.fave) { - qsort(buffer, cnt, sizeof(struct discHdr), __Menu_EntryCmpFavorite); - } else { - qsort(buffer, cnt, sizeof(struct discHdr), __Menu_EntryCmp); - } - /*PgameList = buffer; - buffer = NULL; - PgameCnt = cnt;*/ - - if(PgameList) *PgameList = buffer; else free(buffer); - if(PgameCnt) *PgameCnt = cnt; - - return 0; - - return cnt; -} - - -/**************************************************************************** - * Get Gamelist - ***************************************************************************/ -int __Menu_GetGameList(int t, wchar_t* gameFilter, discHdr ** PgameList, u32 *PgameCnt) { - struct discHdr *buffer = NULL; - struct discHdr *output = NULL; - - u32 cnt, cnt2=0; - - if (GetFullHeaders(&buffer, &cnt)) - { - return -1; - } - - int len = cnt * sizeof(struct discHdr); - output = (struct discHdr *) memalign(32, len); - memset(output, 0, len); - - for (u32 i = 0; i < cnt; i++) { - struct discHdr *header = &buffer[i]; - - /* Register game */ - NewTitles::Instance()->CheckGame(header->id); - - /* Filters */ - if (Settings.fave && t==0) { - struct Game_NUM* game_num = CFG_get_game_num(header->id); - if (!game_num || game_num->favorite==0) - continue; - } - - //ignore uLoader cfg "iso". i was told it is "__CFG_" but not confirmed - if (header->id[0]=='_'&&header->id[1]=='_'&& - header->id[2]=='C'&&header->id[3]=='F'&& - header->id[4]=='G'&&header->id[5]=='_') - continue; - - if (Settings.parentalcontrol && !Settings.godmode && t==0) { - if (get_block(header) >= Settings.parentalcontrol) - continue; - } - - /* Other parental control method */ - if (Settings.parentalcontrol == 0 && Settings.godmode == 0 && Settings.parental.enabled == 1 && t==0) - { - // 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); - wchar_t *gameName = charToWideChar(get_title(header)); - if (!gameName || wcsnicmp(gameName, gameFilter, filter_len)) { - delete [] gameName; - continue; - } - } - output[cnt2] = buffer[i]; - cnt2++; - } - NewTitles::Instance()->Save(); - - if(cnt > cnt2) - { - cnt = cnt2; - output = (struct discHdr *)realloc(output, sizeof(struct discHdr) * cnt); - } - if (!output) - return -1; -#ifdef DEBUG_GAMELIST - gprintf("\n\tAfter retrieval, gamecount: %d", cnt); -#endif - if (Settings.sort==pcount) { - qsort(output, cnt, sizeof(struct discHdr), __Menu_EntryCmpCount); - } else if (Settings.fave) { - qsort(output, cnt, sizeof(struct discHdr), __Menu_EntryCmpFavorite); - } else { - qsort(output, cnt, sizeof(struct discHdr), __Menu_EntryCmp); - } - - /* Set values */ - if(PgameList) *PgameList = output; else free(output); - if(PgameCnt) *PgameCnt = cnt; - - return 0; -} - -int __Menu_GetEntries(int t, const wchar_t* Filter) { - - /*if (mountMethod==3) - { - return buildTitleList(); - }*/ - - - u32 new_gameCnt = 0; - struct discHdr *new_gameList = NULL; - wchar_t *new_gameFilter = NULL; - wchar_t *new_gameFilterNextList = NULL; - wchar_t *new_gameFilterPrev = NULL; - - new_gameFilter = wcsdup_new(Filter ? Filter : (gameFilter ? gameFilter : L"") ); - if(new_gameFilter == NULL) return -1; - - for(;;) - { - if (mountMethod==3) - {if(buildTitleList(t, new_gameFilter, &new_gameList, &new_gameCnt) < 0) - return -1;} - - else - {if(__Menu_GetGameList(t, new_gameFilter, &new_gameList, &new_gameCnt) < 0) - return -1;} - - - if(new_gameCnt > 0 || new_gameFilter[0] == 0) - break; - new_gameFilter[wcslen(new_gameFilter)-1] = 0; - } - - /* init GameFilterNextList */ - if(__Menu_GetGameFilter_NextList(new_gameList, new_gameCnt, &new_gameFilter, &new_gameFilterNextList) < 0) - goto error; - - /* init GameFilterPrev */ - if(__Menu_GetPrevFilter(t, new_gameFilter, new_gameCnt, &new_gameFilterPrev) < 0) - goto error; - - /* Set values */ - if(gameList) free(gameList); - if(gameFilter) delete [] gameFilter; - if(gameFilterNextList) delete [] gameFilterNextList; - if(gameFilterPrev) delete [] gameFilterPrev; - - gameList = new_gameList; - gameCnt = new_gameCnt; - gameFilter = new_gameFilter; - gameFilterNextList = new_gameFilterNextList; - gameFilterPrev = new_gameFilterPrev; - - /* Reset variables */ - gameSelected = gameStart = 0; - return 0; -error: // clean up - if(new_gameList) free(new_gameList); - if(new_gameFilter) delete [] new_gameFilter; - if(new_gameFilterNextList) delete [] new_gameFilterNextList; - if(new_gameFilterPrev) delete [] new_gameFilterPrev; - return -1; -} diff --git a/source/usbloader/getentries.h b/source/usbloader/getentries.h deleted file mode 100644 index a60f0fff..00000000 --- a/source/usbloader/getentries.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** - * PromptWindows - * USB Loader GX 2009 - * - * PromptWindows.h - ***************************************************************************/ - -#ifndef _GETENTRIES_H_ -#define _GETENTRIES_H_ - -#include - -struct discHdr; -extern discHdr *gameList; -extern u32 gameCnt; -extern wchar_t *gameFilter; -extern wchar_t *gameFilterNextList; -extern wchar_t *gameFilterPrev; - -//! param t -//! make this 1 if you want the function to ignore the rules -//! (settings and parental control) when making the game list. -//! -//! param Filter -//! set this Parameter to Filter the List -//! if this Parameter=NULL then the filter is not changed -//! if this Parameter="" then no filter is activ -//! -int __Menu_GetEntries(int t=0, const wchar_t* Filter=NULL); -s32 __Menu_EntryCmpCount(const void *a, const void *b); -s32 __Menu_EntryCmp(const void *a, const void *b); -void ResetGamelist(); - -#endif diff --git a/source/usbloader/wbfs.cpp b/source/usbloader/wbfs.cpp index 0b4fea64..29dc803b 100644 --- a/source/usbloader/wbfs.cpp +++ b/source/usbloader/wbfs.cpp @@ -11,7 +11,7 @@ #include "usbloader/wbfs/wbfs_ntfs.h" #include "usbloader/partition_usbloader.h" -#include "usbloader/getentries.h" +#include "usbloader/GameList.h" #include "gecko.h" Wbfs *current = NULL; @@ -38,8 +38,9 @@ wbfs_t *GetHddInfo(void) { return current->GetHddInfo(); } -s32 WBFS_Init(u32 device) { - return Wbfs::Init(device); +s32 WBFS_Init(u32 device) +{ + return Wbfs::Init(device); } s32 WBFS_Open(void) { @@ -188,7 +189,7 @@ bool WBFS_Close(void) wbfs_part_lba = 0; wbfs_fs_drive[0] = '\0'; - ResetGamelist(); + gameList.clear(); return 0; } @@ -216,17 +217,17 @@ s32 WBFS_CheckGame(u8 *discid) { s32 WBFS_AddGame(void) { s32 retval = current->AddGame(); - if (retval == 0) { - ResetGamelist(); - } + if (retval == 0) + gameList.clear(); + return retval; } s32 WBFS_RemoveGame(u8 *discid) { s32 retval = current->RemoveGame(discid); - if (retval == 0) { - ResetGamelist(); - } + if (retval == 0) + gameList.clear(); + return retval; } @@ -240,17 +241,17 @@ s32 WBFS_DiskSpace(f32 *used, f32 *free) { s32 WBFS_RenameGame(u8 *discid, const void *newname) { s32 retval = current->RenameGame(discid, newname); - if (retval == 0) { - ResetGamelist(); - } + if (retval == 0) + gameList.clear(); + return retval; } s32 WBFS_ReIDGame(u8 *discid, const void *newID) { s32 retval = current->ReIDGame(discid, newID); - if (retval == 0) { - ResetGamelist(); - } + if (retval == 0) + gameList.clear(); + return retval; } diff --git a/source/wstring.cpp b/source/wstring.cpp index 778000a2..939b94a2 100644 --- a/source/wstring.cpp +++ b/source/wstring.cpp @@ -1,3 +1,4 @@ +#include #include "wstring.hpp" using namespace std; @@ -149,3 +150,19 @@ size_t utf8Len(const char *s) } return len; } + +int wcsnicmp(const wchar_t *s1, const wchar_t *s2, int len) +{ + if (len <= 0) + return (0); + + do + { + int r = towupper(*s1) - towupper(*s2++); + if (r) return r; + if (*s1++ == 0) + break; + } while (--len != 0); + + return (0); +} diff --git a/source/wstring.hpp b/source/wstring.hpp index 216294ad..381eda5b 100644 --- a/source/wstring.hpp +++ b/source/wstring.hpp @@ -20,6 +20,7 @@ public: }; size_t utf8Len(const char *s); +int wcsnicmp(const wchar_t *s1, const wchar_t *s2, int len); #endif // !defined(__WSTRING_HPP)