-made game list even more efficient and smaller again

-fixed finding gamecube fst extracted games
-fixed possible plugin display bug
This commit is contained in:
fix94.1 2012-10-04 11:37:53 +00:00
parent 17b9e10a16
commit 4d4e987286
8 changed files with 133 additions and 129 deletions

View File

@ -23,10 +23,12 @@
#include "fileOps/fileOps.h"
#include "gui/text.hpp"
void ListGenerator::Init(string settingsDir, string Language)
ListGenerator m_gameList;
void ListGenerator::Init(const char *settingsDir, const char *Language)
{
gameTDB_Path = fmt("%s/wiitdb.xml", settingsDir.c_str());
CustomTitlesPath = fmt("%s/" CTITLES_FILENAME, settingsDir.c_str());
gameTDB_Path = fmt("%s/wiitdb.xml", settingsDir);
CustomTitlesPath = fmt("%s/" CTITLES_FILENAME, settingsDir);
gameTDB_Language = Language;
}
@ -51,8 +53,8 @@ void ListGenerator::CloseConfigs()
CustomTitles.unload();
}
void ListGenerator::CreateList(u32 Flow, u32 Device, string Path, vector<string> FileTypes,
string DBName, bool UpdateCache, u32 Color, u32 Magic)
void ListGenerator::CreateList(u32 Flow, u32 Device, const string& Path,
const vector<string>& FileTypes, const string& DBName, bool UpdateCache, u32 Color, u32 Magic)
{
Cleanup();
if(UpdateCache)
@ -93,63 +95,68 @@ void ListGenerator::CreateList(u32 Flow, u32 Device, string Path, vector<string>
void ListGenerator::Create_Wii_WBFS_List(wbfs_t *handle)
{
discHdr Header;
for(u32 i = 0; i < wbfs_count_discs(handle); i++)
{
memset((void*)&Header, 0, sizeof(discHdr));
s32 ret = wbfs_get_disc_info(handle, i, (u8*)&Header, sizeof(discHdr), NULL);
if(ret == 0 && Header.magic == WII_MAGIC)
AddISO((const char*)Header.id, (const char*)Header.title, " ", 1, TYPE_WII_GAME);
memset((void*)&WiiGameHeader, 0, sizeof(discHdr));
s32 ret = wbfs_get_disc_info(handle, i, (u8*)&WiiGameHeader, sizeof(discHdr), NULL);
if(ret == 0 && WiiGameHeader.magic == WII_MAGIC)
AddISO((const char*)WiiGameHeader.id, (const char*)WiiGameHeader.title,
NULL, 1, TYPE_WII_GAME);
}
}
void ListGenerator::Create_Wii_EXT_List(string Path, vector<string> FileTypes)
void ListGenerator::Create_Wii_EXT_List(const string& Path, const vector<string>& FileTypes)
{
vector<string> FileList;
GetFiles(Path.c_str(), FileTypes, &FileList);
discHdr Header;
for(vector<string>::iterator Name = FileList.begin(); Name != FileList.end(); Name++)
GetFiles(Path.c_str(), FileTypes, InternalList, false);
for(vector<string>::iterator Name = InternalList.begin(); Name != InternalList.end(); Name++)
{
memset((void*)&Header, 0, sizeof(discHdr));
memset((void*)&WiiGameHeader, 0, sizeof(discHdr));
FILE *fp = fopen(Name->c_str(), "rb");
if(fp)
{
fseek(fp, strcasestr(Name->c_str(), ".wbfs") != NULL ? 512 : 0, SEEK_SET);
fread((void*)&Header, 1, sizeof(discHdr), fp);
if(Header.magic == WII_MAGIC)
AddISO((const char*)Header.id, (const char*)Header.title, Name->c_str(), 1, TYPE_WII_GAME);
fread((void*)&WiiGameHeader, 1, sizeof(discHdr), fp);
if(WiiGameHeader.magic == WII_MAGIC)
AddISO((const char*)WiiGameHeader.id, (const char*)WiiGameHeader.title,
Name->c_str(), 1, TYPE_WII_GAME);
fclose(fp);
}
}
FileList.clear();
InternalList.clear();
}
void ListGenerator::Create_GC_List(string Path, vector<string> FileTypes)
void ListGenerator::Create_GC_List(const string& Path, const vector<string>& FileTypes)
{
vector<string> FileList;
GetFiles(Path.c_str(), FileTypes, &FileList, true);
gc_discHdr Header;
for(vector<string>::iterator Name = FileList.begin(); Name != FileList.end(); Name++)
GetFiles(Path.c_str(), FileTypes, InternalList, true);
for(vector<string>::iterator Name = InternalList.begin(); Name != InternalList.end(); Name++)
{
memset((void*)&Header, 0, sizeof(gc_discHdr));
memset((void*)&GCGameHeader, 0, sizeof(gc_discHdr));
FILE *fp = fopen(Name->c_str(), "rb");
if(!fp && Name->find("root") != string::npos) //fst folder
{
Name->erase(Name->begin() + Name->find("root"), Name->end());
Name->append("sys/boot.bin");
gprintf("FST Name: %s\n", Name->c_str());
fp = fopen(Name->c_str(), "rb");
}
if(fp)
{
fread((void*)&Header, 1, sizeof(gc_discHdr), fp);
if(Header.magic == GC_MAGIC)
AddISO((const char*)Header.id, (const char*)Header.title, Name->c_str(), 0, TYPE_GC_GAME);
fread((void*)&GCGameHeader, 1, sizeof(gc_discHdr), fp);
if(GCGameHeader.magic == GC_MAGIC)
AddISO((const char*)GCGameHeader.id, (const char*)GCGameHeader.title,
Name->c_str(), 0, TYPE_GC_GAME);
fclose(fp);
}
}
FileList.clear();
InternalList.clear();
}
void ListGenerator::Create_Plugin_List(string Path, vector<string> FileTypes, u32 Color, u32 Magic)
void ListGenerator::Create_Plugin_List(const string& Path, const vector<string>& FileTypes,
u32 Color, u32 Magic)
{
dir_discHdr ListElement;
vector<string> FileList;
GetFiles(Path.c_str(), FileTypes, &FileList, false, 20);
for(vector<string>::iterator Name = FileList.begin(); Name != FileList.end(); Name++)
GetFiles(Path.c_str(), FileTypes, InternalList, false, 30);
for(vector<string>::const_iterator Name = InternalList.begin(); Name != InternalList.end(); ++Name)
{
memset((void*)&ListElement, 0, sizeof(dir_discHdr));
ListElement.index = this->size();
@ -165,15 +172,14 @@ void ListGenerator::Create_Plugin_List(string Path, vector<string> FileTypes, u3
ListElement.type = TYPE_PLUGIN;
this->push_back(ListElement);
}
FileList.clear();
InternalList.clear();
}
void ListGenerator::Create_Homebrew_List(string Path, vector<string> FileTypes)
void ListGenerator::Create_Homebrew_List(const string& Path, const vector<string>& FileTypes)
{
dir_discHdr ListElement;
vector<string> FileList;
GetFiles(Path.c_str(), FileTypes, &FileList, false, 4);
for(vector<string>::iterator Name = FileList.begin(); Name != FileList.end(); Name++)
GetFiles(Path.c_str(), FileTypes, InternalList, false, 4);
for(vector<string>::iterator Name = InternalList.begin(); Name != InternalList.end(); Name++)
{
if(Name->find("boot.") == string::npos)
continue;
@ -204,9 +210,7 @@ void ListGenerator::CreateChannelList()
Channels ChannelHandle;
dir_discHdr ListElement;
ChannelHandle.Init(0, gameTDB_Language, true);
u32 count = ChannelHandle.Count();
this->reserve(count);
for(u32 i = 0; i < count; ++i)
for(int i = 0; i < ChannelHandle.Count(); i++)
{
Channel *chan = ChannelHandle.GetChannel(i);
if(chan->id == NULL)
@ -264,8 +268,18 @@ void ListGenerator::AddISO(const char *GameID, const char *GameTitle, const char
this->push_back(ListElement); //I am a vector! :P
}
void ListGenerator::GetFiles(const char *Path, vector<string> FileTypes,
vector<string> *FileList, bool gc, u32 max_depth, u32 depth)
bool ListGenerator::IsFileSupported(const char *File, const vector<string>& FileTypes)
{
for(vector<string>::const_iterator cmp = FileTypes.begin(); cmp != FileTypes.end(); ++cmp)
{
if(strcasecmp(File, cmp->c_str()) == 0)
return true;
}
return false;
}
void ListGenerator::GetFiles(const char *Path, const vector<string>& FileTypes,
vector<string>& FileList, bool CompareFolders, u32 max_depth, u32 depth)
{
struct dirent *pent = NULL;
vector<string> SubPaths;
@ -279,8 +293,11 @@ void ListGenerator::GetFiles(const char *Path, vector<string> FileTypes,
string CurrentItem = sfmt("%s/%s", Path, pent->d_name);
if(pent->d_type == DT_DIR)
{
if(gc && depth == 2 && strcasecmp(pent->d_name, "root") == 0) //fst
FileList->push_back(CurrentItem);
if(CompareFolders && IsFileSupported(pent->d_name, FileTypes))
{
FileList.push_back(CurrentItem);
continue;
}
else if(depth < max_depth)
SubPaths.push_back(CurrentItem); //thanks to libntfs for a complicated way
}
@ -288,18 +305,15 @@ void ListGenerator::GetFiles(const char *Path, vector<string> FileTypes,
{
const char *FileName = strstr(pent->d_name, ".");
if(FileName == NULL) FileName = pent->d_name;
for(vector<string>::iterator cmp = FileTypes.begin(); cmp != FileTypes.end(); cmp++)
if(IsFileSupported(FileName, FileTypes))
{
if(strcasecmp(FileName, cmp->c_str()) == 0)
{
FileList->push_back(CurrentItem);
break;
}
FileList.push_back(CurrentItem);
continue;
}
}
}
closedir(pdir);
for(vector<string>::iterator SubPath = SubPaths.begin(); SubPath != SubPaths.end(); SubPath++)
GetFiles(SubPath->c_str(), FileTypes, FileList, gc, max_depth, depth + 1);
GetFiles(SubPath->c_str(), FileTypes, FileList, CompareFolders, max_depth, depth + 1);
SubPaths.clear();
}

View File

@ -32,20 +32,22 @@ using namespace std;
class ListGenerator : public vector<dir_discHdr>
{
public:
void Init(string settingsDir, string Language);
void Init(const char *settingsDir, const char *Language);
void Cleanup();
void CreateList(u32 Flow, u32 Device, string Path, vector<string> FileTypes,
string DBName, bool UpdateCache, u32 Color = 0, u32 Magic = 0);
void CreateList(u32 Flow, u32 Device, const string& Path, const vector<string>& FileTypes,
const string& DBName, bool UpdateCache, u32 Color = 0, u32 Magic = 0);
void GetFiles(const char *Path, const vector<string>& FileTypes, vector<string>& FileList,
bool CompareFolders, u32 max_depth = 2, u32 depth = 1);
private:
void Create_Wii_WBFS_List(wbfs_t *handle);
void Create_Wii_EXT_List(string Path, vector<string> FileTypes);
void Create_GC_List(string Path, vector<string> FileTypes);
void Create_Plugin_List(string Path, vector<string> FileTypes, u32 Color, u32 Magic);
void Create_Homebrew_List(string Path, vector<string> FileTypes);
void Create_Wii_EXT_List(const string& Path, const vector<string>& FileTypes);
void Create_GC_List(const string& Path, const vector<string>& FileTypes);
void Create_Plugin_List(const string& Path, const vector<string>& FileTypes,
u32 Color, u32 Magic);
void Create_Homebrew_List(const string& Path, const vector<string>& FileTypes);
void CreateChannelList();
void GetFiles(const char *Path, vector<string> FileTypes, vector<string> *FileList,
bool gc = false, u32 max_depth = 2, u32 depth = 1);
void AddISO(const char *GameID, const char *GameTitle, const char *GamePath, u32 GameColor, u8 Type);
bool IsFileSupported(const char *File, const vector<string>& FileTypes);
void OpenConfigs();
void CloseConfigs();
string gameTDB_Path;
@ -53,6 +55,11 @@ private:
string gameTDB_Language;
GameTDB gameTDB;
Config CustomTitles;
vector<string> InternalList;
discHdr WiiGameHeader;
gc_discHdr GCGameHeader;
};
extern ListGenerator m_gameList;
#endif /*_LISTGENERATOR_HPP_*/

View File

@ -419,7 +419,7 @@ void CMenu::init(void)
}
m_tempView = false;
m_gameList.Init(m_settingsDir, m_loc.getString(m_curLanguage, "gametdb_code", "EN"));
m_gameList.Init(m_settingsDir.c_str(), m_loc.getString(m_curLanguage, "gametdb_code", "EN").c_str());
m_aa = 3;
@ -2171,8 +2171,9 @@ bool CMenu::_loadChannelList(void)
{
string cacheDir(fmt("%s/%s_channels.db", m_cacheDir.c_str(), disable_emu ? "nand" : DeviceName[currentPartition]));
bool updateCache = disable_emu ? true : m_cfg.getBool(_domainFromView(), "update_cache");
vector<string> NullVector;
m_gameList.CreateList(m_current_view, currentPartition, std::string(),
stringToVector(std::string(), '|'), cacheDir, updateCache);
NullVector, cacheDir, updateCache);
}
lastPartition = currentPartition;
@ -2257,7 +2258,8 @@ bool CMenu::_loadDmlList()
string gameDir(fmt(currentPartition == SD ? DML_DIR : m_DMLgameDir.c_str(), DeviceName[currentPartition]));
string cacheDir(fmt("%s/%s_gamecube.db", m_cacheDir.c_str(), DeviceName[currentPartition]));
bool updateCache = m_cfg.getBool(_domainFromView(), "update_cache");
m_gameList.CreateList(m_current_view, currentPartition, gameDir, stringToVector(".iso", '|'), cacheDir, updateCache);
m_gameList.CreateList(m_current_view, currentPartition, gameDir,
stringToVector(".iso|root", '|'),cacheDir, updateCache);
return m_gameList.size() > 0 ? true : false;
}
@ -2269,52 +2271,50 @@ bool CMenu::_loadEmuList()
return false;
bool updateCache = m_cfg.getBool(_domainFromView(), "update_cache");
DIR *pdir;
struct dirent *pent;
vector<dir_discHdr> emuList;
Config m_plugin_cfg;
pdir = opendir(m_pluginsDir.c_str());
while((pent = readdir(pdir)) != NULL)
vector<string> INI_List;
m_gameList.clear();
m_gameList.GetFiles(m_pluginsDir.c_str(), stringToVector(".ini", '|'), INI_List, false, 1);
for(vector<string>::const_iterator Name = INI_List.begin(); Name != INI_List.end(); ++Name)
{
if(strcmp(pent->d_name, ".") == 0 || strcmp(pent->d_name, "..") == 0 || strcasecmp(pent->d_name, "scummvm.ini") == 0)
if(Name->find("scummvm.ini") != string::npos)
continue;
if(strcasestr(pent->d_name, ".ini") != NULL)
m_plugin_cfg.load(Name->c_str());
if(m_plugin_cfg.loaded())
{
m_plugin_cfg.load(fmt("%s/%s", m_pluginsDir.c_str(), pent->d_name));
if(m_plugin_cfg.loaded())
m_plugin.AddPlugin(m_plugin_cfg);
if(m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").find("scummvm.ini") == string::npos)
{
m_plugin.AddPlugin(m_plugin_cfg);
if(m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").find("scummvm.ini") == string::npos)
{
string gameDir(fmt("%s:/%s", DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").c_str()));
string cacheDir(fmt("%s/%s_%s.db", m_cacheDir.c_str(), DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str()));
string FileTypes(m_plugin_cfg.getString(PLUGIN_DOMAIN,"fileTypes"));
u32 CaseColor = strtoul(m_plugin_cfg.getString(PLUGIN_DOMAIN,"coverColor").c_str(), NULL, 16);
u32 MagicWord = strtoul(m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str(), NULL, 16);
m_gameList.CreateList(m_current_view, currentPartition, gameDir,
stringToVector(FileTypes, '|'), cacheDir, updateCache, CaseColor, MagicWord);
for(vector<dir_discHdr>::iterator tmp_itr = m_gameList.begin(); tmp_itr != m_gameList.end(); tmp_itr++)
emuList.push_back(*tmp_itr);
}
else
{
Config scummvm;
vector<dir_discHdr> scummvmList;
scummvm.load(fmt("%s/%s", m_pluginsDir.c_str(), "scummvm.ini"));
scummvmList = m_plugin.ParseScummvmINI(scummvm, string(DeviceName[currentPartition]));
for(vector<dir_discHdr>::iterator tmp_itr = scummvmList.begin(); tmp_itr != scummvmList.end(); tmp_itr++)
emuList.push_back(*tmp_itr);
}
string gameDir(fmt("%s:/%s", DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").c_str()));
string cacheDir(fmt("%s/%s_%s.db", m_cacheDir.c_str(), DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str()));
vector<string> FileTypes = stringToVector(m_plugin_cfg.getString(PLUGIN_DOMAIN,"fileTypes"), '|');
u32 CaseColor = strtoul(m_plugin_cfg.getString(PLUGIN_DOMAIN,"coverColor").c_str(), NULL, 16);
u32 MagicWord = strtoul(m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str(), NULL, 16);
m_gameList.CreateList(m_current_view, currentPartition, gameDir,
FileTypes, cacheDir, updateCache, CaseColor, MagicWord);
for(vector<dir_discHdr>::iterator tmp_itr = m_gameList.begin(); tmp_itr != m_gameList.end(); tmp_itr++)
emuList.push_back(*tmp_itr);
}
else
{
Config scummvm;
vector<dir_discHdr> scummvmList;
scummvm.load(fmt("%s/%s", m_pluginsDir.c_str(), "scummvm.ini"));
scummvmList = m_plugin.ParseScummvmINI(scummvm, string(DeviceName[currentPartition]));
for(vector<dir_discHdr>::iterator tmp_itr = scummvmList.begin(); tmp_itr != scummvmList.end(); tmp_itr++)
emuList.push_back(*tmp_itr);
}
m_plugin_cfg.unload();
}
m_plugin_cfg.unload();
}
closedir(pdir);
m_gameList.clear();
for(vector<dir_discHdr>::iterator tmp_itr = emuList.begin(); tmp_itr != emuList.end(); tmp_itr++)
{
tmp_itr->index = m_gameList.size();
m_gameList.push_back(*tmp_itr);
}
emuList.clear();
//If we return to the coverflow before wiiflow quit we dont need to reload plugins
m_plugin.EndAdd();

View File

@ -56,7 +56,6 @@ private:
CButtonsMgr m_btnMgr;
CCoverFlow m_cf;
CFanart m_fa;
ListGenerator m_gameList;
Config m_cfg;
Config m_loc;
Config m_cat;

View File

@ -574,7 +574,8 @@ void CMenu::_game(bool launch)
ListGenerator SD_List;
string gameDir(fmt(DML_DIR, DeviceName[SD]));
string cacheDir(fmt("%s/%s_gamecube.db", m_cacheDir.c_str(), DeviceName[SD]));
SD_List.CreateList(COVERFLOW_DML, SD, gameDir, stringToVector(".iso", '|'), cacheDir, false);
SD_List.CreateList(COVERFLOW_DML, SD, gameDir,
stringToVector(".iso|root", '|'), cacheDir, false);
for(vector<dir_discHdr>::iterator List = SD_List.begin(); List != SD_List.end(); List++)
{
if(strncasecmp(hdr->id, List->id, 6) == 0)
@ -758,7 +759,8 @@ void CMenu::directlaunch(const char *GameID)
DeviceHandle.OpenWBFS(currentPartition);
string gameDir(fmt(GAMES_DIR, DeviceName[currentPartition]));
string cacheDir(fmt("%s/%s_wii.db", m_cacheDir.c_str(), DeviceName[currentPartition]));
m_gameList.CreateList(COVERFLOW_USB, currentPartition, gameDir, stringToVector(".wbfs|.iso", '|'), cacheDir, false);
m_gameList.CreateList(COVERFLOW_USB, currentPartition, gameDir,
stringToVector(".wbfs|.iso", '|'), cacheDir, false);
WBFS_Close();
for(u32 i = 0; i < m_gameList.size(); i++)
{

View File

@ -785,14 +785,14 @@ int CMenu::_NandDumper(void *obj)
if(m.m_saveExtGameId.empty())
{
m.m_nandexentry = 0;
saveList.reserve(m.m_gameList.size());
for(u32 i = 0; i < m.m_gameList.size() && !m.m_thrdStop; ++i)
saveList.reserve(m_gameList.size());
for(u32 i = 0; i < m_gameList.size() && !m.m_thrdStop; ++i)
{
LWP_MutexLock(m.m_mutex);
m._setDumpMsg(m._t("cfgne18", L"Listing game saves to extract..."), 0.f, 0.f);
LWP_MutexUnlock(m.m_mutex);
string id((const char *)m.m_gameList[i].id, 4);
string id((const char *)m_gameList[i].id, 4);
if(!missingOnly || !m._checkSave(id, false))
{

View File

@ -14,15 +14,14 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <dirent.h>
#include <cstdio>
#include "MusicPlayer.hpp"
#include "SoundHandler.hpp"
#include "fileOps/fileOps.h"
#include "list/ListGenerator.hpp"
#include "gui/text.hpp"
#include "gecko/gecko.h"
#define MUSIC_DEPTH 10
Musicplayer MusicPlayer;
void Musicplayer::Cleanup()
@ -35,7 +34,7 @@ void Musicplayer::Cleanup()
FileNames.clear();
}
void Musicplayer::Init(Config &cfg, string musicDir, string themeMusicDir)
void Musicplayer::Init(Config &cfg, const string& musicDir, const string& themeMusicDir)
{
Cleanup();
FadeRate = cfg.getInt("GENERAL", "music_fade_rate", 8);
@ -44,8 +43,9 @@ void Musicplayer::Init(Config &cfg, string musicDir, string themeMusicDir)
SetVolume(0);
MusicFile.SetVoice(0);
ScanDirectories(themeMusicDir.c_str());
ScanDirectories(musicDir.c_str());
vector<string> Types = stringToVector(".mp3|.ogg", '|');
m_gameList.GetFiles(musicDir.c_str(), Types, FileNames, false, MUSIC_DEPTH);
m_gameList.GetFiles(themeMusicDir.c_str(), Types, FileNames, false, MUSIC_DEPTH);
if(cfg.getBool("GENERAL", "randomize_music", true) && FileNames.size() > 0)
{
srand(unsigned(time(NULL)));
@ -54,23 +54,6 @@ void Musicplayer::Init(Config &cfg, string musicDir, string themeMusicDir)
CurrentFileName = FileNames.begin();
}
void Musicplayer::ScanDirectories(const char *directory)
{
struct dirent *pent = NULL;
DIR *pdir = opendir(directory);
while((pent = readdir(pdir)) != NULL)
{
if(strcmp(pent->d_name, ".") == 0 || strcmp(pent->d_name, "..") == 0)
continue;
string CurrentItem = sfmt("%s/%s", directory, pent->d_name);
if(fsop_DirExist(CurrentItem.c_str()))
ScanDirectories(CurrentItem.c_str());
else if(strcasestr(pent->d_name, ".mp3") != NULL || strcasestr(pent->d_name, ".ogg") != NULL)
FileNames.push_back(CurrentItem);
}
closedir(pdir);
}
void Musicplayer::SetMaxVolume(u8 volume)
{
Volume = volume;

View File

@ -28,7 +28,7 @@ class Musicplayer
{
public:
void Cleanup();
void Init(Config &cfg, string musicDir, string themeMusicDir);
void Init(Config &cfg, const string& musicDir, const string& themeMusicDir);
void Tick(bool attenuate);
void SetVolume(u8 volume);
@ -49,7 +49,6 @@ public:
protected:
bool PosFromPrevFile();
void LoadCurrentFile();
void ScanDirectories(const char *directory);
u8 Volume;
u8 CurrentVolume;