diff --git a/HBC/META.XML b/HBC/META.XML index 6ccbc7c8..4062b986 100644 --- a/HBC/META.XML +++ b/HBC/META.XML @@ -2,8 +2,8 @@ USB Loader GX USB Loader GX Team - 2.0 r1059 - 201101282120 + 2.0 r1060 + 201101301622 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. diff --git a/gui.pnproj b/gui.pnproj index a8353d93..2573a3c6 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/BoxCover/BoxCover.cpp b/source/BoxCover/BoxCover.cpp index 84174091..3921120c 100644 --- a/source/BoxCover/BoxCover.cpp +++ b/source/BoxCover/BoxCover.cpp @@ -169,8 +169,8 @@ void BoxCover::Draw() GX_LoadPosMtxImm(modelView, GX_PNMTX0); - GX_InvalidateTexAll(); GX_LoadTexObj(&boxBorderTex, GX_TEXMAP0); + GX_InvalidateTexAll(); //! Border quads GX_SetArray(GX_VA_POS, (void *) &g_boxMeshQ[0].pos, sizeof(g_boxMeshQ[0])); @@ -199,6 +199,7 @@ void BoxCover::Draw() GX_End(); GX_LoadTexObj(flatCover ? &defaultBoxTex : &coverTex, GX_TEXMAP0); + GX_InvalidateTexAll(); //! Back Cover GX_SetArray(GX_VA_POS, (void *) &g_boxBackCoverMesh[0].pos, sizeof(g_boxBackCoverMesh[0])); @@ -220,6 +221,7 @@ void BoxCover::Draw() { //! Front Flat Cover GX_LoadTexObj(&coverTex, GX_TEXMAP0); + GX_InvalidateTexAll(); GX_SetArray(GX_VA_POS, (void *) &g_flatCoverMesh[0].pos, sizeof(g_flatCoverMesh[0])); GX_SetArray(GX_VA_TEX0, (void *) &g_flatCoverMesh[0].texCoord, sizeof(g_flatCoverMesh[0])); diff --git a/source/Controls/DeviceHandler.cpp b/source/Controls/DeviceHandler.cpp index 35486740..586630aa 100644 --- a/source/Controls/DeviceHandler.cpp +++ b/source/Controls/DeviceHandler.cpp @@ -258,6 +258,7 @@ int DeviceHandler::GetUSBFilesystemType(int partition) PartitionHandle * usbHandle = instance->GetUSBHandle(); const char * FSName = usbHandle->GetFSName(partition); + if(!FSName) return -1; if(strncmp(FSName, "WBFS", 4) == 0) return PART_FS_WBFS; diff --git a/source/FileOperations/fileops.cpp b/source/FileOperations/fileops.cpp index c87ef8c4..ebe37717 100644 --- a/source/FileOperations/fileops.cpp +++ b/source/FileOperations/fileops.cpp @@ -43,94 +43,6 @@ static bool actioncanceled = false; -/**************************************************************************** - * FindFile - * - * Check if file is available in the given directory - ***************************************************************************/ -extern "C" bool FindFile(const char * filename, const char * path) -{ - if(!filename || ! path) - return false; - - DIR_ITER *dir = NULL; - struct stat st; - char currfilename[MAXPATHLEN]; - - dir = diropen(path); - if(!dir) - { - dirclose(dir); - return false; - } - - while (dirnext(dir,currfilename,&st) == 0) - { - if (strcasecmp(currfilename, filename) == 0) - { - dirclose(dir); - return true; - } - } - dirclose(dir); - return false; -} - -/**************************************************************************** - * SearchFile - * - * Search for a file recursive through all subdirectories - ***************************************************************************/ -extern "C" bool SearchFile(const char * searchpath, const char * searched_filename, char * outfilepath) -{ - struct stat st; - DIR_ITER *dir = NULL; - bool result = false; - - char filename[MAXPATHLEN]; - char pathptr[strlen(searchpath)+2]; - snprintf(pathptr, sizeof(pathptr), "%s", searchpath); - - if(pathptr[strlen(pathptr)-1] == '/') - { - pathptr[strlen(pathptr)-1] = '\0'; - } - - char * notRoot = strrchr(pathptr, '/'); - if(!notRoot) - { - strcat(pathptr, "/"); - } - - dir = diropen(pathptr); - if(!dir) - return false; - - while (dirnext(dir,filename,&st) == 0 && result == false) - { - if(strcasecmp(filename, searched_filename) == 0) - { - if(outfilepath) - { - sprintf(outfilepath, "%s/%s", pathptr, filename); - } - result = true; - } - else if((st.st_mode & S_IFDIR) != 0) - { - if(strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0) - { - char newpath[1024]; - snprintf(newpath, sizeof(newpath), "%s/%s", pathptr, filename); - result = SearchFile(newpath, searched_filename, outfilepath); - } - } - } - dirclose(dir); - - return result; -} - /**************************************************************************** * CheckFile * @@ -465,239 +377,6 @@ static inline void ClearList(std::vector &List) std::vector().swap(List); } -/**************************************************************************** - * CopyDirectory - * - * Copy recursive a complete source path to destination path - ***************************************************************************/ -extern "C" int CopyDirectory(const char * src, const char * dest) -{ - struct stat st; - DIR_ITER *dir = NULL; - - dir = diropen(src); - if(dir == NULL) - return -1; - - char *filename = (char *) malloc(MAXPATHLEN); - if(!filename) - { - dirclose(dir); - return -2; - } - - std::vector DirList; - std::vector FileList; - - while (dirnext(dir,filename,&st) == 0) - { - if(actioncanceled) - { - free(filename); - ClearList(DirList); - ClearList(FileList); - dirclose(dir); - return -10; - } - - if(st.st_mode & S_IFDIR) - { - if(strcmp(filename,".") != 0 && strcmp(filename,"..") != 0) - { - VectorResize(DirList); - DirList.push_back(strdup(filename)); - } - } - else - { - VectorResize(FileList); - FileList.push_back(strdup(filename)); - } - } - dirclose(dir); - free(filename); - filename = NULL; - - //! Ensure that empty directories are created - CreateSubfolder(dest); - - for(u32 i = 0; i < FileList.size(); ++i) - { - if(actioncanceled) - { - ClearList(DirList); - ClearList(FileList); - return -10; - } - - if(FileList[i]) - { - u32 strsize = strlen(src)+strlen(FileList[i])+1; - char currentname[strsize]; - char destname[strsize]; - sprintf(currentname, "%s%s", src, FileList[i]); - sprintf(destname, "%s%s", dest, FileList[i]); - free(FileList[i]); - FileList[i] = NULL; - CopyFile(currentname, destname); - } - } - - FileList.clear(); - ClearList(FileList); - - for(u32 i = 0; i < DirList.size(); ++i) - { - if(actioncanceled) - { - ClearList(DirList); - ClearList(FileList); - return -10; - } - - if(DirList[i]) - { - u32 strsize = strlen(src)+strlen(DirList[i])+2; - char currentname[strsize]; - char destname[strsize]; - sprintf(currentname, "%s%s/", src, DirList[i]); - sprintf(destname, "%s%s/", dest, DirList[i]); - free(DirList[i]); - DirList[i] = NULL; - CopyDirectory(currentname, destname); - } - } - - DirList.clear(); - ClearList(DirList); - - if(actioncanceled) - return -10; - - return 1; -} - -/**************************************************************************** - * MoveDirectory - * - * Move recursive a complete source path to destination path - ***************************************************************************/ -extern "C" int MoveDirectory(char * src, const char * dest) -{ - struct stat st; - DIR_ITER *dir = NULL; - - dir = diropen(src); - if(dir == NULL) - return -1; - - char *filename = (char *) malloc(MAXPATHLEN); - - if(!filename) - { - dirclose(dir); - return -2; - } - - std::vector DirList; - std::vector FileList; - - while (dirnext(dir,filename,&st) == 0) - { - if(actioncanceled) - { - free(filename); - ClearList(DirList); - ClearList(FileList); - dirclose(dir); - return -10; - } - - if(st.st_mode & S_IFDIR) - { - if(strcmp(filename,".") != 0 && strcmp(filename,"..") != 0) - { - VectorResize(DirList); - DirList.push_back(strdup(filename)); - } - } - else - { - VectorResize(FileList); - FileList.push_back(strdup(filename)); - } - } - dirclose(dir); - free(filename); - filename = NULL; - - //! Ensure that empty directories are created - CreateSubfolder(dest); - - for(u32 i = 0; i < FileList.size(); ++i) - { - if(actioncanceled) - { - ClearList(DirList); - ClearList(FileList); - return -10; - } - - if(FileList[i]) - { - u32 strsize = strlen(src)+strlen(FileList[i])+2; - char currentname[strsize]; - char destname[strsize]; - sprintf(currentname, "%s%s", src, FileList[i]); - sprintf(destname, "%s%s", dest, FileList[i]); - - MoveFile(currentname, destname); - - free(FileList[i]); - FileList[i] = NULL; - } - } - - FileList.clear(); - ClearList(FileList); - - for(u32 i = 0; i < DirList.size(); ++i) - { - if(actioncanceled) - { - ClearList(DirList); - ClearList(FileList); - return -10; - } - - if(DirList[i]) - { - u32 strsize = strlen(src)+strlen(DirList[i])+2; - char currentname[strsize]; - char destname[strsize]; - sprintf(currentname, "%s%s/", src, DirList[i]); - sprintf(destname, "%s%s/", dest, DirList[i]); - free(DirList[i]); - DirList[i] = NULL; - - MoveDirectory(currentname, destname); - } - } - - DirList.clear(); - ClearList(DirList); - - src[strlen(src)-1] = '\0'; - - if(actioncanceled) - return -10; - - if(remove(src) != 0) - return -1; - - return 1; -} - /**************************************************************************** * MoveFile * @@ -723,116 +402,6 @@ extern "C" int MoveFile(const char *srcpath, char *destdir) return -1; } -/**************************************************************************** - * RemoveDirectory - * - * Remove a directory and its content recursively - ***************************************************************************/ -extern "C" int RemoveDirectory(char * dirpath) -{ - struct stat st; - DIR_ITER *dir = NULL; - - dir = diropen(dirpath); - if(dir == NULL) - return -1; - - char * filename = (char *) malloc(MAXPATHLEN); - - if(!filename) - { - dirclose(dir); - return -2; - } - - std::vector DirList; - std::vector FileList; - - while (dirnext(dir,filename,&st) == 0) - { - if(actioncanceled) - { - free(filename); - ClearList(DirList); - ClearList(FileList); - dirclose(dir); - return -10; - } - - if(st.st_mode & S_IFDIR) - { - if(strcmp(filename,".") != 0 && strcmp(filename,"..") != 0) - { - VectorResize(DirList); - DirList.push_back(strdup(filename)); - } - } - else - { - VectorResize(FileList); - FileList.push_back(strdup(filename)); - } - } - dirclose(dir); - free(filename); - filename = NULL; - - for(u32 i = 0; i < FileList.size(); ++i) - { - if(actioncanceled) - { - ClearList(DirList); - ClearList(FileList); - return -10; - } - - if(FileList[i]) - { - u32 strsize = strlen(dirpath)+strlen(FileList[i])+2; - char fullpath[strsize]; - sprintf(fullpath, "%s%s", dirpath, FileList[i]); - RemoveFile(fullpath); - - //!Display Throbber rotating - free(FileList[i]); - FileList[i] = NULL; - } - } - FileList.clear(); - ClearList(FileList); - - for(u32 i = 0; i < DirList.size(); ++i) - { - if(actioncanceled) - { - ClearList(DirList); - ClearList(FileList); - return -10; - } - if(DirList[i]) - { - char fullpath[strlen(dirpath)+strlen(DirList[i])+2]; - sprintf(fullpath, "%s%s/", dirpath, DirList[i]); - free(DirList[i]); - DirList[i] = NULL; - - RemoveDirectory(fullpath); - } - } - DirList.clear(); - ClearList(DirList); - - dirpath[strlen(dirpath)-1] = '\0'; - - if(actioncanceled) - return -10; - - if(remove(dirpath) != 0) - return -1; - - return 1; -} - /**************************************************************************** * RemoveFile * @@ -852,62 +421,3 @@ extern "C" bool RenameFile(const char * srcpath, const char * destpath) { return (rename(srcpath, destpath) == 0); } - -/**************************************************************************** - * GetFolderSize - * - * Get recursivly complete foldersize - ***************************************************************************/ -extern "C" void GetFolderSize(const char * folderpath, u64 * foldersize, u32 * filecount) -{ - struct stat st; - DIR_ITER *dir = diropen(folderpath); - - if(dir == NULL) - return; - - char *filename = (char *) malloc(MAXPATHLEN); - - if(!filename) - { - dirclose(dir); - return; - } - - std::vector DirList; - - while (dirnext(dir,filename,&st) == 0) - { - if(st.st_mode & S_IFDIR) - { - if(strcmp(filename,".") != 0 && strcmp(filename,"..") != 0) - { - VectorResize(DirList); - DirList.push_back(strdup(filename)); - } - } - else - { - if(filecount) *filecount += 1; - if(foldersize) *foldersize += st.st_size; - } - } - dirclose(dir); - free(filename); - filename = NULL; - - for(u32 i = 0; i < DirList.size(); ++i) - { - if(DirList[i]) - { - char currentname[strlen(folderpath)+strlen(DirList[i])+2]; - sprintf(currentname, "%s%s/", folderpath, DirList[i]); - free(DirList[i]); - DirList[i] = NULL; - - GetFolderSize(currentname, foldersize, filecount); - } - } - DirList.clear(); - ClearList(DirList); -} diff --git a/source/FileOperations/fileops.h b/source/FileOperations/fileops.h index 6f16d88e..5df3bc75 100644 --- a/source/FileOperations/fileops.h +++ b/source/FileOperations/fileops.h @@ -35,20 +35,14 @@ extern "C" { #endif bool CreateSubfolder(const char * fullpath); -bool FindFile(const char * filename, const char * path); -bool SearchFile(const char * searchpath, const char * searched_filename, char * outfilepath); bool CheckFile(const char * filepath); u64 FileSize(const char * filepath); int LoadFileToMem(const char * filepath, u8 **buffer, u64 *size); int LoadFileToMemWithProgress(const char *progressText, const char *filePath, u8 **buffer, u64 *size); int CopyFile(const char * src, const char * dest); -int CopyDirectory(const char * src, const char * dest); -int MoveDirectory(char * src, const char * dest); int MoveFile(const char *srcpath, char *destdir); -int RemoveDirectory(char * dirpath); bool RenameFile(const char * srcpath, const char * destpath); bool RemoveFile(const char * filepath); -void GetFolderSize(const char * folderpath, u64 * foldersize, u32 * filenumber); #ifdef __cplusplus } diff --git a/source/SoundOperations/gui_bgm.cpp b/source/SoundOperations/gui_bgm.cpp index 316db100..3dffa875 100644 --- a/source/SoundOperations/gui_bgm.cpp +++ b/source/SoundOperations/gui_bgm.cpp @@ -4,7 +4,7 @@ * * Backgroundmusic ***************************************************************************/ -#include +#include #include "themes/CTheme.h" #include "gui_bgm.h" #include "menu.h" @@ -87,9 +87,9 @@ bool GuiBGM::ParsePath(const char * folderpath) char * LoadedFilename = strrchr(folderpath, '/') + 1; char filename[1024]; - struct stat st; + struct dirent * dirent = NULL; - DIR_ITER * dir = diropen(currentPath); + DIR * dir = opendir(currentPath); if (dir == NULL) { LoadStandard(); @@ -97,24 +97,27 @@ bool GuiBGM::ParsePath(const char * folderpath) } u32 counter = 0; - while (dirnext(dir, filename, &st) == 0) + while ((dirent = readdir(dir)) != 0) { + snprintf(filename, sizeof(filename), dirent->d_name); + char * fileext = strrchr(filename, '.'); - if (fileext) + if (!fileext) + continue; + + if (strcasecmp(fileext, ".mp3") == 0 || strcasecmp(fileext, ".ogg") == 0 || + strcasecmp(fileext, ".wav") == 0 || strcasecmp(fileext, ".aif") == 0) { - if (strcasecmp(fileext, ".mp3") == 0 || strcasecmp(fileext, ".ogg") == 0 || strcasecmp(fileext, ".wav") - == 0) - { - AddEntrie(filename); + AddEntrie(filename); - if (strcmp(LoadedFilename, filename) == 0) currentPlaying = counter; + if (strcmp(LoadedFilename, filename) == 0) currentPlaying = counter; - counter++; - } + counter++; } + } - dirclose(dir); + closedir(dir); snprintf(Settings.ogg_path, sizeof(Settings.ogg_path), "%s", folderpath); diff --git a/source/filelist.h b/source/filelist.h index 229f1061..dd364ad0 100644 --- a/source/filelist.h +++ b/source/filelist.h @@ -529,6 +529,9 @@ extern const u32 boxBorder_png_size; extern const u8 nocoverFull_png[]; extern const u32 nocoverFull_png_size; +extern const u8 playersSort_png[]; +extern const u32 playersSort_png_size; + extern const u8 stub_bin[]; extern const u32 stub_bin_size; diff --git a/source/homebrewboot/HomebrewFiles.cpp b/source/homebrewboot/HomebrewFiles.cpp index 4b6e46c1..49cc593d 100644 --- a/source/homebrewboot/HomebrewFiles.cpp +++ b/source/homebrewboot/HomebrewFiles.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include "HomebrewFiles.h" @@ -37,17 +37,25 @@ HomebrewFiles::~HomebrewFiles() bool HomebrewFiles::LoadPath(const char * folderpath) { struct stat st; - DIR_ITER *dir = NULL; + DIR *dir = NULL; + struct dirent *dirent = NULL; char filename[1024]; - dir = diropen(folderpath); + dir = opendir(folderpath); if (dir == NULL) { return false; } - while (dirnext(dir, filename, &st) == 0) + while ((dirent = readdir(dir)) != 0) { + snprintf(filename, 1024, "%s/%s", folderpath, dirent->d_name); + + if(stat(filename, &st) != 0) + continue; + + snprintf(filename, 1024, dirent->d_name); + if ((st.st_mode & S_IFDIR) != 0) { if (strcmp(filename, ".") != 0 && strcmp(filename, "..") != 0) @@ -76,7 +84,7 @@ bool HomebrewFiles::LoadPath(const char * folderpath) free(FileInfo); FileInfo = NULL; filecount = 0; - dirclose(dir); + closedir(dir); return false; } @@ -89,7 +97,7 @@ bool HomebrewFiles::LoadPath(const char * folderpath) } } } - dirclose(dir); + closedir(dir); return true; } diff --git a/source/images/playersSort.png b/source/images/playersSort.png new file mode 100644 index 00000000..b74b98a2 Binary files /dev/null and b/source/images/playersSort.png differ diff --git a/source/menu/GameBrowseMenu.cpp b/source/menu/GameBrowseMenu.cpp index 04ce59e4..325d4f63 100644 --- a/source/menu/GameBrowseMenu.cpp +++ b/source/menu/GameBrowseMenu.cpp @@ -82,6 +82,7 @@ GameBrowseMenu::GameBrowseMenu() imgabcIcon = Resources::GetImageData("abcIcon.png"); imgrankIcon = Resources::GetImageData("rankIcon.png"); imgplayCountIcon = Resources::GetImageData("playCountIcon.png"); + imgplayersSortIcon = Resources::GetImageData("playersSort.png"); imgarrangeGrid = Resources::GetImageData("arrangeGrid.png"); imgarrangeGrid_gray = Resources::GetImageData("arrangeGrid_gray.png"); imgarrangeList = Resources::GetImageData("arrangeList.png"); @@ -352,6 +353,7 @@ GameBrowseMenu::~GameBrowseMenu() delete imgabcIcon; delete imgrankIcon; delete imgplayCountIcon; + delete imgplayersSortIcon; delete imgarrangeGrid; delete imgarrangeGrid_gray; delete imgarrangeCarousel; @@ -514,6 +516,11 @@ void GameBrowseMenu::ReloadBrowser() sortTTText = tr( "Sort order by most played"); sortImgData = imgplayCountIcon; } + else if(Settings.GameSort & SORT_PLAYERS) + { + sortTTText = tr( "Sort by number of players"); + sortImgData = imgplayersSortIcon; + } else { sortTTText = tr("Sort alphabetically"); @@ -913,6 +920,11 @@ int GameBrowseMenu::MainLoop() else if(Settings.GameSort & SORT_PLAYCOUNT) { Settings.GameSort &= ~SORT_PLAYCOUNT; + Settings.GameSort |= SORT_PLAYERS; + } + else if(Settings.GameSort & SORT_PLAYERS) + { + Settings.GameSort &= ~SORT_PLAYERS; Settings.GameSort |= SORT_ABC; } diff --git a/source/menu/GameBrowseMenu.hpp b/source/menu/GameBrowseMenu.hpp index 8ee55893..0003f7e8 100644 --- a/source/menu/GameBrowseMenu.hpp +++ b/source/menu/GameBrowseMenu.hpp @@ -62,6 +62,7 @@ class GameBrowseMenu : public GuiWindow GuiImageData * imgabcIcon; GuiImageData * imgrankIcon; GuiImageData * imgplayCountIcon; + GuiImageData * imgplayersSortIcon; GuiImageData * imgarrangeGrid; GuiImageData * imgarrangeGrid_gray; GuiImageData * imgarrangeCarousel; diff --git a/source/prompts/filebrowser.cpp b/source/prompts/filebrowser.cpp index 541d4360..ae1757c5 100644 --- a/source/prompts/filebrowser.cpp +++ b/source/prompts/filebrowser.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -80,9 +80,9 @@ int InitBrowsers() if (strcmp(devoptab_list[i]->name, "stdnull") && devoptab_list[i]->write_r != NULL) { snprintf(rootdir, sizeof(rootdir), "%s:/", devoptab_list[i]->name); - if ( DIR_ITER *dir = diropen( rootdir ) ) + if ( DIR *dir = opendir( rootdir ) ) { - dirclose(dir); + closedir(dir); BROWSERINFO browser; browser.dir[0] = '\0'; strcpy(browser.rootdir, rootdir); @@ -171,7 +171,7 @@ int ParseFilter(FILTERCASCADE *Filter, BROWSERENTRY* Entry) **************************************************************************/ int ParseDirectory(const char* Path, int Flags, FILTERCASCADE *Filter) { - DIR_ITER *dir = NULL; + DIR *dir = NULL; char fulldir[MAXPATHLEN]; char filename[MAXPATHLEN]; struct stat filestat; @@ -233,18 +233,27 @@ int ParseDirectory(const char* Path, int Flags, FILTERCASCADE *Filter) ResetBrowser(browser); // open the directory - if ((dir = diropen(fulldir)) == NULL) + if ((dir = opendir(fulldir)) == NULL) { if (Flags & FB_TRYROOTDIR) { + snprintf(fulldir, sizeof(fulldir), browser->rootdir); browser->dir[0] = 0; - if ((dir = diropen(browser->rootdir)) == NULL) return -1; + if ((dir = opendir(browser->rootdir)) == NULL) return -1; } else return -1; } + + struct dirent *dirent = NULL; - while (dirnext(dir, filename, &filestat) == 0) + while ((dirent = readdir(dir)) != 0) { + snprintf(filename, sizeof(filename), "%s/%s", fulldir, dirent->d_name); + if(stat(filename, &filestat) != 0) + continue; + + snprintf(filename, sizeof(filename), dirent->d_name); + if (strcmp(filename, ".") != 0) { BROWSERENTRY newEntry; @@ -258,7 +267,7 @@ int ParseDirectory(const char* Path, int Flags, FILTERCASCADE *Filter) } // close directory - dirclose(dir); + closedir(dir); // Sort the file list std::sort(browser->browserList.begin(), browser->browserList.end()); diff --git a/source/settings/CSettings.cpp b/source/settings/CSettings.cpp index cbd6cdb0..9bdcbd17 100644 --- a/source/settings/CSettings.cpp +++ b/source/settings/CSettings.cpp @@ -114,6 +114,7 @@ void CSettings::SetDefault() InstallPartitions = ONLY_GAME_PARTITION; widescreen = (CONF_GetAspectRatio() == CONF_ASPECT_16_9); HomeMenu = HOME_MENU_DEFAULT; + MultiplePartitions = OFF; } bool CSettings::Load() @@ -255,6 +256,7 @@ bool CSettings::Save() fprintf(file, "ParentalBlocks = %08X\n ", ParentalBlocks); fprintf(file, "returnTo = %s\n ", returnTo); fprintf(file, "HomeMenu = %d\n ", HomeMenu); + fprintf(file, "MultiplePartitions = %d\n ", MultiplePartitions); fclose(file); return true; @@ -457,6 +459,11 @@ bool CSettings::SetSetting(char *name, char *value) if (sscanf(value, "%d", &i) == 1) HomeMenu = i; return true; } + else if (strcmp(name, "MultiplePartitions") == 0) + { + if (sscanf(value, "%d", &i) == 1) MultiplePartitions = i; + return true; + } else if (strcmp(name, "patchcountrystrings") == 0) { if (sscanf(value, "%d", &i) == 1) patchcountrystrings = i; diff --git a/source/settings/CSettings.h b/source/settings/CSettings.h index b99bbbe6..97bc8b7d 100644 --- a/source/settings/CSettings.h +++ b/source/settings/CSettings.h @@ -111,6 +111,7 @@ class CSettings short ShowFreeSpace; short UseIOS58; short HomeMenu; + short MultiplePartitions; u32 InstallPartitions; u32 ParentalBlocks; protected: diff --git a/source/settings/GameTitles.cpp b/source/settings/GameTitles.cpp index 65ebf57c..b8d5bd04 100644 --- a/source/settings/GameTitles.cpp +++ b/source/settings/GameTitles.cpp @@ -76,6 +76,21 @@ int CGameTitles::GetParentalRating(const char * id) const return -1; } + +int CGameTitles::GetPlayersCount(const char * id) const +{ + if(!id) + return 1; + + for(u32 i = 0; i < TitleList.size(); ++i) + { + if(strncasecmp(id, TitleList[i].GameID, 6) == 0) + return TitleList[i].PlayersCount; + } + + return 1; +} + void CGameTitles::SetDefault() { TitleList.clear(); @@ -111,6 +126,7 @@ void CGameTitles::LoadTitlesFromWiiTDB(const char * path) this->SetGameTitle(gameList[i]->id, Title.c_str()); TitleList[TitleList.size()-1].ParentalRating = -1; + TitleList[TitleList.size()-1].PlayersCount = 1; Rating = XML_DB.GetRating((const char *) gameList[i]->id); if(Rating < 0) @@ -120,5 +136,8 @@ void CGameTitles::LoadTitlesFromWiiTDB(const char * path) continue; TitleList[TitleList.size()-1].ParentalRating = ConvertRating(RatValTxt.c_str(), WiiTDB::RatingToString(Rating), "PEGI"); + int ret = XML_DB.GetPlayers((const char *) gameList[i]->id); + if(ret > 0) + TitleList[TitleList.size()-1].PlayersCount = ret; } } diff --git a/source/settings/GameTitles.h b/source/settings/GameTitles.h index ab0f417e..526894b3 100644 --- a/source/settings/GameTitles.h +++ b/source/settings/GameTitles.h @@ -11,6 +11,7 @@ typedef struct _GameTitle char GameID[7]; std::string Title; int ParentalRating; + int PlayersCount; } GameTitle; @@ -31,7 +32,8 @@ class CGameTitles //! Get game parental rating int GetParentalRating(const char * id) const; - + //! Get possible number of players for this game + int GetPlayersCount(const char * id) const; //! Load Game Titles from WiiTDB void LoadTitlesFromWiiTDB(const char * path); //! Set default game titles diff --git a/source/settings/SettingsEnums.h b/source/settings/SettingsEnums.h index 8324ef28..5eef582e 100644 --- a/source/settings/SettingsEnums.h +++ b/source/settings/SettingsEnums.h @@ -91,6 +91,7 @@ enum SORT_PLAYCOUNT = 0x02, SORT_RANKING = 0x04, SORT_FAVORITE = 0x08, + SORT_PLAYERS = 0x10, }; enum { diff --git a/source/settings/menus/LoaderSettings.cpp b/source/settings/menus/LoaderSettings.cpp index 8e22d10a..2c6787e7 100644 --- a/source/settings/menus/LoaderSettings.cpp +++ b/source/settings/menus/LoaderSettings.cpp @@ -115,7 +115,8 @@ LoaderSettings::LoaderSettings() Options->SetName(Idx++, "%s", tr( "Ocarina" )); Options->SetName(Idx++, "%s", tr( "Use IOS58" )); Options->SetName(Idx++, "%s", tr( "Boot/Standard" )); - Options->SetName(Idx++, "%s", tr( "Partition" )); + Options->SetName(Idx++, "%s", tr( "Game/Install Partition" )); + Options->SetName(Idx++, "%s", tr( "Multiple Partitions" )); Options->SetName(Idx++, "%s", tr( "Install directories" )); Options->SetName(Idx++, "%s", tr( "Game Split Size" )); Options->SetName(Idx++, "%s", tr( "Quick Boot" )); @@ -128,14 +129,20 @@ LoaderSettings::LoaderSettings() SetOptionValues(); OldSettingsPartition = Settings.partition; + OldSettingsMultiplePartitions = Settings.MultiplePartitions; } LoaderSettings::~LoaderSettings() { //! if partition has changed, Reinitialize it - if (Settings.partition != OldSettingsPartition) + if (Settings.partition != OldSettingsPartition || + Settings.MultiplePartitions != OldSettingsMultiplePartitions) { - WBFS_OpenPart(Settings.partition); + WBFS_CloseAll(); + if(Settings.MultiplePartitions) + WBFS_OpenAll(); + else + WBFS_OpenPart(Settings.partition); //! Reload the new game titles gameList.ReadGameList(); @@ -174,11 +181,14 @@ void LoaderSettings::SetOptionValues() else Options->SetValue(Idx++, "********"); - //! Settings: Partition + //! Settings: Game/Install Partition PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandle(); // Get the partition name and it's size in GB's Options->SetValue(Idx++, "%s (%.2fGB)", usbHandle->GetFSName(Settings.partition), usbHandle->GetSize(Settings.partition)/GB_SIZE); + //! Settings: Multiple Partitions + Options->SetValue(Idx++, "%s", tr( OnOffText[Settings.MultiplePartitions] )); + //! Settings: Install directories Options->SetValue(Idx++, "%s", tr( InstallToText[Settings.InstallToDir] )); @@ -287,7 +297,7 @@ int LoaderSettings::GetMenuInternal() } } - //! Settings: Partition + //! Settings: Game/Install Partition else if (ret == ++Idx) { if(DeviceHandler::Instance()->GetUSBHandle()->GetPartitionCount() < 2) @@ -308,6 +318,12 @@ int LoaderSettings::GetMenuInternal() Settings.GameSplit = GAMESPLIT_4GB; } + //! Settings: Multiple Partitions + else if (ret == ++Idx) + { + if (++Settings.MultiplePartitions >= MAX_ON_OFF) Settings.MultiplePartitions = 0; + } + //! Settings: Install directories else if (ret == ++Idx) { diff --git a/source/settings/menus/LoaderSettings.hpp b/source/settings/menus/LoaderSettings.hpp index bdd29b75..064a4d4f 100644 --- a/source/settings/menus/LoaderSettings.hpp +++ b/source/settings/menus/LoaderSettings.hpp @@ -37,6 +37,7 @@ class LoaderSettings : public SettingsMenu int GetMenuInternal(); int OldSettingsPartition; + int OldSettingsMultiplePartitions; OptionList GuiOptions; }; diff --git a/source/sys.cpp b/source/sys.cpp index 4291f72b..cf495bdc 100644 --- a/source/sys.cpp +++ b/source/sys.cpp @@ -112,7 +112,7 @@ void AppCleanUp(void) void ExitApp(void) { AppCleanUp(); - WBFS_Close(); + WBFS_CloseAll(); DeviceHandler::DestroyInstance(); USB_Deinitialize(); if(Settings.PlaylogUpdate) diff --git a/source/system/IosLoader.cpp b/source/system/IosLoader.cpp index 370ec493..1be7e7a5 100644 --- a/source/system/IosLoader.cpp +++ b/source/system/IosLoader.cpp @@ -89,7 +89,7 @@ s32 IosLoader::LoadGameCios(s32 ios) s32 ret = -1; // Unmount fat before reloading IOS. - WBFS_Close(); + WBFS_CloseAll(); WDVD_Close(); DeviceHandler::DestroyInstance(); diff --git a/source/themes/Resources.cpp b/source/themes/Resources.cpp index 0cdc7196..73ea8be0 100644 --- a/source/themes/Resources.cpp +++ b/source/themes/Resources.cpp @@ -96,6 +96,7 @@ RecourceFile Resources::RecourceFiles[] = {"abcIcon.png", abcIcon_png, abcIcon_png_size, NULL, 0}, {"rankIcon.png", rankIcon_png, rankIcon_png_size, NULL, 0}, {"playCountIcon.png", playCountIcon_png, playCountIcon_png_size, NULL, 0}, + {"playersSort.png", playersSort_png, playersSort_png_size, NULL, 0}, {"arrangeList.png", arrangeList_png, arrangeList_png_size, NULL, 0}, {"arrangeList_gray.png", arrangeList_gray_png, arrangeList_gray_png_size, NULL, 0}, {"arrangeGrid.png", arrangeGrid_png, arrangeGrid_png_size, NULL, 0}, diff --git a/source/usbloader/AlternateDOLOffsets.cpp b/source/usbloader/AlternateDOLOffsets.cpp index 1a7431f7..c8cccfd1 100644 --- a/source/usbloader/AlternateDOLOffsets.cpp +++ b/source/usbloader/AlternateDOLOffsets.cpp @@ -45,8 +45,6 @@ int defaultAltDol(const char *gameid) if(defaultDolSelected) return defaultDolSelected; - gprintf("\nautoSelectDol() started"); - char id[7]; snprintf(id, sizeof(id), gameid); diff --git a/source/usbloader/GameBooter.cpp b/source/usbloader/GameBooter.cpp index 1625b21b..806ff8d0 100644 --- a/source/usbloader/GameBooter.cpp +++ b/source/usbloader/GameBooter.cpp @@ -31,7 +31,6 @@ u32 AppEntrypoint = 0; struct discHdr *dvdheader = NULL; -extern int wbfs_part_fs; extern u32 hdd_sector_size; extern int mountMethod; @@ -103,8 +102,6 @@ int GameBooter::FindDiscHeader(const char * gameID, struct discHdr &gameHeader) delete dvdheader; dvdheader = NULL; - gameList.clear(); - return 0; } @@ -136,7 +133,7 @@ int GameBooter::SetupDisc(u8 * gameID) int ret = -1; if(((IosLoader::IsWaninkokoIOS() && IOS_GetRevision() < 18) || - hdd_sector_size != 512) && wbfs_part_fs == PART_FS_WBFS) + hdd_sector_size != 512) && gameList.GetGameFS(gameID) == PART_FS_WBFS) { gprintf("Disc_SetUSB..."); ret = Disc_SetUSB(gameID); @@ -243,9 +240,12 @@ int GameBooter::BootGame(const char * gameID) if (reloadblock == ON && IosLoader::IsHermesIOS()) { enable_ES_ioctlv_vector(); - if (wbfs_part_fs == PART_FS_WBFS) + if (gameList.GetGameFS(gameHeader.id) == PART_FS_WBFS) mload_close(); } + + //! Now we can free up the memory used by the game list + gameList.clear(); //! Load main.dol or alternative dol into memory, start the game apploader and get game entrypoint gprintf("\tDisc_wiiBoot\n"); @@ -268,7 +268,7 @@ int GameBooter::BootGame(const char * gameID) shadow_mload(); //! Flush all caches and close up all devices - WBFS_Close(); + WBFS_CloseAll(); DeviceHandler::DestroyInstance(); USB_Deinitialize(); diff --git a/source/usbloader/GameList.cpp b/source/usbloader/GameList.cpp index cfbd2507..e335f4a6 100644 --- a/source/usbloader/GameList.cpp +++ b/source/usbloader/GameList.cpp @@ -43,6 +43,7 @@ void GameList::clear() GameFilter.clear(); AvailableSearchChars.clear(); FullGameList.clear(); + GamePartitionList.clear(); FilteredList.clear(); //! Clear memory of the vector completely std::vector().swap(FilteredList); @@ -60,15 +61,41 @@ struct discHdr * GameList::GetDiscHeader(const char * gameID) const return NULL; } -int GameList::ReadGameList() +int GameList::GetPartitionNumber(const u8 *gameID) const { - // Clear list - clear(); + for (u32 i = 0; i < FullGameList.size(); ++i) + { + if(strncasecmp((const char *) gameID, (const char *) FullGameList[i].id, 6) == 0) + return GamePartitionList[i]; + } + return -1; +} + +void GameList::RemovePartition(int part) +{ + wString filter(GameFilter); + + for(u32 i = 0; i < GamePartitionList.size(); ++i) + { + if(GamePartitionList[i] == part) + { + FullGameList.erase(FullGameList.begin()+i); + GamePartitionList.erase(GamePartitionList.begin()+i); + --i; + } + } + + if(FullGameList.size() > 0) + FilterList(filter.c_str()); +} + +int GameList::InternalReadList(int part) +{ // Retrieve all stuff from WBFS - u32 cnt; + u32 cnt = 0; - int ret = WBFS_GetCount(&cnt); + int ret = WBFS_GetCount(part, &cnt); if (ret < 0) return -1; // We are done here if no games are there @@ -86,18 +113,52 @@ int GameList::ReadGameList() memset(buffer, 0, len); /* Get header list */ - ret = WBFS_GetHeaders(buffer, cnt, sizeof(struct discHdr)); + ret = WBFS_GetHeaders(part, buffer, cnt, sizeof(struct discHdr)); if (ret < 0) { - if (buffer) free(buffer); + free(buffer); return -1; } - FullGameList.resize(cnt); - memcpy(&FullGameList[0], buffer, len); + u32 oldSize = FullGameList.size(); + + FullGameList.resize(oldSize+cnt); + memcpy(&FullGameList[oldSize], buffer, len); free(buffer); + GamePartitionList.resize(oldSize+cnt); + + for(u32 i = oldSize; i < GamePartitionList.size(); ++i) + GamePartitionList[i] = part; + + return cnt; +} + +int GameList::ReadGameList() +{ + // Clear list + clear(); + + if(!Settings.MultiplePartitions) + { + int ret = InternalReadList(Settings.partition); + if(ret <= 0) return ret; + } + else + { + PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandle(); + int cnt = 0; + + for(int part = 0; part < usbHandle->GetPartitionCount(); ++part) + { + int ret = InternalReadList(part); + if(ret > 0) cnt += ret; + } + + if(!cnt) return cnt; + } + return LoadUnfiltered(); } @@ -253,6 +314,10 @@ void GameList::SortList() { std::sort(FilteredList.begin(), FilteredList.end(), RankingSortCallback); } + else if(Settings.GameSort & SORT_PLAYERS) + { + std::sort(FilteredList.begin(), FilteredList.end(), PlayersSortCallback); + } else { std::sort(FilteredList.begin(), FilteredList.end(), NameSortCallback); @@ -287,3 +352,13 @@ bool GameList::RankingSortCallback(const struct discHdr *a, const struct discHdr return (fav1 > fav2); } + +bool GameList::PlayersSortCallback(const struct discHdr *a, const struct discHdr *b) +{ + int count1 = GameTitles.GetPlayersCount((const char *) a->id); + int count2 = GameTitles.GetPlayersCount((const char *) b->id); + + if (count1 == count2) return NameSortCallback(a, b); + + return (count1 > count2); +} diff --git a/source/usbloader/GameList.h b/source/usbloader/GameList.h index a3c041c4..13ecd782 100644 --- a/source/usbloader/GameList.h +++ b/source/usbloader/GameList.h @@ -2,6 +2,7 @@ #define GAME_LIST_H_ #include +#include "Controls/DeviceHandler.hpp" #include "wstring.hpp" #include "usbloader/disc.h" @@ -30,17 +31,22 @@ class GameList int operator++(int i) { return operator++(); } int operator--(int i) { return operator--(); } struct discHdr * GetCurrentSelected() const { return operator[](selectedGame); } - + int GetPartitionNumber(const u8 *gameid) const; + int GetGameFS(const u8 *gameID) const { return DeviceHandler::Instance()->GetUSBFilesystemType(GetPartitionNumber(gameID)); } + void RemovePartition(int part_num); protected: + int InternalReadList(int part); static bool NameSortCallback(const struct discHdr *a, const struct discHdr *b); static bool PlaycountSortCallback(const struct discHdr *a, const struct discHdr *b); static bool RankingSortCallback(const struct discHdr *a, const struct discHdr *b); + static bool PlayersSortCallback(const struct discHdr *a, const struct discHdr *b); wString AvailableSearchChars; wString GameFilter; int selectedGame; std::vector FilteredList; std::vector FullGameList; + std::vector GamePartitionList; }; extern GameList gameList; diff --git a/source/usbloader/MountGamePartition.cpp b/source/usbloader/MountGamePartition.cpp index 42d9d27f..1b4fab7f 100644 --- a/source/usbloader/MountGamePartition.cpp +++ b/source/usbloader/MountGamePartition.cpp @@ -47,7 +47,7 @@ static int FindGamePartition() u32 count; // Get the game count... - WBFS_GetCount(&count); + WBFS_GetCount(i, &count); if (count > 0) { @@ -55,7 +55,7 @@ static int FindGamePartition() return 0; } - WBFS_Close(); + WBFS_Close(i); } return -1; @@ -119,7 +119,12 @@ int MountGamePartition(bool ShowGUI) Sys_LoadMenu(); } - s32 ret = WBFS_OpenPart(Settings.partition); + s32 ret = -1; + + if(Settings.MultiplePartitions) + ret = WBFS_OpenAll(); + else + WBFS_OpenPart(Settings.partition); if(ret < 0) ret = FindGamePartition(); @@ -138,7 +143,7 @@ int MountGamePartition(bool ShowGUI) Sys_LoadMenu(); } - gprintf("\tOpenXMLDatabase\n"); + gprintf("LoadTitlesFromWiiTDB\n"); GameTitles.LoadTitlesFromWiiTDB(Settings.titlestxt_path); diff --git a/source/usbloader/frag.c b/source/usbloader/frag.c index c6a89bde..c4a5096a 100644 --- a/source/usbloader/frag.c +++ b/source/usbloader/frag.c @@ -18,9 +18,6 @@ #define SAFE_FREE(x) if(x) { free(x); x = NULL; } -extern sec_t ntfs_wbfs_sec; -extern sec_t ext_wbfs_sec; - static FragList *frag_list = NULL; void frag_init(FragList *ff, int maxnum) @@ -167,7 +164,7 @@ int frag_remap(FragList *ff, FragList *log, FragList *phy) return 0; } -int get_frag_list_for_file(char *fname, u8 *id) +int get_frag_list_for_file(char *fname, u8 *id, u8 wbfs_part_fs, u32 lba_offset) { char fname1[1024]; struct stat st; @@ -212,7 +209,7 @@ int get_frag_list_for_file(char *fname, u8 *id) } // offset to start of partition for (j=0; jnum; j++) { - fs->frag[j].sector += ntfs_wbfs_sec; + fs->frag[j].sector += lba_offset; } } else if (wbfs_part_fs == PART_FS_EXT) { ret = _EXT2_get_fragments(fname, &_frag_append, fs); @@ -222,7 +219,7 @@ int get_frag_list_for_file(char *fname, u8 *id) } // offset to start of partition for (j=0; jnum; j++) { - fs->frag[j].sector += ext_wbfs_sec; + fs->frag[j].sector += lba_offset; } } else if (wbfs_part_fs == PART_FS_WBFS) { // if wbfs file format, remap. @@ -288,7 +285,7 @@ int set_frag_list(u8 *id) frag_list = NULL; gprintf("Calling WDVD_SetFragList, frag list size %d\n", size); - int ret = WDVD_SetFragList(wbfsDev, FragListAligned, size); + int ret = WDVD_SetFragList(WBFS_MIN_DEVICE, FragListAligned, size); free(FragListAligned); if (ret) diff --git a/source/usbloader/frag.h b/source/usbloader/frag.h index d3c48bd2..107675a6 100644 --- a/source/usbloader/frag.h +++ b/source/usbloader/frag.h @@ -40,7 +40,7 @@ int frag_get(FragList *ff, u32 offset, u32 count, u32 *poffset, u32 *psector, u3 int frag_remap(FragList *ff, FragList *log, FragList *phy); -int get_frag_list_for_file(char *fname, u8 *id); +int get_frag_list_for_file(char *fname, u8 *id, u8 fstype, u32 sec_offset); int get_frag_list(u8 *id); int set_frag_list(u8 *id); diff --git a/source/usbloader/wbfs.cpp b/source/usbloader/wbfs.cpp index d14ae0a4..fb356b40 100644 --- a/source/usbloader/wbfs.cpp +++ b/source/usbloader/wbfs.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -15,23 +16,31 @@ #include "menu/menus.h" #include "gecko.h" -static Wbfs *current = NULL; -/* WBFS device */ -s32 wbfsDev = WBFS_MIN_DEVICE; +#define VALID(x) (x >= 0 && x < (int) WbfsList.size() && WbfsList[x] != NULL) + +static std::vector WbfsList; wbfs_disc_t* WBFS_OpenDisc(u8 *discid) { - return current->OpenDisc(discid); + int part = gameList.GetPartitionNumber(discid); + if(VALID(part)) + return WbfsList[part]->OpenDisc(discid); + + return NULL; } void WBFS_CloseDisc(wbfs_disc_t *disc) { - current->CloseDisc(disc); -} + if(!disc) return; -wbfs_t *GetHddInfo(void) -{ - return current->GetHddInfo(); + for(u32 i = 0; i < WbfsList.size(); ++i) + { + if(WbfsList[i]->GetHDDHandle() == disc->p) + { + WbfsList[i]->CloseDisc(disc); + break; + } + } } s32 WBFS_Init(u32 device) @@ -39,6 +48,21 @@ s32 WBFS_Init(u32 device) return Wbfs::Init(device); } +s32 WBFS_OpenAll() +{ + int ret = -1; + + PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandle(); + + for(int i = 0; i < usbHandle->GetPartitionCount(); ++i) + { + if(WBFS_OpenPart(i) == 0) + ret = 0; + } + + return ret; +} + s32 WBFS_OpenPart(int part_num) { PartitionHandle * usbHandle = DeviceHandler::Instance()->GetUSBHandle(); @@ -46,137 +70,163 @@ s32 WBFS_OpenPart(int part_num) return -1; // close - WBFS_Close(); + WBFS_Close(part_num); + + if(part_num <= (int) WbfsList.size()) + WbfsList.resize(part_num+1); gprintf("\tWBFS_OpenPart: start sector %u, sector count: %u\n", usbHandle->GetLBAStart(part_num), usbHandle->GetSecCount(part_num)); if (strncmp(usbHandle->GetFSName(part_num), "FAT", 3) == 0) { - current = new Wbfs_Fat(wbfsDev, usbHandle->GetLBAStart(part_num), usbHandle->GetSecCount(part_num)); + WbfsList[part_num] = new Wbfs_Fat(WBFS_MIN_DEVICE, usbHandle->GetLBAStart(part_num), usbHandle->GetSecCount(part_num)); } else if (strncmp(usbHandle->GetFSName(part_num), "NTFS", 4) == 0) { - current = new Wbfs_Ntfs(wbfsDev, usbHandle->GetLBAStart(part_num), usbHandle->GetSecCount(part_num)); + WbfsList[part_num] = new Wbfs_Ntfs(WBFS_MIN_DEVICE, usbHandle->GetLBAStart(part_num), usbHandle->GetSecCount(part_num)); } else if (strncmp(usbHandle->GetFSName(part_num), "LINUX", 5) == 0) { - current = new Wbfs_Ext(wbfsDev, usbHandle->GetLBAStart(part_num), usbHandle->GetSecCount(part_num)); + WbfsList[part_num] = new Wbfs_Ext(WBFS_MIN_DEVICE, usbHandle->GetLBAStart(part_num), usbHandle->GetSecCount(part_num)); } else if (strncmp(usbHandle->GetFSName(part_num), "WBFS", 4) == 0) { - current = new Wbfs_Wbfs(wbfsDev, usbHandle->GetLBAStart(part_num), usbHandle->GetSecCount(part_num)); + WbfsList[part_num] = new Wbfs_Wbfs(WBFS_MIN_DEVICE, usbHandle->GetLBAStart(part_num), usbHandle->GetSecCount(part_num)); } else { return -1; } - if (current->Open()) + if (WbfsList[part_num]->Open() != 0) { - delete current; - current = NULL; + delete WbfsList[part_num]; + WbfsList[part_num] = NULL; return -1; } return 0; } -bool WBFS_Close(void) +bool WBFS_Close(int part_num) { - if (current != NULL) - { - current->Close(); - delete current; - current = NULL; - } + if(!VALID(part_num)) + return false; - gameList.clear(); + WbfsList[part_num]->Close(); + delete WbfsList[part_num]; + WbfsList[part_num] = NULL; - return 0; + gameList.RemovePartition(part_num); + + return true; } -bool WBFS_Mounted() +void WBFS_CloseAll() { - return (current != NULL && current->IsMounted()); + for(u32 i = 0; i < WbfsList.size(); ++i) + WBFS_Close(i); } s32 WBFS_Format(u32 lba, u32 size) { - Wbfs_Wbfs Part(wbfsDev, lba, size); + Wbfs_Wbfs Part(WBFS_MIN_DEVICE, lba, size); return Part.Format(); } -s32 WBFS_GetCount(u32 *count) +s32 WBFS_GetCount(int part_num, u32 *count) { - return current->GetCount(count); + if(!VALID(part_num)) + return -1; + + return WbfsList[part_num]->GetCount(count); } -s32 WBFS_GetHeaders(struct discHdr *outbuf, u32 cnt, u32 len) +s32 WBFS_GetHeaders(int part_num, struct discHdr *outbuf, u32 cnt, u32 len) { - return current->GetHeaders(outbuf, cnt, len); + if(!VALID(part_num)) + return -1; + + return WbfsList[part_num]->GetHeaders(outbuf, cnt, len); } s32 WBFS_CheckGame(u8 *discid) { - return current->CheckGame(discid); + int part_num = gameList.GetPartitionNumber(discid); + if(!VALID(part_num)) + return -1; + + return WbfsList[part_num]->CheckGame(discid); } s32 WBFS_AddGame(void) { - s32 retval = current->AddGame(); - if (retval == 0) gameList.clear(); + if(!VALID(Settings.partition)) + return -1; - return retval; + return WbfsList[Settings.partition]->AddGame(); } s32 WBFS_RemoveGame(u8 *discid) { - s32 retval = current->RemoveGame(discid); - if (retval == 0) gameList.clear(); + int part_num = gameList.GetPartitionNumber(discid); + if(!VALID(part_num)) + return -1; - return retval; + return WbfsList[part_num]->RemoveGame(discid); } s32 WBFS_GameSize(u8 *discid, f32 *size) { - return current->GameSize(discid, size); + int part_num = gameList.GetPartitionNumber(discid); + if(!VALID(part_num)) + return -1; + + return WbfsList[part_num]->GameSize(discid, size); } s32 WBFS_DiskSpace(f32 *used, f32 *free) { - return current->DiskSpace(used, free); + if(!VALID(Settings.partition)) + return -1; + + return WbfsList[Settings.partition]->DiskSpace(used, free); } s32 WBFS_RenameGame(u8 *discid, const void *newname) { - s32 retval = current->RenameGame(discid, newname); - if (retval == 0) gameList.clear(); + int part_num = gameList.GetPartitionNumber(discid); + if(!VALID(part_num)) + return -1; - return retval; + return WbfsList[part_num]->RenameGame(discid, newname); } s32 WBFS_ReIDGame(u8 *discid, const void *newID) { - s32 retval = current->ReIDGame(discid, newID); - if (retval == 0) gameList.clear(); + int part_num = gameList.GetPartitionNumber(discid); + if(!VALID(part_num)) + return -1; - return retval; + return WbfsList[part_num]->ReIDGame(discid, newID); } u64 WBFS_EstimeGameSize(void) { - return current->EstimateGameSize(); + if(!VALID(Settings.partition)) + return 0; + + return WbfsList[Settings.partition]->EstimateGameSize(); } int WBFS_GetFragList(u8 *id) { - return current->GetFragList(id); -} + int part_num = gameList.GetPartitionNumber(id); + if(!VALID(part_num)) + return -1; -bool WBFS_ShowFreeSpace(void) -{ - return current->ShowFreeSpace(); + return WbfsList[part_num]->GetFragList(id); } int MountWBFS(bool ShowGUI) diff --git a/source/usbloader/wbfs.h b/source/usbloader/wbfs.h index 00b8d4bb..1e9f2f73 100644 --- a/source/usbloader/wbfs.h +++ b/source/usbloader/wbfs.h @@ -18,32 +18,28 @@ extern "C" #define WBFS_MIN_DEVICE 1 #define WBFS_MAX_DEVICE 2 - extern int wbfs_part_fs; - extern s32 wbfsDev; - /* Prototypes */ - s32 WBFS_Init(u32); - s32 WBFS_Format(u32, u32); - s32 WBFS_GetCount(u32 *); - s32 WBFS_GetHeaders(struct discHdr *, u32, u32); - wbfs_t *GetHddInfo(void); - s32 WBFS_CheckGame(u8 *); + s32 WBFS_Init(u32 device); + s32 WBFS_Format(u32 lba, u32 size); + s32 WBFS_GetCount(int part, u32 *count); + s32 WBFS_GetHeaders(int part, struct discHdr *, u32, u32); + s32 WBFS_CheckGame(u8 *gameid); s32 WBFS_AddGame(void); - s32 WBFS_RemoveGame(u8 *); - s32 WBFS_GameSize(u8 *, f32 *); - bool WBFS_ShowFreeSpace(void); - s32 WBFS_DiskSpace(f32 *, f32 *); - s32 WBFS_RenameGame(u8 *, const void *); + s32 WBFS_RemoveGame(u8 *gameid); + s32 WBFS_GameSize(u8 *gameid, f32 *size); + s32 WBFS_DiskSpace(f32 *used, f32 *free); + s32 WBFS_RenameGame(u8 *gameid, const void *newname); s32 WBFS_ReIDGame(u8 *discid, const void *newID); u64 WBFS_EstimeGameSize(void); int WBFS_GetFragList(u8 *id); + s32 WBFS_OpenAll(); s32 WBFS_OpenPart(int part_num); wbfs_disc_t* WBFS_OpenDisc(u8 *discid); void WBFS_CloseDisc(wbfs_disc_t *disc); - bool WBFS_Close(); - bool WBFS_Mounted(); + bool WBFS_Close(int part); + void WBFS_CloseAll(); bool WBFS_Selected(); int MountWBFS(bool ShowGUI); diff --git a/source/usbloader/wbfs/wbfs_base.cpp b/source/usbloader/wbfs/wbfs_base.cpp index 0f42078c..31a2f0a2 100644 --- a/source/usbloader/wbfs/wbfs_base.cpp +++ b/source/usbloader/wbfs/wbfs_base.cpp @@ -7,26 +7,14 @@ #include "Controls/DeviceHandler.hpp" #include "usbloader/sdhc.h" #include "usbloader/usbstorage2.h" +#include "usbloader/wbfs.h" #include "wbfs_rw.h" #include "wbfs_base.h" -s32 Wbfs::done = -1; -s32 Wbfs::total = -1; -u32 Wbfs::nb_sectors; - -Wbfs::Wbfs(u32 device, u32 lba, u32 size) : - hdd(NULL) +Wbfs::Wbfs(u32 dev, u32 l, u32 s) + : hdd(NULL), device(dev), lba(l), size(s) { - this->device = device; - this->lba = lba; - this->size = size; -} - -void Wbfs::GetProgressValue(s32 * d, s32 * m) -{ - *d = done; - *m = total; } s32 Wbfs::Init(u32 device) @@ -58,9 +46,6 @@ s32 Wbfs::Init(u32 device) /* Setup callbacks */ readCallback = __ReadSDHC; writeCallback = __WriteSDHC; - - /* Device info */ - nb_sectors = 0; } else return -1; break; @@ -114,11 +99,6 @@ s32 Wbfs::GameSize(u8 *discid, f32 *size) return 0; } -wbfs_t *Wbfs::GetHddInfo() -{ - return hdd; -} - bool Wbfs::ShowFreeSpace(void) { return true; diff --git a/source/usbloader/wbfs/wbfs_base.h b/source/usbloader/wbfs/wbfs_base.h index c52a695f..de8cd070 100644 --- a/source/usbloader/wbfs/wbfs_base.h +++ b/source/usbloader/wbfs/wbfs_base.h @@ -13,11 +13,9 @@ class Wbfs public: Wbfs(u32, u32, u32); - void GetProgressValue(s32 * d, s32 * m); static s32 Init(u32); s32 CheckGame(u8 *); s32 GameSize(u8 *, f32 *); - wbfs_t *GetHddInfo(void); bool IsMounted() { return hdd == 0; }; virtual int GetFragList(u8 *id) { return 0; }; virtual bool ShowFreeSpace(void); @@ -35,13 +33,12 @@ class Wbfs virtual s32 RenameGame(u8 *, const void *) = 0; virtual s32 ReIDGame(u8 *discid, const void *newID) = 0; virtual u64 EstimateGameSize(void) = 0; + virtual const u8 GetFSType(void) const = 0; + const wbfs_t *GetHDDHandle(void) const { return hdd; } protected: - static u32 nb_sectors; wbfs_t *hdd; u32 device, lba, size; - private: - - static s32 total, done; + u8 wbfs_part_fs; }; #endif //_H diff --git a/source/usbloader/wbfs/wbfs_ext.cpp b/source/usbloader/wbfs/wbfs_ext.cpp deleted file mode 100644 index 86b17256..00000000 --- a/source/usbloader/wbfs/wbfs_ext.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include -#include "usbloader/usbstorage2.h" -#include "wbfs_ext.h" - -extern int wbfs_part_fs; -sec_t ext_wbfs_sec = 0; - -s32 Wbfs_Ext::Open() -{ - s32 ret = Wbfs_Fat::Open(); - if(ret == 0) - { - ext_wbfs_sec = lba; - wbfs_part_fs = PART_FS_EXT; - } - - return 0; -} diff --git a/source/usbloader/wbfs/wbfs_ext.h b/source/usbloader/wbfs/wbfs_ext.h index dfea087a..787a4ab9 100644 --- a/source/usbloader/wbfs/wbfs_ext.h +++ b/source/usbloader/wbfs/wbfs_ext.h @@ -1,7 +1,6 @@ #ifndef _WBFS_EXT_H #define _WBFS_EXT_H -#include #include "wbfs_fat.h" class Wbfs_Ext: public Wbfs_Fat @@ -11,9 +10,7 @@ class Wbfs_Ext: public Wbfs_Fat Wbfs_Fat(device, lba, size) { } - - virtual s32 Open(); - bool ShowFreeSpace(void) { return true; }; + virtual const u8 GetFSType(void) const { return PART_FS_EXT; } }; #endif //_WBFS_NTFS_H diff --git a/source/usbloader/wbfs/wbfs_fat.cpp b/source/usbloader/wbfs/wbfs_fat.cpp index 9507e250..62d9cf7e 100644 --- a/source/usbloader/wbfs/wbfs_fat.cpp +++ b/source/usbloader/wbfs/wbfs_fat.cpp @@ -34,18 +34,14 @@ using namespace std; -int wbfs_part_fs = -1; - -char Wbfs_Fat::wbfs_fs_drive[16]; -char Wbfs_Fat::wbfs_fat_dir[16] = "/wbfs"; -char Wbfs_Fat::invalid_path[] = "/\\:|<>?*\"'"; -struct discHdr *Wbfs_Fat::fat_hdr_list = NULL; -u32 Wbfs_Fat::fat_hdr_count = 0; -u32 Wbfs_Fat::fat_sector_size = 512; +static const char wbfs_fat_dir[] = "/wbfs"; +static const char invalid_path[] = "/\\:|<>?*\"'"; +static const u32 fat_sector_size = 512; Wbfs_Fat::Wbfs_Fat(u32 device, u32 lba, u32 size) : - Wbfs(device, lba, size) + Wbfs(device, lba, size), fat_hdr_list(NULL), fat_hdr_count(0) { + memset(wbfs_fs_drive, 0, sizeof(wbfs_fs_drive)); } s32 Wbfs_Fat::Open() @@ -59,7 +55,6 @@ s32 Wbfs_Fat::Open() if (device == WBFS_DEVICE_USB && lba == usbHandle->GetLBAStart(i)) { sprintf(wbfs_fs_drive, "%s:", usbHandle->MountName(i)); - wbfs_part_fs = PART_FS_FAT; return 0; } } @@ -75,7 +70,6 @@ void Wbfs_Fat::Close() hdd = NULL; } - wbfs_part_fs = -1; memset(wbfs_fs_drive, 0, sizeof(wbfs_fs_drive)); } @@ -102,9 +96,17 @@ wbfs_disc_t* Wbfs_Fat::OpenDisc(u8 *discid) return iso_file; } - wbfs_t *part = OpenPart(fname); - if (!part) return NULL; - return wbfs_open_disc(part, discid); + hdd = OpenPart(fname); + if (!hdd) return NULL; + + wbfs_disc_t *disc = wbfs_open_disc(hdd, discid); + if(!disc) + { + ClosePart(hdd); + return NULL; + } + + return disc; } void Wbfs_Fat::CloseDisc(wbfs_disc_t* disc) @@ -152,18 +154,14 @@ s32 Wbfs_Fat::GetHeaders(struct discHdr *outbuf, u32 cnt, u32 len) { len = sizeof(struct discHdr); } -#ifdef DEBUG_WBFS - gprintf( "\n\tGetHeaders" ); -#endif + for (i = 0; i < cnt && i < fat_hdr_count; i++) { memcpy(&outbuf[i], &fat_hdr_list[i], len); } SAFE_FREE( fat_hdr_list ); fat_hdr_count = 0; -#ifdef DEBUG_WBFS - gprintf( "...ok" ); -#endif + return 0; } @@ -184,10 +182,7 @@ s32 Wbfs_Fat::AddGame(void) /* Add game to device */ partition_selector_t part_sel = (partition_selector_t) Settings.InstallPartitions; - wbfs_t *old_hdd = hdd; - hdd = part; // used by spinner - ret = wbfs_add_disc(hdd, __ReadDVD, NULL, ShowProgress, part_sel, 0); - hdd = old_hdd; + ret = wbfs_add_disc(part, __ReadDVD, NULL, ShowProgress, part_sel, 0); wbfs_trim(part); ClosePart(part); @@ -210,17 +205,18 @@ s32 Wbfs_Fat::RemoveGame(u8 *discid) // game is in subdir // remove optional .txt file - DIR_ITER *dir_iter; - struct stat st; + DIR *dir = NULL; + struct dirent *dirent = NULL; char path[MAX_FAT_PATH]; char name[MAX_FAT_PATH]; strncpy(path, fname, sizeof(path)); char *p = strrchr(path, '/'); if (p) *p = 0; - dir_iter = diropen(path); - if (!dir_iter) return 0; - while (dirnext(dir_iter, name, &st) == 0) + dir = opendir(path); + if (!dir) return 0; + while ((dirent = readdir(dir)) != 0) { + snprintf(name, sizeof(name), dirent->d_name); if (name[0] == '.') continue; if (name[6] != '_') continue; if (strncmp(name, (char*) discid, 6) != 0) continue; @@ -231,7 +227,7 @@ s32 Wbfs_Fat::RemoveGame(u8 *discid) remove(fname); break; } - dirclose(dir_iter); + closedir(dir); // remove game subdir unlink(path); @@ -382,8 +378,8 @@ s32 Wbfs_Fat::GetHeadersCount() char dir_title[65]; char fname_title[TITLE_LEN]; const char *title; - DIR_ITER *dir_iter; - + DIR *dir_iter; + struct dirent *dirent; //dbg_time1(); SAFE_FREE( fat_hdr_list ); @@ -392,14 +388,18 @@ s32 Wbfs_Fat::GetHeadersCount() strcpy(path, wbfs_fs_drive); strcat(path, wbfs_fat_dir); - dir_iter = diropen(path); + dir_iter = opendir(path); if (!dir_iter) return 0; - dir_iter = diropen(path); - if (!dir_iter) return 0; - - while (dirnext(dir_iter, fname, &st) == 0) + while ((dirent = readdir(dir_iter)) != 0) { + snprintf(fname, sizeof(fname), "%s/%s", path, dirent->d_name); + + if(stat(fname, &st) != 0) + continue; + + snprintf(fname, sizeof(fname), dirent->d_name); + //printf("found: %s\n", fname); Wpad_WaitButtonsCommon(); if ((char) fname[0] == '.') continue; len = strlen(fname); @@ -584,7 +584,7 @@ s32 Wbfs_Fat::GetHeadersCount() fat_hdr_list = (struct discHdr *) realloc(fat_hdr_list, fat_hdr_count * sizeof(struct discHdr)); memcpy(&fat_hdr_list[fat_hdr_count - 1], &tmpHdr, sizeof(struct discHdr)); } - dirclose(dir_iter); + closedir(dir_iter); //dbg_time2("\nFAT_GetCount"); Wpad_WaitButtonsCommon(); return 0; @@ -604,19 +604,26 @@ int Wbfs_Fat::FindFilename(u8 *id, char *fname, int len) if (stat(fname, &st) == 0) return 1; // direct file not found, check subdirs *fname = 0; - DIR_ITER *dir_iter; + DIR *dir_iter; + struct dirent *dirent; char path[MAX_FAT_PATH]; char name[MAX_FAT_PATH]; strcpy(path, wbfs_fs_drive); strcat(path, wbfs_fat_dir); - dir_iter = diropen(path); + dir_iter = opendir(path); //printf("dir: %s %p\n", path, dir); Wpad_WaitButtons(); if (!dir_iter) { return 0; } - while (dirnext(dir_iter, name, &st) == 0) + while ((dirent = readdir(dir_iter)) != 0) { + snprintf(name, sizeof(name), "%s/%s", path, dirent->d_name); + + if(stat(name, &st) != 0) + continue; + + snprintf(name, sizeof(name), dirent->d_name); //dbg_printf("name:%s\n", name); if (name[0] == '.') continue; int n = strlen(name); @@ -660,7 +667,7 @@ int Wbfs_Fat::FindFilename(u8 *id, char *fname, int len) if (stat(fname, &st) == 0) break; *fname = 0; } - dirclose(dir_iter); + closedir(dir_iter); if (*fname) { // found @@ -739,7 +746,7 @@ wbfs_t* Wbfs_Fat::CreatePart(u8 *id, char *path) // 1 cluster less than 4gb u64 OPT_split_size = 4LL * 1024 * 1024 * 1024 - 32 * 1024; - if(Settings.GameSplit == GAMESPLIT_NONE && wbfs_part_fs != PART_FS_FAT) + if(Settings.GameSplit == GAMESPLIT_NONE && gameList.GetGameFS(id) != PART_FS_FAT) OPT_split_size = (u64) 100LL * 1024 * 1024 * 1024 - 32 * 1024; else if(Settings.GameSplit == GAMESPLIT_2GB) @@ -860,7 +867,7 @@ int Wbfs_Fat::GetFragList(u8 *id) int ret = FindFilename(id, fname, sizeof(fname)); if (!ret) return -1; - return get_frag_list_for_file(fname, id); + return get_frag_list_for_file(fname, id, GetFSType(), lba); } bool Wbfs_Fat::ShowFreeSpace(void) diff --git a/source/usbloader/wbfs/wbfs_fat.h b/source/usbloader/wbfs/wbfs_fat.h index 5ab31477..dad80490 100644 --- a/source/usbloader/wbfs/wbfs_fat.h +++ b/source/usbloader/wbfs/wbfs_fat.h @@ -31,19 +31,16 @@ class Wbfs_Fat: public Wbfs u64 EstimateGameSize(); - int GetFragList(u8 *); + virtual int GetFragList(u8 *); virtual bool ShowFreeSpace(void); + virtual const u8 GetFSType(void) const { return PART_FS_FAT; } protected: - static char wbfs_fs_drive[16]; - private: split_info_t split; - static u32 fat_sector_size; - static char wbfs_fat_dir[16]; - static char invalid_path[]; - static struct discHdr *fat_hdr_list; - static u32 fat_hdr_count; + struct discHdr *fat_hdr_list; + u32 fat_hdr_count; + char wbfs_fs_drive[16]; wbfs_t* OpenPart(char *fname); void ClosePart(wbfs_t* part); diff --git a/source/usbloader/wbfs/wbfs_ntfs.cpp b/source/usbloader/wbfs/wbfs_ntfs.cpp deleted file mode 100644 index 4c284918..00000000 --- a/source/usbloader/wbfs/wbfs_ntfs.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include -#include "wbfs_ntfs.h" -#include "usbloader/usbstorage2.h" - -extern int wbfs_part_fs; -sec_t ntfs_wbfs_sec = 0; - -s32 Wbfs_Ntfs::Open() -{ - s32 ret = Wbfs_Fat::Open(); - if(ret == 0) - { - ntfs_wbfs_sec = lba; - wbfs_part_fs = PART_FS_NTFS; - } - - return 0; -} diff --git a/source/usbloader/wbfs/wbfs_ntfs.h b/source/usbloader/wbfs/wbfs_ntfs.h index 19610cec..d8074c5d 100644 --- a/source/usbloader/wbfs/wbfs_ntfs.h +++ b/source/usbloader/wbfs/wbfs_ntfs.h @@ -10,10 +10,7 @@ class Wbfs_Ntfs: public Wbfs_Fat Wbfs_Fat(device, lba, size) { } - - virtual s32 Open(); - - bool ShowFreeSpace(void) { return true; }; + virtual const u8 GetFSType(void) const { return PART_FS_NTFS; } }; #endif //_WBFS_NTFS_H diff --git a/source/usbloader/wbfs/wbfs_wbfs.cpp b/source/usbloader/wbfs/wbfs_wbfs.cpp index f76e77d0..4872166a 100644 --- a/source/usbloader/wbfs/wbfs_wbfs.cpp +++ b/source/usbloader/wbfs/wbfs_wbfs.cpp @@ -4,7 +4,6 @@ #include "usbloader/wbfs.h" #include "wbfs_rw.h" -extern int wbfs_part_fs; extern u32 hdd_sector_size; s32 Wbfs_Wbfs::Open() @@ -42,8 +41,6 @@ s32 Wbfs_Wbfs::Open() Close(); hdd = part; - wbfs_part_fs = PART_FS_WBFS; - return 0; } @@ -54,8 +51,6 @@ void Wbfs_Wbfs::Close() wbfs_close(hdd); hdd = NULL; } - - wbfs_part_fs = -1; } wbfs_disc_t* Wbfs_Wbfs::OpenDisc(u8 *discid) @@ -212,5 +207,5 @@ s32 Wbfs_Wbfs::GetFragList(u8 *id) { //! Doesn't have to be called ".iso" just something different than .wbfs but with a dot. //! So that the code doesn't fail. - return get_frag_list_for_file((char *) ".iso", id); + return get_frag_list_for_file((char *) ".iso", id, GetFSType(), lba); } diff --git a/source/usbloader/wbfs/wbfs_wbfs.h b/source/usbloader/wbfs/wbfs_wbfs.h index de9974df..b4657cf8 100644 --- a/source/usbloader/wbfs/wbfs_wbfs.h +++ b/source/usbloader/wbfs/wbfs_wbfs.h @@ -3,6 +3,7 @@ #include "wbfs_base.h" #include "libs/libwbfs/libwbfs.h" +#include "usbloader/wbfs.h" #include "wbfs_rw.h" class Wbfs_Wbfs: public Wbfs @@ -32,8 +33,9 @@ class Wbfs_Wbfs: public Wbfs u64 EstimateGameSize(); int GetFragList(u8 *id); + virtual const u8 GetFSType(void) const { return PART_FS_WBFS; } private: - _WBFS_PartInfo PartInfo; + WBFS_PartInfo PartInfo; }; #endif //_WBFS_WBFS_H