mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-01 00:55:06 +01:00
-nearly rewrote that list code again lol, should be even faster
and smaller now
This commit is contained in:
parent
68087ab880
commit
b2fa9f672f
Binary file not shown.
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.3 KiB |
@ -390,14 +390,16 @@ STexture::TexErr STexture::fromPNG(const u8 *buffer, u8 f, Alloc alloc, u32 minM
|
|||||||
newWidth >>= 1;
|
newWidth >>= 1;
|
||||||
newHeight >>= 1;
|
newHeight >>= 1;
|
||||||
}
|
}
|
||||||
SmartBuf tmpData2 = smartMem2Alloc(imgProp.imgWidth * imgProp.imgHeight * 4);
|
u32 Size2 = imgProp.imgWidth * imgProp.imgHeight * 4;
|
||||||
|
SmartBuf tmpData2 = smartMem2Alloc(Size2);
|
||||||
|
u32 Size = fixGX_GetTexBufferSize(newWidth, newHeight, f, GX_TRUE, maxLODTmp - minLODTmp);
|
||||||
switch (alloc)
|
switch (alloc)
|
||||||
{
|
{
|
||||||
case ALLOC_MEM2:
|
case ALLOC_MEM2:
|
||||||
tmpData = smartMem2Alloc(fixGX_GetTexBufferSize(newWidth, newHeight, f, GX_TRUE, maxLODTmp - minLODTmp));
|
tmpData = smartMem2Alloc(Size);
|
||||||
break;
|
break;
|
||||||
case ALLOC_MALLOC:
|
case ALLOC_MALLOC:
|
||||||
tmpData = smartMemAlign32(fixGX_GetTexBufferSize(newWidth, newHeight, f, GX_TRUE, maxLODTmp - minLODTmp));
|
tmpData = smartMemAlign32(Size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!tmpData || !tmpData2)
|
if (!tmpData || !tmpData2)
|
||||||
@ -407,9 +409,11 @@ STexture::TexErr STexture::fromPNG(const u8 *buffer, u8 f, Alloc alloc, u32 minM
|
|||||||
PNGU_ReleaseImageContext(ctx);
|
PNGU_ReleaseImageContext(ctx);
|
||||||
return STexture::TE_NOMEM;
|
return STexture::TE_NOMEM;
|
||||||
}
|
}
|
||||||
|
memset(tmpData2.get(), 0, Size2);
|
||||||
|
DCFlushRange(tmpData2.get(), Size2);
|
||||||
PNGU_DecodeToRGBA8(ctx, imgProp.imgWidth, imgProp.imgHeight, tmpData2.get(), 0, 0xFF);
|
PNGU_DecodeToRGBA8(ctx, imgProp.imgWidth, imgProp.imgHeight, tmpData2.get(), 0, 0xFF);
|
||||||
PNGU_ReleaseImageContext(ctx);
|
PNGU_ReleaseImageContext(ctx);
|
||||||
DCFlushRange(tmpData2.get(), imgProp.imgWidth * imgProp.imgHeight * 4);
|
DCFlushRange(tmpData2.get(), Size2);
|
||||||
|
|
||||||
tmpData2 = STexture::_genMipMaps(tmpData2.get(), imgProp.imgWidth, imgProp.imgHeight, maxLODTmp, baseWidth, baseHeight);
|
tmpData2 = STexture::_genMipMaps(tmpData2.get(), imgProp.imgWidth, imgProp.imgHeight, maxLODTmp, baseWidth, baseHeight);
|
||||||
if (!tmpData2) return STexture::TE_NOMEM;
|
if (!tmpData2) return STexture::TE_NOMEM;
|
||||||
@ -419,6 +423,8 @@ STexture::TexErr STexture::fromPNG(const u8 *buffer, u8 f, Alloc alloc, u32 minM
|
|||||||
u8 *pSrc = tmpData2.get();
|
u8 *pSrc = tmpData2.get();
|
||||||
if (minLODTmp > 0)
|
if (minLODTmp > 0)
|
||||||
pSrc += fixGX_GetTexBufferSize(baseWidth, baseHeight, GX_TF_RGBA8, minLODTmp > 1 ? GX_TRUE : GX_FALSE, minLODTmp - 1);
|
pSrc += fixGX_GetTexBufferSize(baseWidth, baseHeight, GX_TF_RGBA8, minLODTmp > 1 ? GX_TRUE : GX_FALSE, minLODTmp - 1);
|
||||||
|
memset(tmpData.get(), 0, Size);
|
||||||
|
DCFlushRange(tmpData.get(), Size);
|
||||||
u8 *pDst = tmpData.get();
|
u8 *pDst = tmpData.get();
|
||||||
for (u8 i = minLODTmp; i <= maxLODTmp; ++i)
|
for (u8 i = minLODTmp; i <= maxLODTmp; ++i)
|
||||||
{
|
{
|
||||||
@ -448,13 +454,14 @@ STexture::TexErr STexture::fromPNG(const u8 *buffer, u8 f, Alloc alloc, u32 minM
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
u32 Size = GX_GetTexBufferSize(pngWidth, pngHeight, f, GX_FALSE, 0);
|
||||||
switch (alloc)
|
switch (alloc)
|
||||||
{
|
{
|
||||||
case ALLOC_MEM2:
|
case ALLOC_MEM2:
|
||||||
tmpData = smartMem2Alloc(GX_GetTexBufferSize(pngWidth, pngHeight, f, GX_FALSE, maxLOD));
|
tmpData = smartMem2Alloc(Size);
|
||||||
break;
|
break;
|
||||||
case ALLOC_MALLOC:
|
case ALLOC_MALLOC:
|
||||||
tmpData = smartMemAlign32(GX_GetTexBufferSize(pngWidth, pngHeight, f, GX_FALSE, maxLOD));
|
tmpData = smartMemAlign32(Size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!tmpData)
|
if (!tmpData)
|
||||||
@ -462,6 +469,8 @@ STexture::TexErr STexture::fromPNG(const u8 *buffer, u8 f, Alloc alloc, u32 minM
|
|||||||
PNGU_ReleaseImageContext(ctx);
|
PNGU_ReleaseImageContext(ctx);
|
||||||
return STexture::TE_NOMEM;
|
return STexture::TE_NOMEM;
|
||||||
}
|
}
|
||||||
|
memset(tmpData.get(), 0, Size);
|
||||||
|
DCFlushRange(tmpData.get(), Size);
|
||||||
format = f;
|
format = f;
|
||||||
width = pngWidth;
|
width = pngWidth;
|
||||||
height = pngHeight;
|
height = pngHeight;
|
||||||
@ -480,7 +489,7 @@ STexture::TexErr STexture::fromPNG(const u8 *buffer, u8 f, Alloc alloc, u32 minM
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
PNGU_ReleaseImageContext(ctx);
|
PNGU_ReleaseImageContext(ctx);
|
||||||
DCFlushRange(data.get(), GX_GetTexBufferSize(width, height, format, GX_FALSE, 0));
|
DCFlushRange(data.get(), Size);
|
||||||
}
|
}
|
||||||
return STexture::TE_OK;
|
return STexture::TE_OK;
|
||||||
}
|
}
|
||||||
@ -603,6 +612,8 @@ SmartBuf STexture::_genMipMaps(const u8 *src, u32 width, u32 height, u8 maxLOD,
|
|||||||
u32 bufSize = fixGX_GetTexBufferSize(lod0Width, lod0Height, GX_TF_RGBA8, GX_TRUE, maxLOD);
|
u32 bufSize = fixGX_GetTexBufferSize(lod0Width, lod0Height, GX_TF_RGBA8, GX_TRUE, maxLOD);
|
||||||
SmartBuf dst = smartMem2Alloc(bufSize);
|
SmartBuf dst = smartMem2Alloc(bufSize);
|
||||||
if (!dst) return dst;
|
if (!dst) return dst;
|
||||||
|
memset(dst.get(), 0, bufSize);
|
||||||
|
DCFlushRange(dst.get(), bufSize);
|
||||||
STexture::_resize(dst.get(), lod0Width, lod0Height, src, width, height);
|
STexture::_resize(dst.get(), lod0Width, lod0Height, src, width, height);
|
||||||
DCFlushRange(dst.get(), lod0Width * lod0Height * 4);
|
DCFlushRange(dst.get(), lod0Width * lod0Height * 4);
|
||||||
u32 nWidth = lod0Width;
|
u32 nWidth = lod0Width;
|
||||||
|
@ -24,6 +24,12 @@
|
|||||||
#include "gui/text.hpp"
|
#include "gui/text.hpp"
|
||||||
|
|
||||||
ListGenerator m_gameList;
|
ListGenerator m_gameList;
|
||||||
|
static Config CustomTitles;
|
||||||
|
static GameTDB gameTDB;
|
||||||
|
|
||||||
|
static dir_discHdr ListElement;
|
||||||
|
static discHdr WiiGameHeader;
|
||||||
|
static gc_discHdr GCGameHeader;
|
||||||
|
|
||||||
void ListGenerator::Init(const char *settingsDir, const char *Language)
|
void ListGenerator::Init(const char *settingsDir, const char *Language)
|
||||||
{
|
{
|
||||||
@ -38,7 +44,6 @@ void ListGenerator::Init(const char *settingsDir, const char *Language)
|
|||||||
void ListGenerator::Cleanup()
|
void ListGenerator::Cleanup()
|
||||||
{
|
{
|
||||||
this->clear(); //clear gamelist
|
this->clear(); //clear gamelist
|
||||||
InternalList.clear(); //clear pathlist
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListGenerator::OpenConfigs()
|
void ListGenerator::OpenConfigs()
|
||||||
@ -57,198 +62,11 @@ void ListGenerator::CloseConfigs()
|
|||||||
CustomTitles.unload();
|
CustomTitles.unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListGenerator::CreateList(u32 Flow, u32 Device, const string& Path, const vector<string>& FileTypes,
|
static void AddISO(const char *GameID, const char *GameTitle, const char *GamePath,
|
||||||
const string& DBName, bool UpdateCache, u32 Color, u32 Magic)
|
u32 GameColor, u8 Type)
|
||||||
{
|
{
|
||||||
Cleanup();
|
|
||||||
if(!DBName.empty())
|
|
||||||
{
|
|
||||||
if(UpdateCache)
|
|
||||||
fsop_deleteFile(DBName.c_str());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CCache(*this, DBName, LOAD);
|
|
||||||
if(!this->empty())
|
|
||||||
return;
|
|
||||||
fsop_deleteFile(DBName.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OpenConfigs();
|
|
||||||
if(Flow == COVERFLOW_USB)
|
|
||||||
{
|
|
||||||
if(DeviceHandle.GetFSType(Device) == PART_FS_WBFS)
|
|
||||||
Create_Wii_WBFS_List(DeviceHandle.GetWbfsHandle(Device));
|
|
||||||
else
|
|
||||||
Create_Wii_EXT_List(Path, FileTypes);
|
|
||||||
}
|
|
||||||
else if(Flow == COVERFLOW_CHANNEL)
|
|
||||||
Create_Channel_List();
|
|
||||||
else if(DeviceHandle.GetFSType(Device) != PART_FS_WBFS)
|
|
||||||
{
|
|
||||||
if(Flow == COVERFLOW_DML)
|
|
||||||
Create_GC_List(Path, FileTypes);
|
|
||||||
else if(Flow == COVERFLOW_PLUGIN)
|
|
||||||
Create_Plugin_List(Path, FileTypes, Color, Magic);
|
|
||||||
else if(Flow == COVERFLOW_HOMEBREW)
|
|
||||||
Create_Homebrew_List(Path, FileTypes);
|
|
||||||
}
|
|
||||||
CloseConfigs();
|
|
||||||
if(!this->empty() && !DBName.empty()) /* Write a new Cache */
|
|
||||||
CCache(*this, DBName, SAVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListGenerator::Create_Wii_WBFS_List(wbfs_t *handle)
|
|
||||||
{
|
|
||||||
for(u32 i = 0; i < wbfs_count_discs(handle); i++)
|
|
||||||
{
|
|
||||||
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(const string& Path, const vector<string>& FileTypes)
|
|
||||||
{
|
|
||||||
GetFiles(Path.c_str(), FileTypes, InternalList, false);
|
|
||||||
for(vector<string>::iterator Name = InternalList.begin(); Name != InternalList.end(); Name++)
|
|
||||||
{
|
|
||||||
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*)&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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InternalList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListGenerator::Create_GC_List(const string& Path, const vector<string>& FileTypes)
|
|
||||||
{
|
|
||||||
GetFiles(Path.c_str(), FileTypes, InternalList, true);
|
|
||||||
for(vector<string>::iterator Name = InternalList.begin(); Name != InternalList.end(); Name++)
|
|
||||||
{
|
|
||||||
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");
|
|
||||||
fp = fopen(Name->c_str(), "rb");
|
|
||||||
}
|
|
||||||
if(fp)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
InternalList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListGenerator::Create_Plugin_List(const string& Path, const vector<string>& FileTypes,
|
|
||||||
u32 Color, u32 Magic)
|
|
||||||
{
|
|
||||||
dir_discHdr ListElement;
|
|
||||||
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();
|
|
||||||
strncpy(ListElement.path, Name->c_str(), sizeof(ListElement.path));
|
|
||||||
strncpy(ListElement.id, "PLUGIN", 6);
|
|
||||||
|
|
||||||
string Title(Name->begin() + Name->find_last_of('/') + 1, Name->begin() + Name->find_last_of('.'));
|
|
||||||
mbstowcs(ListElement.title, Title.c_str(), 63);
|
|
||||||
Asciify(ListElement.title);
|
|
||||||
|
|
||||||
ListElement.settings[0] = Magic; //Plugin magic
|
|
||||||
ListElement.casecolor = Color;
|
|
||||||
ListElement.type = TYPE_PLUGIN;
|
|
||||||
this->push_back(ListElement);
|
|
||||||
}
|
|
||||||
InternalList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListGenerator::Create_Homebrew_List(const string& Path, const vector<string>& FileTypes)
|
|
||||||
{
|
|
||||||
dir_discHdr ListElement;
|
|
||||||
GetFiles(Path.c_str(), FileTypes, InternalList, false);
|
|
||||||
for(vector<string>::iterator Name = InternalList.begin(); Name != InternalList.end(); Name++)
|
|
||||||
{
|
|
||||||
if(Name->find("boot.") == string::npos)
|
|
||||||
continue;
|
|
||||||
memset((void*)&ListElement, 0, sizeof(dir_discHdr));
|
|
||||||
ListElement.index = this->size();
|
|
||||||
Name->erase(Name->begin() + Name->find_last_of('/'), Name->end());
|
|
||||||
strncpy(ListElement.path, Name->c_str(), sizeof(ListElement.path));
|
|
||||||
strncpy(ListElement.id, "HB_APP", 6);
|
|
||||||
|
|
||||||
string FolderTitle(Name->begin() + Name->find_last_of('/') + 1, Name->end());
|
|
||||||
ListElement.casecolor = CustomTitles.getColor("COVERS", FolderTitle.c_str(), 1).intVal();
|
|
||||||
string CustomTitle = CustomTitles.getString("TITLES", FolderTitle.c_str());
|
|
||||||
if(CustomTitle.size() > 0)
|
|
||||||
mbstowcs(ListElement.title, CustomTitle.c_str(), 63);
|
|
||||||
else
|
|
||||||
mbstowcs(ListElement.title, FolderTitle.c_str(), 63);
|
|
||||||
Asciify(ListElement.title);
|
|
||||||
|
|
||||||
ListElement.type = TYPE_HOMEBREW;
|
|
||||||
this->push_back(ListElement);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
InternalList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListGenerator::Create_Channel_List()
|
|
||||||
{
|
|
||||||
u32 GameColor = 1;
|
|
||||||
dir_discHdr ListElement;
|
|
||||||
ChannelHandle.Init(0, gameTDB_Language, true);
|
|
||||||
for(int i = 0; i < ChannelHandle.Count(); i++)
|
|
||||||
{
|
|
||||||
Channel *chan = ChannelHandle.GetChannel(i);
|
|
||||||
if(chan->id == NULL)
|
|
||||||
continue; // Skip invalid channels
|
|
||||||
memset((void*)&ListElement, 0, sizeof(dir_discHdr));
|
|
||||||
ListElement.index = this->size();
|
|
||||||
ListElement.settings[0] = TITLE_UPPER(chan->title);
|
|
||||||
ListElement.settings[1] = TITLE_LOWER(chan->title);
|
|
||||||
strncpy(ListElement.id, chan->id, 4);
|
|
||||||
ListElement.casecolor = CustomTitles.getColor("COVERS", ListElement.id, GameColor).intVal();
|
|
||||||
string CustomTitle = CustomTitles.getString("TITLES", ListElement.id);
|
|
||||||
if(gameTDB.IsLoaded())
|
|
||||||
{
|
|
||||||
if(ListElement.casecolor == GameColor)
|
|
||||||
ListElement.casecolor = gameTDB.GetCaseColor(ListElement.id);
|
|
||||||
if(CustomTitle.size() == 0)
|
|
||||||
gameTDB.GetTitle(ListElement.id, CustomTitle);
|
|
||||||
ListElement.wifi = gameTDB.GetWifiPlayers(ListElement.id);
|
|
||||||
ListElement.players = gameTDB.GetPlayers(ListElement.id);
|
|
||||||
}
|
|
||||||
if(CustomTitle.size() > 0)
|
|
||||||
mbstowcs(ListElement.title, CustomTitle.c_str(), 63);
|
|
||||||
else
|
|
||||||
wcsncpy(ListElement.title, chan->name, 64);
|
|
||||||
ListElement.type = TYPE_CHANNEL;
|
|
||||||
this->push_back(ListElement);
|
|
||||||
}
|
|
||||||
InternalList.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ListGenerator::AddISO(const char *GameID, const char *GameTitle, const char *GamePath, u32 GameColor, u8 Type)
|
|
||||||
{
|
|
||||||
dir_discHdr ListElement;
|
|
||||||
memset((void*)&ListElement, 0, sizeof(dir_discHdr));
|
memset((void*)&ListElement, 0, sizeof(dir_discHdr));
|
||||||
ListElement.index = this->size();
|
ListElement.index = m_gameList.size();
|
||||||
if(GameID != NULL) strncpy(ListElement.id, GameID, 6);
|
if(GameID != NULL) strncpy(ListElement.id, GameID, 6);
|
||||||
if(GamePath != NULL) strncpy(ListElement.path, GamePath, sizeof(ListElement.path));
|
if(GamePath != NULL) strncpy(ListElement.path, GamePath, sizeof(ListElement.path));
|
||||||
ListElement.casecolor = CustomTitles.getColor("COVERS", ListElement.id, GameColor).intVal();
|
ListElement.casecolor = CustomTitles.getColor("COVERS", ListElement.id, GameColor).intVal();
|
||||||
@ -269,10 +87,172 @@ void ListGenerator::AddISO(const char *GameID, const char *GameTitle, const char
|
|||||||
Asciify(ListElement.title);
|
Asciify(ListElement.title);
|
||||||
|
|
||||||
ListElement.type = Type;
|
ListElement.type = Type;
|
||||||
this->push_back(ListElement); //I am a vector! :P
|
m_gameList.push_back(ListElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListGenerator::IsFileSupported(const char *File, const vector<string>& FileTypes)
|
static void Create_Wii_WBFS_List(wbfs_t *handle)
|
||||||
|
{
|
||||||
|
for(u32 i = 0; i < wbfs_count_discs(handle); i++)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Create_Wii_EXT_List(char *FullPath)
|
||||||
|
{
|
||||||
|
FILE *fp = fopen(FullPath, "rb");
|
||||||
|
if(fp)
|
||||||
|
{
|
||||||
|
fseek(fp, strcasestr(FullPath, ".wbfs") != NULL ? 512 : 0, SEEK_SET);
|
||||||
|
fread((void*)&WiiGameHeader, 1, sizeof(discHdr), fp);
|
||||||
|
if(WiiGameHeader.magic == WII_MAGIC)
|
||||||
|
AddISO((const char*)WiiGameHeader.id, (const char*)WiiGameHeader.title,
|
||||||
|
FullPath, 1, TYPE_WII_GAME);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Create_GC_List(char *FullPath)
|
||||||
|
{
|
||||||
|
static const char *FST_APPEND = "sys/boot.bin";
|
||||||
|
|
||||||
|
FILE *fp = fopen(FullPath, "rb");
|
||||||
|
if(!fp && strstr(FullPath, "/root") != NULL) //fst folder
|
||||||
|
{
|
||||||
|
*(strstr(FullPath, "/root") + 1) = '\0';
|
||||||
|
if(strlen(FullPath) + strlen(FST_APPEND) < 255) strcat(FullPath, FST_APPEND);
|
||||||
|
fp = fopen(FullPath, "rb");
|
||||||
|
}
|
||||||
|
if(fp)
|
||||||
|
{
|
||||||
|
fread((void*)&GCGameHeader, 1, sizeof(gc_discHdr), fp);
|
||||||
|
if(GCGameHeader.magic == GC_MAGIC)
|
||||||
|
AddISO((const char*)GCGameHeader.id, (const char*)GCGameHeader.title,
|
||||||
|
FullPath, 0, TYPE_GC_GAME);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Create_Plugin_List(char *FullPath)
|
||||||
|
{
|
||||||
|
memset((void*)&ListElement, 0, sizeof(dir_discHdr));
|
||||||
|
|
||||||
|
strncpy(ListElement.path, FullPath, sizeof(ListElement.path));
|
||||||
|
strncpy(ListElement.id, "PLUGIN", 6);
|
||||||
|
*strchr(FullPath, '.') = '\0';
|
||||||
|
mbstowcs(ListElement.title, strrchr(FullPath, '/') + 1, 63);
|
||||||
|
Asciify(ListElement.title);
|
||||||
|
|
||||||
|
ListElement.settings[0] = m_gameList.Magic; //Plugin magic
|
||||||
|
ListElement.casecolor = m_gameList.Color;
|
||||||
|
ListElement.type = TYPE_PLUGIN;
|
||||||
|
m_gameList.push_back(ListElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Create_Homebrew_List(char *FullPath)
|
||||||
|
{
|
||||||
|
if(strcasestr(FullPath, "boot.") == NULL)
|
||||||
|
return;
|
||||||
|
memset((void*)&ListElement, 0, sizeof(dir_discHdr));
|
||||||
|
ListElement.index = m_gameList.size();
|
||||||
|
*strrchr(FullPath, '/') = '\0';
|
||||||
|
strncpy(ListElement.path, FullPath, sizeof(ListElement.path));
|
||||||
|
strncpy(ListElement.id, "HB_APP", 6);
|
||||||
|
|
||||||
|
static const char *FolderTitle = strrchr(FullPath, '/') + 1;
|
||||||
|
ListElement.casecolor = CustomTitles.getColor("COVERS", FolderTitle, 1).intVal();
|
||||||
|
const string &CustomTitle = CustomTitles.getString("TITLES", FolderTitle);
|
||||||
|
if(CustomTitle.size() > 0)
|
||||||
|
mbstowcs(ListElement.title, CustomTitle.c_str(), 63);
|
||||||
|
else
|
||||||
|
mbstowcs(ListElement.title, FolderTitle, 63);
|
||||||
|
Asciify(ListElement.title);
|
||||||
|
|
||||||
|
ListElement.type = TYPE_HOMEBREW;
|
||||||
|
m_gameList.push_back(ListElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Create_Channel_List()
|
||||||
|
{
|
||||||
|
for(int i = 0; i < ChannelHandle.Count(); i++)
|
||||||
|
{
|
||||||
|
Channel *chan = ChannelHandle.GetChannel(i);
|
||||||
|
if(chan->id == NULL)
|
||||||
|
continue; // Skip invalid channels
|
||||||
|
memset((void*)&ListElement, 0, sizeof(dir_discHdr));
|
||||||
|
ListElement.index = m_gameList.size();
|
||||||
|
ListElement.settings[0] = TITLE_UPPER(chan->title);
|
||||||
|
ListElement.settings[1] = TITLE_LOWER(chan->title);
|
||||||
|
strncpy(ListElement.id, chan->id, 4);
|
||||||
|
ListElement.casecolor = CustomTitles.getColor("COVERS", ListElement.id, 1).intVal();
|
||||||
|
string CustomTitle = CustomTitles.getString("TITLES", ListElement.id);
|
||||||
|
if(gameTDB.IsLoaded())
|
||||||
|
{
|
||||||
|
if(ListElement.casecolor == 1)
|
||||||
|
ListElement.casecolor = gameTDB.GetCaseColor(ListElement.id);
|
||||||
|
if(CustomTitle.size() == 0)
|
||||||
|
gameTDB.GetTitle(ListElement.id, CustomTitle);
|
||||||
|
ListElement.wifi = gameTDB.GetWifiPlayers(ListElement.id);
|
||||||
|
ListElement.players = gameTDB.GetPlayers(ListElement.id);
|
||||||
|
}
|
||||||
|
if(CustomTitle.size() > 0)
|
||||||
|
mbstowcs(ListElement.title, CustomTitle.c_str(), 63);
|
||||||
|
else
|
||||||
|
wcsncpy(ListElement.title, chan->name, 64);
|
||||||
|
ListElement.type = TYPE_CHANNEL;
|
||||||
|
m_gameList.push_back(ListElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListGenerator::CreateList(u32 Flow, u32 Device, const string& Path, const vector<string>& FileTypes,
|
||||||
|
const string& DBName, bool UpdateCache)
|
||||||
|
{
|
||||||
|
Cleanup();
|
||||||
|
if(!DBName.empty())
|
||||||
|
{
|
||||||
|
if(UpdateCache)
|
||||||
|
fsop_deleteFile(DBName.c_str());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CCache(*this, DBName, LOAD);
|
||||||
|
if(!this->empty())
|
||||||
|
return;
|
||||||
|
fsop_deleteFile(DBName.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(Flow != COVERFLOW_PLUGIN)
|
||||||
|
OpenConfigs();
|
||||||
|
if(Flow == COVERFLOW_USB)
|
||||||
|
{
|
||||||
|
if(DeviceHandle.GetFSType(Device) == PART_FS_WBFS)
|
||||||
|
Create_Wii_WBFS_List(DeviceHandle.GetWbfsHandle(Device));
|
||||||
|
else
|
||||||
|
GetFiles(Path.c_str(), FileTypes, Create_Wii_EXT_List, false);
|
||||||
|
}
|
||||||
|
else if(Flow == COVERFLOW_CHANNEL)
|
||||||
|
{
|
||||||
|
ChannelHandle.Init(0, gameTDB_Language, true);
|
||||||
|
Create_Channel_List();
|
||||||
|
}
|
||||||
|
else if(DeviceHandle.GetFSType(Device) != PART_FS_WBFS)
|
||||||
|
{
|
||||||
|
if(Flow == COVERFLOW_DML)
|
||||||
|
GetFiles(Path.c_str(), FileTypes, Create_GC_List, true);
|
||||||
|
else if(Flow == COVERFLOW_PLUGIN)
|
||||||
|
GetFiles(Path.c_str(), FileTypes, Create_Plugin_List, false, 30);
|
||||||
|
else if(Flow == COVERFLOW_HOMEBREW)
|
||||||
|
GetFiles(Path.c_str(), FileTypes, Create_Homebrew_List, false);
|
||||||
|
}
|
||||||
|
CloseConfigs();
|
||||||
|
if(!this->empty() && !DBName.empty()) /* Write a new Cache */
|
||||||
|
CCache(*this, DBName, SAVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool IsFileSupported(const char *File, const vector<string>& FileTypes)
|
||||||
{
|
{
|
||||||
for(vector<string>::const_iterator cmp = FileTypes.begin(); cmp != FileTypes.end(); ++cmp)
|
for(vector<string>::const_iterator cmp = FileTypes.begin(); cmp != FileTypes.end(); ++cmp)
|
||||||
{
|
{
|
||||||
@ -282,42 +262,52 @@ bool ListGenerator::IsFileSupported(const char *File, const vector<string>& File
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListGenerator::GetFiles(const char *Path, const vector<string>& FileTypes,
|
void GetFiles(const char *Path, const vector<string>& FileTypes,
|
||||||
vector<string>& FileList, bool CompareFolders, u32 max_depth, u32 depth)
|
FileAdder AddFile, bool CompareFolders, u32 max_depth, u32 depth)
|
||||||
{
|
{
|
||||||
struct dirent *pent = NULL;
|
static const char *NewFileName = NULL;
|
||||||
vector<string> SubPaths;
|
static dirent *pent = NULL;
|
||||||
DIR *pdir = opendir(Path);
|
static DIR *pdir = NULL;
|
||||||
|
|
||||||
|
pdir = opendir(Path);
|
||||||
if(pdir == NULL)
|
if(pdir == NULL)
|
||||||
return;
|
return;
|
||||||
|
char *FullPathChar = (char*)MEM2_alloc(256);
|
||||||
|
if(FullPathChar == NULL)
|
||||||
|
return;
|
||||||
while((pent = readdir(pdir)) != NULL)
|
while((pent = readdir(pdir)) != NULL)
|
||||||
{
|
{
|
||||||
if(strcmp(pent->d_name, ".") == 0 || strcmp(pent->d_name, "..") == 0)
|
if(pent->d_name[0] == '.')
|
||||||
continue;
|
continue;
|
||||||
string CurrentItem = sfmt("%s/%s", Path, pent->d_name);
|
memset(FullPathChar, 0, 256);
|
||||||
|
strncpy(FullPathChar, fmt("%s/%s", Path, pent->d_name), 255);
|
||||||
if(pent->d_type == DT_DIR)
|
if(pent->d_type == DT_DIR)
|
||||||
{
|
{
|
||||||
if(CompareFolders && IsFileSupported(pent->d_name, FileTypes))
|
if(CompareFolders && IsFileSupported(pent->d_name, FileTypes))
|
||||||
{
|
{
|
||||||
FileList.push_back(CurrentItem);
|
AddFile(FullPathChar);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if(depth < max_depth)
|
else if(depth < max_depth)
|
||||||
SubPaths.push_back(CurrentItem); //thanks to libntfs for a complicated way
|
{
|
||||||
|
u64 currentPos = telldir(pdir);
|
||||||
|
closedir(pdir); //thanks libntfs
|
||||||
|
GetFiles(FullPathChar, FileTypes, AddFile, CompareFolders, max_depth, depth + 1);
|
||||||
|
pdir = opendir(Path);
|
||||||
|
seekdir(pdir, currentPos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(pent->d_type == DT_REG)
|
else if(pent->d_type == DT_REG)
|
||||||
{
|
{
|
||||||
const char *FileName = strstr(pent->d_name, ".");
|
NewFileName = strchr(pent->d_name, '.');
|
||||||
if(FileName == NULL) FileName = pent->d_name;
|
if(NewFileName == NULL) NewFileName = pent->d_name;
|
||||||
if(IsFileSupported(FileName, FileTypes))
|
if(IsFileSupported(NewFileName, FileTypes))
|
||||||
{
|
{
|
||||||
FileList.push_back(CurrentItem);
|
AddFile(FullPathChar);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
MEM2_free(FullPathChar);
|
||||||
closedir(pdir);
|
closedir(pdir);
|
||||||
for(vector<string>::iterator SubPath = SubPaths.begin(); SubPath != SubPaths.end(); SubPath++)
|
|
||||||
GetFiles(SubPath->c_str(), FileTypes, FileList, CompareFolders, max_depth, depth + 1);
|
|
||||||
SubPaths.clear();
|
|
||||||
}
|
}
|
||||||
|
@ -35,31 +35,20 @@ public:
|
|||||||
void Init(const char *settingsDir, const char *Language);
|
void Init(const char *settingsDir, const char *Language);
|
||||||
void Cleanup();
|
void Cleanup();
|
||||||
void CreateList(u32 Flow, u32 Device, const string& Path, const vector<string>& FileTypes,
|
void CreateList(u32 Flow, u32 Device, const string& Path, const vector<string>& FileTypes,
|
||||||
const string& DBName, bool UpdateCache, u32 Color = 0, u32 Magic = 0);
|
const string& DBName, bool UpdateCache);
|
||||||
void GetFiles(const char *Path, const vector<string>& FileTypes, vector<string>& FileList,
|
u32 Color;
|
||||||
bool CompareFolders, u32 max_depth = 2, u32 depth = 1);
|
u32 Magic;
|
||||||
private:
|
private:
|
||||||
void Create_Wii_WBFS_List(wbfs_t *handle);
|
|
||||||
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 Create_Channel_List();
|
|
||||||
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 OpenConfigs();
|
||||||
void CloseConfigs();
|
void CloseConfigs();
|
||||||
string gameTDB_Path;
|
string gameTDB_Path;
|
||||||
string CustomTitlesPath;
|
string CustomTitlesPath;
|
||||||
string gameTDB_Language;
|
string gameTDB_Language;
|
||||||
GameTDB gameTDB;
|
|
||||||
Config CustomTitles;
|
|
||||||
vector<string> InternalList;
|
|
||||||
discHdr WiiGameHeader;
|
|
||||||
gc_discHdr GCGameHeader;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (*FileAdder)(char *Path);
|
||||||
|
void GetFiles(const char *Path, const vector<string>& FileTypes,
|
||||||
|
FileAdder AddFile, bool CompareFolders, u32 max_depth = 2, u32 depth = 1);
|
||||||
extern ListGenerator m_gameList;
|
extern ListGenerator m_gameList;
|
||||||
|
|
||||||
#endif /*_LISTGENERATOR_HPP_*/
|
#endif /*_LISTGENERATOR_HPP_*/
|
||||||
|
@ -2266,6 +2266,13 @@ bool CMenu::_loadDmlList()
|
|||||||
return m_gameList.size() > 0 ? true : false;
|
return m_gameList.size() > 0 ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static vector<string> INI_List;
|
||||||
|
static void GrabINIFiles(char *FullPath)
|
||||||
|
{
|
||||||
|
//Just push back
|
||||||
|
INI_List.push_back(FullPath);
|
||||||
|
}
|
||||||
|
|
||||||
bool CMenu::_loadEmuList()
|
bool CMenu::_loadEmuList()
|
||||||
{
|
{
|
||||||
currentPartition = m_cfg.getInt("EMULATOR", "partition", SD);
|
currentPartition = m_cfg.getInt("EMULATOR", "partition", SD);
|
||||||
@ -2276,9 +2283,9 @@ bool CMenu::_loadEmuList()
|
|||||||
vector<dir_discHdr> emuList;
|
vector<dir_discHdr> emuList;
|
||||||
Config m_plugin_cfg;
|
Config m_plugin_cfg;
|
||||||
|
|
||||||
vector<string> INI_List;
|
INI_List.clear();
|
||||||
m_gameList.clear();
|
m_gameList.clear();
|
||||||
m_gameList.GetFiles(m_pluginsDir.c_str(), stringToVector(".ini", '|'), INI_List, false, 1);
|
GetFiles(m_pluginsDir.c_str(), stringToVector(".ini", '|'), GrabINIFiles, false, 1);
|
||||||
for(vector<string>::const_iterator Name = INI_List.begin(); Name != INI_List.end(); ++Name)
|
for(vector<string>::const_iterator Name = INI_List.begin(); Name != INI_List.end(); ++Name)
|
||||||
{
|
{
|
||||||
if(Name->find("scummvm.ini") != string::npos)
|
if(Name->find("scummvm.ini") != string::npos)
|
||||||
@ -2292,10 +2299,9 @@ bool CMenu::_loadEmuList()
|
|||||||
string gameDir(fmt("%s:/%s", DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").c_str()));
|
string gameDir(fmt("%s:/%s", DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"romDir").c_str()));
|
||||||
string cacheDir(fmt("%s/%s_%s.db", m_listCacheDir.c_str(), DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str()));
|
string cacheDir(fmt("%s/%s_%s.db", m_listCacheDir.c_str(), DeviceName[currentPartition], m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str()));
|
||||||
vector<string> FileTypes = stringToVector(m_plugin_cfg.getString(PLUGIN_DOMAIN,"fileTypes"), '|');
|
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);
|
m_gameList.Color = 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.Magic = strtoul(m_plugin_cfg.getString(PLUGIN_DOMAIN,"magic").c_str(), NULL, 16);
|
||||||
m_gameList.CreateList(m_current_view, currentPartition, gameDir,
|
m_gameList.CreateList(m_current_view, currentPartition, gameDir, FileTypes, cacheDir, updateCache);
|
||||||
FileTypes, cacheDir, updateCache, CaseColor, MagicWord);
|
|
||||||
for(vector<dir_discHdr>::iterator tmp_itr = m_gameList.begin(); tmp_itr != m_gameList.end(); tmp_itr++)
|
for(vector<dir_discHdr>::iterator tmp_itr = m_gameList.begin(); tmp_itr != m_gameList.end(); tmp_itr++)
|
||||||
emuList.push_back(*tmp_itr);
|
emuList.push_back(*tmp_itr);
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,9 @@
|
|||||||
#define MUSIC_DEPTH 10
|
#define MUSIC_DEPTH 10
|
||||||
Musicplayer MusicPlayer;
|
Musicplayer MusicPlayer;
|
||||||
|
|
||||||
|
static vector<string> FileNames;
|
||||||
|
static vector<string>::const_iterator CurrentFileName;
|
||||||
|
|
||||||
void Musicplayer::Cleanup()
|
void Musicplayer::Cleanup()
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
@ -34,6 +37,12 @@ void Musicplayer::Cleanup()
|
|||||||
FileNames.clear();
|
FileNames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void FileNameAdder(char *Path)
|
||||||
|
{
|
||||||
|
/* No need for more checks */
|
||||||
|
FileNames.push_back(Path);
|
||||||
|
}
|
||||||
|
|
||||||
void Musicplayer::Init(Config &cfg, const string& musicDir, const string& themeMusicDir)
|
void Musicplayer::Init(Config &cfg, const string& musicDir, const string& themeMusicDir)
|
||||||
{
|
{
|
||||||
Cleanup();
|
Cleanup();
|
||||||
@ -44,8 +53,8 @@ void Musicplayer::Init(Config &cfg, const string& musicDir, const string& themeM
|
|||||||
MusicFile.SetVoice(0);
|
MusicFile.SetVoice(0);
|
||||||
|
|
||||||
vector<string> Types = stringToVector(".mp3|.ogg", '|');
|
vector<string> Types = stringToVector(".mp3|.ogg", '|');
|
||||||
m_gameList.GetFiles(musicDir.c_str(), Types, FileNames, false, MUSIC_DEPTH);
|
GetFiles(musicDir.c_str(), Types, FileNameAdder, false, MUSIC_DEPTH);
|
||||||
m_gameList.GetFiles(themeMusicDir.c_str(), Types, FileNames, false, MUSIC_DEPTH);
|
GetFiles(themeMusicDir.c_str(), Types, FileNameAdder, false, MUSIC_DEPTH);
|
||||||
if(cfg.getBool("GENERAL", "randomize_music", true) && FileNames.size() > 0)
|
if(cfg.getBool("GENERAL", "randomize_music", true) && FileNames.size() > 0)
|
||||||
{
|
{
|
||||||
srand(unsigned(time(NULL)));
|
srand(unsigned(time(NULL)));
|
||||||
@ -73,7 +82,7 @@ void Musicplayer::Previous()
|
|||||||
|
|
||||||
if(CurrentFileName == FileNames.begin())
|
if(CurrentFileName == FileNames.begin())
|
||||||
CurrentFileName = FileNames.end();
|
CurrentFileName = FileNames.end();
|
||||||
CurrentFileName--;
|
--CurrentFileName;
|
||||||
LoadCurrentFile();
|
LoadCurrentFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +91,7 @@ void Musicplayer::Next()
|
|||||||
if(FileNames.empty() || PosFromPrevFile())
|
if(FileNames.empty() || PosFromPrevFile())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CurrentFileName++;
|
++CurrentFileName;
|
||||||
if(CurrentFileName == FileNames.end())
|
if(CurrentFileName == FileNames.end())
|
||||||
CurrentFileName = FileNames.begin();
|
CurrentFileName = FileNames.begin();
|
||||||
LoadCurrentFile();
|
LoadCurrentFile();
|
||||||
|
@ -58,8 +58,6 @@ protected:
|
|||||||
bool MusicChanged;
|
bool MusicChanged;
|
||||||
|
|
||||||
GuiSound MusicFile;
|
GuiSound MusicFile;
|
||||||
vector<string> FileNames;
|
|
||||||
vector<string>::iterator CurrentFileName;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Musicplayer MusicPlayer;
|
extern Musicplayer MusicPlayer;
|
||||||
|
Loading…
Reference in New Issue
Block a user