From 201813f6f966483f50c9b613ddda8f8c4510424e Mon Sep 17 00:00:00 2001 From: wiidev Date: Sun, 1 Jan 2023 17:00:12 +0000 Subject: [PATCH] Improve region info accuracy --- source/menu/GameBrowseMenu.cpp | 96 +++++++++++++++++++++++----------- source/menu/GameBrowseMenu.hpp | 2 +- source/settings/GameTitles.cpp | 34 ++++++++++-- source/settings/GameTitles.h | 7 ++- 4 files changed, 101 insertions(+), 38 deletions(-) diff --git a/source/menu/GameBrowseMenu.cpp b/source/menu/GameBrowseMenu.cpp index 8868c47d..c522471c 100644 --- a/source/menu/GameBrowseMenu.cpp +++ b/source/menu/GameBrowseMenu.cpp @@ -33,6 +33,7 @@ #include "utils/ShowError.h" #include "utils/tools.h" #include "utils/PasswordCheck.h" +#include "xml/GameTDB.hpp" #include "gecko.h" #include "menus.h" #include "wpad.h" @@ -1354,7 +1355,7 @@ int GameBrowseMenu::MainLoop() { struct discHdr *header = gameList[gameSelected]; LoadCover(header); - UpdateGameInfoText(header->id); + UpdateGameInfoText(header); } } @@ -1463,9 +1464,9 @@ void GameBrowseMenu::UpdateClock() } } -void GameBrowseMenu::UpdateGameInfoText(const u8 * gameId) +void GameBrowseMenu::UpdateGameInfoText(struct discHdr *header) { - if(!gameId) + if (!header) { Remove(GameRegionTxt); delete GameRegionTxt; @@ -1476,35 +1477,70 @@ void GameBrowseMenu::UpdateGameInfoText(const u8 * gameId) return; } - char gameregion[10]; + std::string gameregion; char IDfull[7]; - snprintf(IDfull, sizeof(IDfull), (char *) gameId); + snprintf(IDfull, sizeof(IDfull), (char *) header->id); - switch (IDfull[3]) + const char *region = GameTitles.GetRegion(IDfull); + if (strcmp(region, "NULL") != 0) + gameregion = region; + else { - case 'A': - case 'B': - case 'U': - case 'X': - strcpy(gameregion, tr("Region Free")); - break; - case 'E': - case 'N': - strcpy(gameregion, "NTSC U"); - break; - case 'J': - strcpy(gameregion, "NTSC J"); - break; - case 'K': - case 'Q': - case 'T': - strcpy(gameregion, "NTSC K"); - break; - case 'W': - strcpy(gameregion, "NTSC T"); - break; - default: - strcpy(gameregion, " PAL "); + char sys[2]; + char reg[2]; + snprintf(sys, sizeof(sys), "%c", IDfull[0]); + snprintf(reg, sizeof(reg), "%c", IDfull[3]); + if (header->type >= TYPE_GAME_NANDCHAN) + { + // Force some homebrew to display as region free + char regions[] = "ABDEFHIJKLMNPQRSTUVW"; + char systems[] = "CEFHJLMNPQWX"; + if (!(strstr(systems, sys) && strstr(regions, reg))) + reg[0] = 'A'; + if (memcmp(IDfull, "JODI", 4) == 0) + reg[0] = 'A'; + if (memcmp(IDfull, "IDCL", 4) == 0) + reg[0] = 'A'; + } + + switch (reg[0]) + { + case 'P': // Europe + case 'D': // Germany + case 'F': // France + case 'H': // Netherlands + case 'I': // Italy + case 'L': // Japanese import to Europe + case 'M': // American import to Europe + case 'R': // Russia + case 'S': // Spain + case 'U': // Australia + case 'V': // Scandinavia + gameregion = "PAL"; + break; + case 'E': // USA + case 'N': // Japanese import to USA + gameregion = "NTSC-U"; + break; + case 'J': // Japan + gameregion = "NTSC-J"; + break; + case 'K': // Korea + case 'Q': // Japanese import to Korea + case 'T': // American import to Korea + gameregion = "NTSC-K"; + break; + case 'W': // Taiwan / Hong Kong / Macau + gameregion = "NTSC-T"; + break; + case 'X': // Europe / USA special releases + case 'Y': // Europe / USA special releases + case 'Z': // Europe / USA special releases + gameregion = "PAL / NTSC-U"; + break; + default: + gameregion = tr("Region Free"); + } } HaltGui(); @@ -1523,7 +1559,7 @@ void GameBrowseMenu::UpdateGameInfoText(const u8 * gameId) { Remove(GameRegionTxt); delete GameRegionTxt; - GameRegionTxt = new GuiText(gameregion, 22, thColor("r=55 g=190 b=237 a=255 - region info text color")); + GameRegionTxt = new GuiText(gameregion.c_str(), 22, thColor("r=55 g=190 b=237 a=255 - region info text color")); GameRegionTxt->SetAlignment(ALIGN_LEFT, ALIGN_TOP); GameRegionTxt->SetPosition(thInt("68 - region info text pos x"), thInt("30 - region info text pos y")); GameRegionTxt->SetEffect(EFFECT_FADE, 20); diff --git a/source/menu/GameBrowseMenu.hpp b/source/menu/GameBrowseMenu.hpp index 55c58c38..4809b295 100644 --- a/source/menu/GameBrowseMenu.hpp +++ b/source/menu/GameBrowseMenu.hpp @@ -17,7 +17,7 @@ class GameBrowseMenu : public GuiWindow int MainLoop(); int OpenClickedGame(struct discHdr *header); int GetSelectedGame() { return (gameBrowser ? gameBrowser->GetSelectedOption() : -1); } - void UpdateGameInfoText(const u8 * gameId); + void UpdateGameInfoText(struct discHdr *header); void LoadCover(struct discHdr *header); void CheckDiscSlotUpdate(); void UpdateFreeSpace(void *arg); diff --git a/source/settings/GameTitles.cpp b/source/settings/GameTitles.cpp index b03eeb30..47f35b90 100644 --- a/source/settings/GameTitles.cpp +++ b/source/settings/GameTitles.cpp @@ -7,11 +7,11 @@ #include "svnrev.h" #include "gecko.h" -#define VALID_CACHE_REVISION 1148 +#define VALID_CACHE_REVISION 1280 CGameTitles GameTitles; -void CGameTitles::SetGameTitle(const char * id, const char * title) +void CGameTitles::SetGameTitle(const char * id, const char * title, const std::string region) { if(!id || !title) return; @@ -21,6 +21,7 @@ void CGameTitles::SetGameTitle(const char * id, const char * title) if(strncasecmp(id, TitleList[i].GameID, 6) == 0) { TitleList[i].Title = title; + TitleList[i].Region = region; return; } } @@ -28,6 +29,7 @@ void CGameTitles::SetGameTitle(const char * id, const char * title) GameTitle newTitle; snprintf(newTitle.GameID, sizeof(newTitle.GameID), id); newTitle.Title = title; + newTitle.Region = region; newTitle.ParentalRating = -1; newTitle.PlayersCount = 1; newTitle.FromWiiTDB = 0; @@ -70,6 +72,20 @@ const char * CGameTitles::GetTitle(const struct discHdr *header) const return header->title; } +const char * CGameTitles::GetRegion(const char * id) const +{ + if(!id || !Settings.titlesOverride) + return "NULL"; + + for(u32 i = 0; i < TitleList.size(); ++i) + { + if(strncasecmp(id, TitleList[i].GameID, 6) == 0) + return TitleList[i].Region.c_str(); + } + + return "NULL"; +} + int CGameTitles::GetParentalRating(const char * id) const { if(!id) @@ -109,7 +125,8 @@ void CGameTitles::SetDefault() typedef struct _CacheTitle { char GameID[7]; - char Title[100]; + char Title[130]; // long titles e.g. RGOJJ9 & DLSP64 + char Region[7]; char FromWiiTDB; int ParentalRating; int PlayersCount; @@ -123,7 +140,7 @@ u32 CGameTitles::ReadCachedTitles(const char * path) Cachepath += '/'; Cachepath += "TitlesCache.bin"; - //! Load cached least so that the titles are preloaded before reading list + //! Load cached last so that the titles are preloaded before reading list FILE * f = fopen(Cachepath.c_str(), "rb"); if(!f) return 0; @@ -162,6 +179,7 @@ u32 CGameTitles::ReadCachedTitles(const char * path) { strcpy(TitleList[i].GameID, CachedList[i].GameID); TitleList[i].Title = CachedList[i].Title; + TitleList[i].Region = CachedList[i].Region; TitleList[i].ParentalRating = CachedList[i].ParentalRating; TitleList[i].PlayersCount = CachedList[i].PlayersCount; TitleList[i].FromWiiTDB = CachedList[i].FromWiiTDB; @@ -193,6 +211,7 @@ void CGameTitles::WriteCachedTitles(const char * path) memset(&Cache, 0, sizeof(CacheTitle)); snprintf(Cache.GameID, sizeof(Cache.GameID), "%s", TitleList[i].GameID); snprintf(Cache.Title, sizeof(Cache.Title), "%s", TitleList[i].Title.c_str()); + snprintf(Cache.Region, sizeof(Cache.Region), "%s", TitleList[i].Region.c_str()); Cache.ParentalRating = TitleList[i].ParentalRating; Cache.PlayersCount = TitleList[i].PlayersCount; Cache.FromWiiTDB = TitleList[i].FromWiiTDB; @@ -271,13 +290,17 @@ void CGameTitles::LoadTitlesFromGameTDB(const char * path, bool removeUnused) XML_DB.SetLanguageCode(Settings.db_language); int Rating; std::string RatValTxt; + std::string Region; for(u32 i = 0; i < MissingTitles.size(); ++i) { if(!XML_DB.GetTitle(MissingTitles[i].c_str(), Title)) continue; - this->SetGameTitle(MissingTitles[i].c_str(), Title.c_str()); + if(XML_DB.GetRegion(MissingTitles[i].c_str(), Region)) + this->SetGameTitle(MissingTitles[i].c_str(), Title.c_str(), Region); + else + this->SetGameTitle(MissingTitles[i].c_str(), Title.c_str()); //! Title is loaded from WiiTDB, remember that it's good TitleList[TitleList.size()-1].FromWiiTDB = 1; @@ -293,4 +316,5 @@ void CGameTitles::LoadTitlesFromGameTDB(const char * path, bool removeUnused) if(ret > 0) TitleList[TitleList.size()-1].PlayersCount = ret; } + XML_DB.CloseFile(); } diff --git a/source/settings/GameTitles.h b/source/settings/GameTitles.h index 373f6a41..ff125255 100644 --- a/source/settings/GameTitles.h +++ b/source/settings/GameTitles.h @@ -10,6 +10,7 @@ typedef struct _GameTitle { char GameID[7]; std::string Title; + std::string Region; int ParentalRating; int PlayersCount; char FromWiiTDB; @@ -20,9 +21,9 @@ class CGameTitles { public: //! Set a game title from GameTDB - void SetGameTitle(const char * id, const char * title); + void SetGameTitle(const char * id, const char * title, const std::string region = "NULL"); //! Overload - void SetGameTitle(const u8 * id, const char * title) { SetGameTitle((const char *) id, title); }; + void SetGameTitle(const u8 * id, const char * title) { SetGameTitle((const char *) id, title, "NULL"); }; //! Get a game title const char * GetTitle(const char * id) const; @@ -31,6 +32,8 @@ class CGameTitles //! Overload const char * GetTitle(const struct discHdr *header) const; + //! Get game region + const char * GetRegion(const char * id) const; //! Get game parental rating int GetParentalRating(const char * id) const; //! Get possible number of players for this game