Display banners correctly on Korean consoles

This is a workaround. Ideally a lightweight Korean banner font should be loaded.
This commit is contained in:
wiidev 2021-08-01 18:00:20 +01:00
parent 6b0a425bb0
commit 6d240872bb
8 changed files with 301 additions and 165 deletions

View File

@ -368,6 +368,18 @@ Pane* Layout::FindPane(const std::string& find_name)
return NULL; return NULL;
} }
Pane* Layout::FindPanePartial(const std::string& find_name)
{
for(u32 i = 0; i < panes.size(); ++i)
{
Pane* found = panes[i]->FindPanePartial(find_name, find_name.length());
if(found)
return found;
}
return NULL;
}
Material* Layout::FindMaterial(const std::string& find_name) Material* Layout::FindMaterial(const std::string& find_name)
{ {
for(u32 i = 0; i < resources.materials.size(); ++i) for(u32 i = 0; i < resources.materials.size(); ++i)

View File

@ -88,6 +88,7 @@ public:
void SetLanguage(const std::string& language); void SetLanguage(const std::string& language);
Pane* FindPane(const std::string& name); Pane* FindPane(const std::string& name);
Pane* FindPanePartial(const std::string& name);
Material* FindMaterial(const std::string& name); Material* FindMaterial(const std::string& name);
Texture *FindTexture(const std::string &name); Texture *FindTexture(const std::string &name);

View File

@ -42,7 +42,7 @@ distribution.
#include "wstring.hpp" #include "wstring.hpp"
#include "OpeningBNR.hpp" #include "OpeningBNR.hpp"
BNRInstance * BNRInstance::instance = NULL; BNRInstance *BNRInstance::instance = NULL;
OpeningBNR::OpeningBNR() OpeningBNR::OpeningBNR()
: imetHdr(0), filesize(0) : imetHdr(0), filesize(0)
@ -52,7 +52,7 @@ OpeningBNR::OpeningBNR()
OpeningBNR::~OpeningBNR() OpeningBNR::~OpeningBNR()
{ {
if(imetHdr) if (imetHdr)
free(imetHdr); free(imetHdr);
} }
@ -60,19 +60,19 @@ bool OpeningBNR::LoadCachedBNR(const char *id)
{ {
char path[255]; char path[255];
snprintf(path, sizeof(path), "%s%.6s.bnr", Settings.BNRCachePath, id); snprintf(path, sizeof(path), "%s%.6s.bnr", Settings.BNRCachePath, id);
if((filesize = FileSize(path)) == 0) if ((filesize = FileSize(path)) == 0)
{ {
snprintf(path, sizeof(path), "%s%.3s.bnr", Settings.BNRCachePath, id); snprintf(path, sizeof(path), "%s%.3s.bnr", Settings.BNRCachePath, id);
if((filesize = FileSize(path)) == 0) if ((filesize = FileSize(path)) == 0)
return false; return false;
} }
FILE *f = fopen(path, "rb"); FILE *f = fopen(path, "rb");
if(!f) if (!f)
return false; return false;
imetHdr = (IMETHeader *) malloc(filesize); imetHdr = (IMETHeader *)malloc(filesize);
if(!imetHdr) if (!imetHdr)
{ {
fclose(f); fclose(f);
return false; return false;
@ -85,7 +85,7 @@ bool OpeningBNR::LoadCachedBNR(const char *id)
{ {
//! check if it's a channel .app file //! check if it's a channel .app file
IMETHeader *channelImet = (IMETHeader *)(((u8 *)imetHdr) + 0x40); IMETHeader *channelImet = (IMETHeader *)(((u8 *)imetHdr) + 0x40);
if(channelImet->fcc != 'IMET') if (channelImet->fcc != 'IMET')
{ {
free(imetHdr); free(imetHdr);
imetHdr = NULL; imetHdr = NULL;
@ -108,28 +108,28 @@ void OpeningBNR::WriteCachedBNR(const char *id, const u8 *buffer, u32 size)
CreateSubfolder(Settings.BNRCachePath); CreateSubfolder(Settings.BNRCachePath);
FILE *f = fopen(path, "wb"); FILE *f = fopen(path, "wb");
if(!f) if (!f)
return; return;
fwrite(buffer, 1, size, f); fwrite(buffer, 1, size, f);
fclose(f); fclose(f);
} }
bool OpeningBNR::Load(const discHdr * header) bool OpeningBNR::Load(const discHdr *header)
{ {
if(!header) if (!header)
return false; return false;
if(memcmp(gameID, header->id, 6) == 0) if (memcmp(gameID, header->id, 6) == 0)
return true; return true;
memcpy(gameID, header->id, 6); memcpy(gameID, header->id, 6);
if(imetHdr) if (imetHdr)
free(imetHdr); free(imetHdr);
imetHdr = NULL; imetHdr = NULL;
switch(header->type) switch (header->type)
{ {
case TYPE_GAME_WII_IMG: case TYPE_GAME_WII_IMG:
case TYPE_GAME_WII_DISC: case TYPE_GAME_WII_DISC:
@ -140,7 +140,7 @@ bool OpeningBNR::Load(const discHdr * header)
case TYPE_GAME_GC_IMG: case TYPE_GAME_GC_IMG:
case TYPE_GAME_GC_DISC: case TYPE_GAME_GC_DISC:
case TYPE_GAME_GC_EXTRACTED: case TYPE_GAME_GC_EXTRACTED:
if(!Settings.CacheBNRFiles) if (!Settings.CacheBNRFiles)
return false; return false;
return LoadCachedBNR((char *)header->id); return LoadCachedBNR((char *)header->id);
default: default:
@ -150,23 +150,21 @@ bool OpeningBNR::Load(const discHdr * header)
return false; return false;
} }
bool OpeningBNR::LoadWiiBanner(const discHdr * header) bool OpeningBNR::LoadWiiBanner(const discHdr *header)
{ {
if(!header || ( (header->type != TYPE_GAME_WII_IMG) if (!header || ((header->type != TYPE_GAME_WII_IMG) && (header->type != TYPE_GAME_WII_DISC)))
&& (header->type != TYPE_GAME_WII_DISC)))
return false; return false;
if (Settings.CacheBNRFiles && LoadCachedBNR((const char *)header->id))
if(Settings.CacheBNRFiles && LoadCachedBNR((const char *)header->id))
return true; return true;
if(header->type == TYPE_GAME_WII_DISC) if (header->type == TYPE_GAME_WII_DISC)
{ {
wiidisc_t *wdisc = wd_open_disc(__ReadDVD, 0); wiidisc_t *wdisc = wd_open_disc(__ReadDVD, 0);
if (!wdisc) if (!wdisc)
return false; return false;
imetHdr = (IMETHeader*) wd_extract_file(wdisc, ALL_PARTITIONS, (char *) "opening.bnr"); imetHdr = (IMETHeader *)wd_extract_file(wdisc, ALL_PARTITIONS, (char *)"opening.bnr");
filesize = wdisc->extracted_size; filesize = wdisc->extracted_size;
@ -174,18 +172,18 @@ bool OpeningBNR::LoadWiiBanner(const discHdr * header)
} }
else else
{ {
wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) gameID); wbfs_disc_t *disc = WBFS_OpenDisc((u8 *)gameID);
if (!disc) if (!disc)
return false; return false;
wiidisc_t *wdisc = wd_open_disc((s32(*)(void *, u32, u32, void *)) wbfs_disc_read, disc); wiidisc_t *wdisc = wd_open_disc((s32(*)(void *, u32, u32, void *))wbfs_disc_read, disc);
if (!wdisc) if (!wdisc)
{ {
WBFS_CloseDisc(disc); WBFS_CloseDisc(disc);
return false; return false;
} }
imetHdr = (IMETHeader*) wd_extract_file(wdisc, ALL_PARTITIONS, (char *) "opening.bnr"); imetHdr = (IMETHeader *)wd_extract_file(wdisc, ALL_PARTITIONS, (char *)"opening.bnr");
filesize = wdisc->extracted_size; filesize = wdisc->extracted_size;
@ -193,7 +191,7 @@ bool OpeningBNR::LoadWiiBanner(const discHdr * header)
WBFS_CloseDisc(disc); WBFS_CloseDisc(disc);
} }
if(!imetHdr) if (!imetHdr)
return false; return false;
if (imetHdr->fcc != 'IMET') if (imetHdr->fcc != 'IMET')
@ -203,26 +201,25 @@ bool OpeningBNR::LoadWiiBanner(const discHdr * header)
return false; return false;
} }
if(Settings.CacheBNRFiles) if (Settings.CacheBNRFiles)
WriteCachedBNR((const char *) header->id, (u8 *) imetHdr, filesize); WriteCachedBNR((const char *)header->id, (u8 *)imetHdr, filesize);
return true; return true;
} }
bool OpeningBNR::LoadChannelBanner(const discHdr *header) bool OpeningBNR::LoadChannelBanner(const discHdr *header)
{ {
if(!header || (header->tid == 0) || ( (header->type != TYPE_GAME_NANDCHAN) if (!header || (header->tid == 0) || ((header->type != TYPE_GAME_NANDCHAN) && (header->type != TYPE_GAME_EMUNANDCHAN)))
&& (header->type != TYPE_GAME_EMUNANDCHAN)))
return false; return false;
if(Settings.CacheBNRFiles && LoadCachedBNR((char *) header->id)) if (Settings.CacheBNRFiles && LoadCachedBNR((char *)header->id))
return true; return true;
const u64 &tid = header->tid; const u64 &tid = header->tid;
const char *pathPrefix = (header->type == TYPE_GAME_EMUNANDCHAN) ? Settings.NandEmuChanPath : ""; const char *pathPrefix = (header->type == TYPE_GAME_EMUNANDCHAN) ? Settings.NandEmuChanPath : "";
imetHdr = (IMETHeader*) Channels::GetOpeningBnr(tid, &filesize, pathPrefix); imetHdr = (IMETHeader *)Channels::GetOpeningBnr(tid, &filesize, pathPrefix);
if(!imetHdr) if (!imetHdr)
return false; return false;
if (imetHdr->fcc != 'IMET') if (imetHdr->fcc != 'IMET')
@ -232,29 +229,29 @@ bool OpeningBNR::LoadChannelBanner(const discHdr *header)
return false; return false;
} }
if(Settings.CacheBNRFiles) if (Settings.CacheBNRFiles)
WriteCachedBNR((char *) header->id, (u8 *) imetHdr, filesize); WriteCachedBNR((char *)header->id, (u8 *)imetHdr, filesize);
return true; return true;
} }
const u16 * OpeningBNR::GetIMETTitle(int lang) const u16 *OpeningBNR::GetIMETTitle(int lang)
{ {
if(!imetHdr || lang < 0 || lang >= 10) if (!imetHdr || lang < 0 || lang >= 10)
return NULL; return NULL;
if (imetHdr->fcc != 'IMET') if (imetHdr->fcc != 'IMET')
return NULL; return NULL;
if(imetHdr->names[lang][0] == 0) if (imetHdr->names[lang][0] == 0)
lang = CONF_LANG_ENGLISH; lang = CONF_LANG_ENGLISH;
return imetHdr->names[lang]; // possible unaligned pointer value return imetHdr->names[lang]; // possible unaligned pointer value
} }
static s32 GC_Disc_Read(void *fp, u32 offset, u32 count, void*iobuf) static s32 GC_Disc_Read(void *fp, u32 offset, u32 count, void *iobuf)
{ {
if(fp) if (fp)
{ {
fseek((FILE *)fp, offset, SEEK_SET); fseek((FILE *)fp, offset, SEEK_SET);
return fread(iobuf, 1, count, (FILE *)fp); return fread(iobuf, 1, count, (FILE *)fp);
@ -263,72 +260,74 @@ static s32 GC_Disc_Read(void *fp, u32 offset, u32 count, void*iobuf)
return __ReadDVDPlain(iobuf, count, offset); return __ReadDVDPlain(iobuf, count, offset);
} }
u8 *OpeningBNR::LoadGCBNR(const discHdr * header, u32 *len) u8 *OpeningBNR::LoadGCBNR(const discHdr *header, u32 *len)
{ {
if(!header || ( (header->type != TYPE_GAME_GC_IMG) if (!header || ((header->type != TYPE_GAME_GC_IMG) && (header->type != TYPE_GAME_GC_DISC) && (header->type != TYPE_GAME_GC_EXTRACTED)))
&& (header->type != TYPE_GAME_GC_DISC)
&& (header->type != TYPE_GAME_GC_EXTRACTED)))
return NULL; return NULL;
const char *path = GCGames::Instance()->GetPath((char *) header->id); const char *path = GCGames::Instance()->GetPath((char *)header->id);
if(!path) if (!path)
return NULL; return NULL;
FILE *file = NULL; FILE *file = NULL;
GC_OpeningBnr *openingBnr = NULL; GC_OpeningBnr *openingBnr = NULL;
// read from file // read from file
if((header->type == TYPE_GAME_GC_IMG) || (header->type == TYPE_GAME_GC_DISC)) if ((header->type == TYPE_GAME_GC_IMG) || (header->type == TYPE_GAME_GC_DISC))
{ {
//! open iso file if it's iso //! open iso file if it's iso
if(header->type == TYPE_GAME_GC_IMG) if (header->type == TYPE_GAME_GC_IMG)
{ {
file = fopen(path, "rb"); file = fopen(path, "rb");
if(!file) if (!file)
return NULL; return NULL;
} }
gcdisc_t *disc = gc_open_disc(GC_Disc_Read, file); gcdisc_t *disc = gc_open_disc(GC_Disc_Read, file);
if(!disc) { if (!disc)
{
fclose(file); fclose(file);
return NULL; return NULL;
} }
if(!strcmp(Settings.db_language, "JA")) { if (!strcmp(Settings.db_language, "JA"))
{
bool loaded = gc_extract_file(disc, "openingJA.bnr"); bool loaded = gc_extract_file(disc, "openingJA.bnr");
if(!loaded) if (!loaded)
loaded = gc_extract_file(disc, "opening.bnr"); loaded = gc_extract_file(disc, "opening.bnr");
if(!loaded) if (!loaded)
loaded = gc_extract_file(disc, "openingUS.bnr"); loaded = gc_extract_file(disc, "openingUS.bnr");
if(!loaded) if (!loaded)
loaded = gc_extract_file(disc, "openingEU.bnr"); loaded = gc_extract_file(disc, "openingEU.bnr");
} }
else if(!strcmp(Settings.db_language, "EN")) { else if (!strcmp(Settings.db_language, "EN"))
{
bool loaded = gc_extract_file(disc, "openingUS.bnr"); bool loaded = gc_extract_file(disc, "openingUS.bnr");
if(!loaded) if (!loaded)
loaded = gc_extract_file(disc, "opening.bnr"); loaded = gc_extract_file(disc, "opening.bnr");
if(!loaded) if (!loaded)
loaded = gc_extract_file(disc, "openingEU.bnr"); loaded = gc_extract_file(disc, "openingEU.bnr");
if(!loaded) if (!loaded)
loaded = gc_extract_file(disc, "openingJA.bnr"); loaded = gc_extract_file(disc, "openingJA.bnr");
} }
else { else
{
bool loaded = gc_extract_file(disc, "openingEU.bnr"); bool loaded = gc_extract_file(disc, "openingEU.bnr");
if(!loaded) if (!loaded)
loaded = gc_extract_file(disc, "opening.bnr"); loaded = gc_extract_file(disc, "opening.bnr");
if(!loaded) if (!loaded)
loaded = gc_extract_file(disc, "openingUS.bnr"); loaded = gc_extract_file(disc, "openingUS.bnr");
if(!loaded) if (!loaded)
loaded = gc_extract_file(disc, "openingJA.bnr"); loaded = gc_extract_file(disc, "openingJA.bnr");
} }
openingBnr = (GC_OpeningBnr *) disc->extracted_buffer; openingBnr = (GC_OpeningBnr *)disc->extracted_buffer;
if(len) if (len)
*len = disc->extracted_size; *len = disc->extracted_size;
gc_close_disc(disc); gc_close_disc(disc);
} }
else if(header->type == TYPE_GAME_GC_EXTRACTED) else if (header->type == TYPE_GAME_GC_EXTRACTED)
{ {
std::string gamePath = path; std::string gamePath = path;
gamePath += "root/"; gamePath += "root/";
@ -336,69 +335,73 @@ u8 *OpeningBNR::LoadGCBNR(const discHdr * header, u32 *len)
file = fopen((gamePath + "opening.bnr").c_str(), "rb"); file = fopen((gamePath + "opening.bnr").c_str(), "rb");
// if not found try the region specific ones // if not found try the region specific ones
if(!strcmp(Settings.db_language, "JA")) { if (!strcmp(Settings.db_language, "JA"))
if(!file) {
if (!file)
file = fopen((gamePath + "openingJA.bnr").c_str(), "rb"); file = fopen((gamePath + "openingJA.bnr").c_str(), "rb");
if(!file) if (!file)
file = fopen((gamePath + "openingUS.bnr").c_str(), "rb"); file = fopen((gamePath + "openingUS.bnr").c_str(), "rb");
if(!file) if (!file)
file = fopen((gamePath + "openingEU.bnr").c_str(), "rb"); file = fopen((gamePath + "openingEU.bnr").c_str(), "rb");
} }
else if(!strcmp(Settings.db_language, "EN")) { else if (!strcmp(Settings.db_language, "EN"))
if(!file) {
if (!file)
file = fopen((gamePath + "openingUS.bnr").c_str(), "rb"); file = fopen((gamePath + "openingUS.bnr").c_str(), "rb");
if(!file) if (!file)
file = fopen((gamePath + "openingEU.bnr").c_str(), "rb"); file = fopen((gamePath + "openingEU.bnr").c_str(), "rb");
if(!file) if (!file)
file = fopen((gamePath + "openingJA.bnr").c_str(), "rb"); file = fopen((gamePath + "openingJA.bnr").c_str(), "rb");
} }
else { else
if(!file) {
if (!file)
file = fopen((gamePath + "openingEU.bnr").c_str(), "rb"); file = fopen((gamePath + "openingEU.bnr").c_str(), "rb");
if(!file) if (!file)
file = fopen((gamePath + "openingUS.bnr").c_str(), "rb"); file = fopen((gamePath + "openingUS.bnr").c_str(), "rb");
if(!file) if (!file)
file = fopen((gamePath + "openingJA.bnr").c_str(), "rb"); file = fopen((gamePath + "openingJA.bnr").c_str(), "rb");
} }
// file not found // file not found
if(!file) if (!file)
return NULL; return NULL;
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
int size = ftell(file); int size = ftell(file);
rewind(file); rewind(file);
openingBnr = (GC_OpeningBnr *) malloc(size); openingBnr = (GC_OpeningBnr *)malloc(size);
if(openingBnr) if (openingBnr)
{ {
if(len) if (len)
*len = size; *len = size;
fread(openingBnr, 1, size, file); fread(openingBnr, 1, size, file);
} }
} }
if(file) if (file)
fclose(file); fclose(file);
if(!openingBnr) if (!openingBnr)
return NULL; return NULL;
// check magic of the opening bnr // check magic of the opening bnr
if(openingBnr->magic != 'BNR1' && openingBnr->magic != 'BNR2') { if (openingBnr->magic != 'BNR1' && openingBnr->magic != 'BNR2')
{
free(openingBnr); free(openingBnr);
return NULL; return NULL;
} }
return (u8 *) openingBnr; return (u8 *)openingBnr;
} }
CustomBanner *OpeningBNR::CreateGCBanner(const discHdr * header) CustomBanner *OpeningBNR::CreateGCBanner(const discHdr *header)
{ {
int language = 0; int language = 0;
u32 openingBnrSize; u32 openingBnrSize;
GC_OpeningBnr *openingBnr = (GC_OpeningBnr *) LoadGCBNR(header, &openingBnrSize); wString developer;
GC_OpeningBnr *openingBnr = (GC_OpeningBnr *)LoadGCBNR(header, &openingBnrSize);
CustomBanner *banner = new CustomBanner; CustomBanner *banner = new CustomBanner;
banner->LoadBanner(Resources::GetFile("custom_banner.bnr"), Resources::GetFileSize("custom_banner.bnr")); banner->LoadBanner(Resources::GetFile("custom_banner.bnr"), Resources::GetFileSize("custom_banner.bnr"));
@ -406,56 +409,52 @@ CustomBanner *OpeningBNR::CreateGCBanner(const discHdr * header)
banner->SetBannerText("T_PF", tr("GameCube")); banner->SetBannerText("T_PF", tr("GameCube"));
if(openingBnr) if (openingBnr)
{ {
banner->SetBannerTexture("HBPic.tpl", openingBnr->tpl_data, 96, 32, GX_TF_RGB5A3); banner->SetBannerTexture("HBPic.tpl", openingBnr->tpl_data, 96, 32, GX_TF_RGB5A3);
// European opening bnr file // European opening bnr file
if(openingBnr->magic == 'BNR2') if (openingBnr->magic == 'BNR2')
{ {
if(!strcmp(Settings.db_language, "DE")) { if (!strcmp(Settings.db_language, "DE"))
language = 1; language = 1;
} else if (!strcmp(Settings.db_language, "FR"))
else if(!strcmp(Settings.db_language, "FR")) {
language = 2; language = 2;
} else if (!strcmp(Settings.db_language, "ES"))
else if(!strcmp(Settings.db_language, "ES")) {
language = 3; language = 3;
} else if (!strcmp(Settings.db_language, "IT"))
else if(!strcmp(Settings.db_language, "IT")) {
language = 4; language = 4;
} else if (!strcmp(Settings.db_language, "NL"))
else if(!strcmp(Settings.db_language, "NL")) {
language = 5; language = 5;
}
if((0x1820 + sizeof(openingBnr->description[0]) * language) > openingBnrSize) { if ((0x1820 + sizeof(openingBnr->description[0]) * language) > openingBnrSize)
{
language = 0; language = 0;
} }
} }
// sets the developer // sets the developer
wString str; developer.resize(strlen((char *)openingBnr->description[language].developer));
str.resize(strlen((char *) openingBnr->description[language].developer)); for (u32 i = 0; i < developer.size(); i++)
for(u32 i = 0; i < str.size(); i++) developer[i] = *(openingBnr->description[language].developer + i);
str[i] = *(openingBnr->description[language].developer + i);
banner->SetBannerText("T_Coded_by", tr("Developer:")); banner->SetBannerText("T_Coded_by", tr("Developer:"));
banner->SetBannerText("T_coder", str.toUTF8().c_str()); banner->SetBannerText("T_coder", developer.toUTF8().c_str());
// sets the description and converts encodings (Japan and Taiwan) // sets the description and converts encodings (Japan and Taiwan)
if(header->id[3] == 'J' || header->id[3] == 'W') if (header->id[3] == 'J' || header->id[3] == 'W')
{ {
std::string description((char *) openingBnr->description[language].long_description); std::string description((char *)openingBnr->description[language].long_description);
banner->SetBannerText("T_short_descript", sj2utf8(description).c_str()); banner->SetBannerText("T_short_descript", sj2utf8(description).c_str());
} }
else else
{ {
str.resize(strlen((char *) openingBnr->description[language].long_description)); wString description;
for(u32 i = 0; i < str.size(); i++) description.resize(strlen((char *)openingBnr->description[language].long_description));
str[i] = *(openingBnr->description[language].long_description + i); for (u32 i = 0; i < description.size(); i++)
description[i] = *(openingBnr->description[language].long_description + i);
banner->SetBannerText("T_short_descript", str.toUTF8().c_str()); banner->SetBannerText("T_short_descript", description.toUTF8().c_str());
} }
// free buffer // free buffer
@ -469,7 +468,13 @@ CustomBanner *OpeningBNR::CreateGCBanner(const discHdr * header)
banner->SetBannerText("T_short_descript", " "); banner->SetBannerText("T_short_descript", " ");
} }
banner->SetBannerText("T_name", GameTitles.GetTitle(header)); if (strcmp(Settings.db_language, "KO") == 0)
{
banner->SetBannerText("T_Coded_by", developer.toUTF8().c_str());
banner->SetBannerPaneVisible("T_coder", false);
}
else
banner->SetBannerText("T_name", GameTitles.GetTitle(header));
banner->SetBannerPaneVisible("Line1", false); banner->SetBannerPaneVisible("Line1", false);
banner->SetBannerPaneVisible("Line2", false); banner->SetBannerPaneVisible("Line2", false);
banner->SetBannerPaneVisible("T_Released", false); banner->SetBannerPaneVisible("T_Released", false);
@ -481,14 +486,14 @@ CustomBanner *OpeningBNR::CreateGCBanner(const discHdr * header)
return banner; return banner;
} }
CustomBanner *OpeningBNR::CreateGCIcon(const discHdr * header) CustomBanner *OpeningBNR::CreateGCIcon(const discHdr *header)
{ {
GC_OpeningBnr *openingBnr = (GC_OpeningBnr *) LoadGCBNR(header); GC_OpeningBnr *openingBnr = (GC_OpeningBnr *)LoadGCBNR(header);
CustomBanner *newBanner = new CustomBanner; CustomBanner *newBanner = new CustomBanner;
newBanner->LoadIcon(Resources::GetFile("custom_banner.bnr"), Resources::GetFileSize("custom_banner.bnr")); newBanner->LoadIcon(Resources::GetFile("custom_banner.bnr"), Resources::GetFileSize("custom_banner.bnr"));
if(openingBnr) if (openingBnr)
newBanner->SetIconTexture("Iconpng.tpl", openingBnr->tpl_data, 96, 32, GX_TF_RGB5A3); newBanner->SetIconTexture("Iconpng.tpl", openingBnr->tpl_data, 96, 32, GX_TF_RGB5A3);
else else
newBanner->SetIconPngImage("Iconpng.tpl", Resources::GetFile("gc_icon_bg.png"), Resources::GetFileSize("gc_icon_bg.png")); newBanner->SetIconPngImage("Iconpng.tpl", Resources::GetFile("gc_icon_bg.png"), Resources::GetFileSize("gc_icon_bg.png"));
@ -496,7 +501,7 @@ CustomBanner *OpeningBNR::CreateGCIcon(const discHdr * header)
newBanner->SetIconPngImage("HBLogo.tpl", Resources::GetFile("gc_icon_bg.png"), Resources::GetFileSize("gc_icon_bg.png")); newBanner->SetIconPngImage("HBLogo.tpl", Resources::GetFile("gc_icon_bg.png"), Resources::GetFileSize("gc_icon_bg.png"));
// free buffer // free buffer
if(openingBnr) if (openingBnr)
free(openingBnr); free(openingBnr);
return newBanner; return newBanner;

View File

@ -29,17 +29,17 @@ distribution.
typedef struct _GC_OpeningBnr typedef struct _GC_OpeningBnr
{ {
u32 magic; // BNR1 or BNR2 u32 magic; // BNR1 or BNR2
u8 pad[0x1C]; u8 pad[0x1C];
u8 tpl_data[0x1800]; // 96x32 pixel format GX_TF_RGB5A3 u8 tpl_data[0x1800]; // 96x32 pixel format GX_TF_RGB5A3
struct struct
{ {
u8 disc_title[0x20]; // Gamename u8 disc_title[0x20]; // Gamename
u8 developer_short[0x20]; // Company/Developer u8 developer_short[0x20]; // Company/Developer
u8 full_title[0x40]; // Full Game Title u8 full_title[0x40]; // Full Game Title
u8 developer[0x40]; // Company/Developer Full name, or description u8 developer[0x40]; // Company/Developer Full name, or description
u8 long_description[0x80]; // Game Description u8 long_description[0x80]; // Game Description
} description[6]; // 6 only on BNR2 => English, German, French, Spanish, Italian, Dutch ?? } description[6]; // 6 only on BNR2 => English, German, French, Spanish, Italian, Dutch ??
} GC_OpeningBnr; } GC_OpeningBnr;
typedef struct _IMETHeader typedef struct _IMETHeader
@ -51,8 +51,8 @@ typedef struct _IMETHeader
u32 bannerSize; u32 bannerSize;
u32 soundSize; u32 soundSize;
u32 flag1; u32 flag1;
u16 names[10][42]; // 10 languages (thanks dkosmari for the info) u16 names[10][42]; // 10 languages (thanks dkosmari for the info)
u16 zeroes_2[7*42]; // padding for 7 more languages (thanks dkosmari for the info) u16 zeroes_2[7 * 42]; // padding for 7 more languages (thanks dkosmari for the info)
u8 crypto[16]; u8 crypto[16];
} __attribute__((packed)) IMETHeader; } __attribute__((packed)) IMETHeader;
@ -77,8 +77,8 @@ typedef struct _U8Entry
{ {
struct struct
{ {
u32 fileType :8; u32 fileType : 8;
u32 nameOffset :24; u32 nameOffset : 24;
}; };
u32 fileOffset; u32 fileOffset;
union union
@ -86,49 +86,63 @@ typedef struct _U8Entry
u32 fileLength; u32 fileLength;
u32 numEntries; u32 numEntries;
}; };
} __attribute__( ( packed ) ) U8Entry; } __attribute__((packed)) U8Entry;
static inline const char *u8Filename(const U8Entry *fst, int i)
static inline const char * u8Filename(const U8Entry *fst, int i)
{ {
return (char *) (fst + fst[0].numEntries) + fst[i].nameOffset; return (char *)(fst + fst[0].numEntries) + fst[i].nameOffset;
} }
class OpeningBNR class OpeningBNR
{ {
public: public:
OpeningBNR(); OpeningBNR();
~OpeningBNR(); ~OpeningBNR();
bool Load(const discHdr * header); bool Load(const discHdr *header);
bool LoadWiiBanner(const discHdr * header); bool LoadWiiBanner(const discHdr *header);
bool LoadChannelBanner(const discHdr *header); bool LoadChannelBanner(const discHdr *header);
CustomBanner *CreateGCBanner(const discHdr * header); CustomBanner *CreateGCBanner(const discHdr *header);
CustomBanner *CreateGCIcon(const discHdr * header); CustomBanner *CreateGCIcon(const discHdr *header);
const u8 * Get() const { return (const u8*) imetHdr; } const u8 *Get() const { return (const u8 *)imetHdr; }
u32 GetSize() const { return filesize; } u32 GetSize() const { return filesize; }
bool LoadCachedBNR(const char *id); bool LoadCachedBNR(const char *id);
void WriteCachedBNR(const char *id, const u8 *buffer, u32 size); void WriteCachedBNR(const char *id, const u8 *buffer, u32 size);
const u16 * GetIMETTitle(int lang); const u16 *GetIMETTitle(int lang);
const u16 * GetIMETTitle(const discHdr * header, int lang) { Load(header); return GetIMETTitle(lang); } const u16 *GetIMETTitle(const discHdr *header, int lang)
private: {
u8 *LoadGCBNR(const discHdr * header, u32 *len = 0); Load(header);
IMETHeader *imetHdr; return GetIMETTitle(lang);
u32 filesize; }
char gameID[7];
private:
u8 *LoadGCBNR(const discHdr *header, u32 *len = 0);
IMETHeader *imetHdr;
u32 filesize;
char gameID[7];
}; };
class BNRInstance : public OpeningBNR class BNRInstance : public OpeningBNR
{ {
public: public:
static BNRInstance * Instance() { if(!instance) instance = new BNRInstance; return instance; } static BNRInstance *Instance()
static void DestroyInstance() { delete instance; instance = NULL; } {
private: if (!instance)
BNRInstance() { } instance = new BNRInstance;
~BNRInstance() { } return instance;
static BNRInstance * instance; }
static void DestroyInstance()
{
delete instance;
instance = NULL;
}
private:
BNRInstance() {}
~BNRInstance() {}
static BNRInstance *instance;
}; };
#endif #endif

View File

@ -130,6 +130,25 @@ Pane* Pane::FindPane(const std::string& find_name)
return NULL; return NULL;
} }
Pane* Pane::FindPanePartial(const std::string& find_name, int len)
{
if(!header)
return NULL;
std::string str(getName());
if (str.compare(0, len, find_name) == 0)
return this;
for(u32 i = 0; i < panes.size(); ++i)
{
Pane *found = panes[i]->FindPanePartial(find_name, len);
if (found)
return found;
}
return NULL;
}
void Pane::ProcessHermiteKey(const KeyType& type, float value) void Pane::ProcessHermiteKey(const KeyType& type, float value)
{ {
if (type.type == ANIMATION_TYPE_VERTEX_COLOR) // vertex color if (type.type == ANIMATION_TYPE_VERTEX_COLOR) // vertex color

View File

@ -108,7 +108,8 @@ public:
bool GetWidescren() const { return ((header->flags & (1 << FLAG_WIDESCREEN)) != 0); } bool GetWidescren() const { return ((header->flags & (1 << FLAG_WIDESCREEN)) != 0); }
Pane* FindPane(const std::string& name); // recursive Pane* FindPane(const std::string& name); // recursive
Pane* FindPanePartial(const std::string& name, int len); // recursive
PaneList panes; PaneList panes;

View File

@ -22,6 +22,7 @@
#include "banner/OpeningBNR.hpp" #include "banner/OpeningBNR.hpp"
#include "settings/CSettings.h" #include "settings/CSettings.h"
#include "settings/CGameStatistics.h" #include "settings/CGameStatistics.h"
#include "settings/GameTitles.h"
#include "settings/menus/GameSettingsMenu.hpp" #include "settings/menus/GameSettingsMenu.hpp"
#include "SystemMenu/SystemMenuResources.h" #include "SystemMenu/SystemMenuResources.h"
#include "prompts/GameWindow.hpp" #include "prompts/GameWindow.hpp"
@ -116,6 +117,12 @@ BannerWindow::BannerWindow(GameBrowseMenu *m, struct discHdr *header)
settingsBtn->SetSoundClick(btnSoundClick2); settingsBtn->SetSoundClick(btnSoundClick2);
settingsBtn->SetPosition(-120, 175); settingsBtn->SetPosition(-120, 175);
settingsBtn->SetTrigger(trigA); settingsBtn->SetTrigger(trigA);
if (strcmp(Settings.db_language, "KO") == 0)
{
settingsBtnTxt = new GuiText(tr("Settings"), 35, thColor("r=0 g=0 b=0 a=255 - game window size text color"));
settingsBtn->SetPosition(Settings.widescreen ? -113 : -131, 161);
settingsBtn->SetLabel(settingsBtnTxt);
}
startBtn = new GuiButton(215, 75); startBtn = new GuiButton(215, 75);
startBtn->SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE); startBtn->SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
@ -123,6 +130,12 @@ BannerWindow::BannerWindow(GameBrowseMenu *m, struct discHdr *header)
startBtn->SetSoundClick(btnSoundClick2); startBtn->SetSoundClick(btnSoundClick2);
startBtn->SetPosition(110, 175); startBtn->SetPosition(110, 175);
startBtn->SetTrigger(trigA); startBtn->SetTrigger(trigA);
if (strcmp(Settings.db_language, "KO") == 0)
{
startBtnTxt = new GuiText(tr("Start"), 35, thColor("r=0 g=0 b=0 a=255 - game window size text color"));
startBtn->SetPosition(Settings.widescreen ? 114 : 132, 161);
startBtn->SetLabel(startBtnTxt);
}
backBtn = new GuiButton(215, 75); backBtn = new GuiButton(215, 75);
backBtn->SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE); backBtn->SetAlignment(ALIGN_CENTER, ALIGN_MIDDLE);
@ -131,6 +144,11 @@ BannerWindow::BannerWindow(GameBrowseMenu *m, struct discHdr *header)
backBtn->SetPosition(-screenwidth, -screenheight); // set out of screen backBtn->SetPosition(-screenwidth, -screenheight); // set out of screen
backBtn->SetTrigger(0, trigA); backBtn->SetTrigger(0, trigA);
backBtn->SetTrigger(1, trigB); backBtn->SetTrigger(1, trigB);
if (strcmp(Settings.db_language, "KO") == 0)
{
backBtnTxt = new GuiText(tr("Back"), 35, thColor("r=0 g=0 b=0 a=255 - game window size text color"));
backBtn->SetLabel(backBtnTxt);
}
// Set favorite button position // Set favorite button position
int xPos = -198-(3*27)-14; int xPos = -198-(3*27)-14;
@ -254,12 +272,19 @@ BannerWindow::BannerWindow(GameBrowseMenu *m, struct discHdr *header)
Append(btnRight); Append(btnRight);
} }
bannerFrame.SetButtonBText(tr("Start")); if (strcmp(Settings.db_language, "KO") == 0)
{
bannerFrame.SetButtonAText(" ");
bannerFrame.SetButtonBText(" ");
}
else
bannerFrame.SetButtonBText(tr("Start"));
//check if unlocked //check if unlocked
if (Settings.godmode || !(Settings.ParentalBlocks & BLOCK_GAME_SETTINGS)) if (Settings.godmode || !(Settings.ParentalBlocks & BLOCK_GAME_SETTINGS))
{ {
bannerFrame.SetButtonAText(tr("Settings")); if (strcmp(Settings.db_language, "KO") != 0)
bannerFrame.SetButtonAText(tr("Settings"));
Append(settingsBtn); Append(settingsBtn);
if(Settings.bannerFavIcon != BANNER_FAVICON_OFF) if(Settings.bannerFavIcon != BANNER_FAVICON_OFF)
for(int i = 0; i < FAVORITE_STARS; ++i) for(int i = 0; i < FAVORITE_STARS; ++i)
@ -267,12 +292,26 @@ BannerWindow::BannerWindow(GameBrowseMenu *m, struct discHdr *header)
} }
else else
{ {
bannerFrame.SetButtonAText(tr("Back")); if (strcmp(Settings.db_language, "KO") == 0)
backBtn->SetPosition(-120, 175); {
backBtn->SetPosition(Settings.widescreen ? -113 : -131, 161);
}
else
{
bannerFrame.SetButtonAText(tr("Back"));
backBtn->SetPosition(-120, 175);
}
} }
Append(startBtn); //! Appending the disc on top of all Append(startBtn); //! Appending the disc on top of all
if (strcmp(Settings.db_language, "KO") == 0)
{
titleName = new GuiText((char *) NULL, 29, (GXColor) {255, 255, 255, 255});
titleName->SetFontSize(29);
titleName->SetScale(0.8f);
}
ChangeGame(false); ChangeGame(false);
} }
@ -300,6 +339,14 @@ BannerWindow::~BannerWindow()
delete playcntTxt; delete playcntTxt;
if (strcmp(Settings.db_language, "KO") == 0)
{
delete startBtnTxt;
delete backBtnTxt;
delete settingsBtnTxt;
delete titleName;
}
delete startBtn; delete startBtn;
delete backBtn; delete backBtn;
delete settingsBtn; delete settingsBtn;
@ -331,6 +378,11 @@ void BannerWindow::ChangeGame(bool playsound)
BannerAsync::HaltThread(); BannerAsync::HaltThread();
Banner *newBanner = NULL; Banner *newBanner = NULL;
if (strcmp(Settings.db_language, "KO") == 0)
{
Remove(titleName);
titleName->SetText(GameTitles.GetTitle(header));
}
// continue playing sound during loading process // continue playing sound during loading process
if((header->type == TYPE_GAME_GC_IMG) || (header->type == TYPE_GAME_GC_DISC) || (header->type == TYPE_GAME_GC_EXTRACTED)) if((header->type == TYPE_GAME_GC_IMG) || (header->type == TYPE_GAME_GC_DISC) || (header->type == TYPE_GAME_GC_EXTRACTED))
{ {
@ -338,9 +390,18 @@ void BannerWindow::ChangeGame(bool playsound)
if(BNRInstance::Instance()->Load(header) && BNRInstance::Instance()->Get() != NULL) if(BNRInstance::Instance()->Load(header) && BNRInstance::Instance()->Get() != NULL)
newBanner = new Banner; newBanner = new Banner;
else else
{
newBanner = BNRInstance::Instance()->CreateGCBanner(header); newBanner = BNRInstance::Instance()->CreateGCBanner(header);
if (strcmp(Settings.db_language, "KO") == 0)
{
titleName->SetAlignment(ALIGN_CENTER, ALIGN_BOTTOM);
titleName->SetPosition(0, -170);
Append(titleName);
}
}
} }
else { else
{
BNRInstance::Instance()->Load(header); BNRInstance::Instance()->Load(header);
newBanner = new Banner; newBanner = new Banner;
} }
@ -393,6 +454,24 @@ void BannerWindow::ChangeGame(bool playsound)
for(int i = 0; i < FAVORITE_STARS; ++i) for(int i = 0; i < FAVORITE_STARS; ++i)
FavoriteBtnImg[i]->SetImage(favoritevar >= i+1 ? imgFavorite : imgNotFavorite); FavoriteBtnImg[i]->SetImage(favoritevar >= i+1 ? imgFavorite : imgNotFavorite);
if (strcmp(Settings.db_language, "KO") == 0)
{
Pane *yearPane = gameBanner->getBanner()->FindPanePartial("YearLine");
if (yearPane)
yearPane->SetVisible(false);
Pane *playersPane = gameBanner->getBanner()->FindPanePartial("PlayLine");
if (playersPane)
playersPane->SetVisible(false);
Pane *titlePane = gameBanner->getBanner()->FindPanePartial("T_VCTitle");
if (titlePane)
{
titlePane->SetVisible(false);
titleName->SetAlignment(ALIGN_CENTER, ALIGN_BOTTOM);
titleName->SetPosition(0, -170);
Append(titleName);
}
}
//! Resume all threads //! Resume all threads
BannerAsync::ResumeThread(); BannerAsync::ResumeThread();
ResumeGui(); ResumeGui();

View File

@ -90,6 +90,11 @@ class BannerWindow : public GuiWindow
GuiText * playcntTxt; GuiText * playcntTxt;
GuiText * startBtnTxt;
GuiText * backBtnTxt;
GuiText * settingsBtnTxt;
GuiText * titleName;
GuiButton * startBtn; GuiButton * startBtn;
GuiButton * backBtn; GuiButton * backBtn;
GuiButton * settingsBtn; GuiButton * settingsBtn;