Merge pull request #7471 from JosJuice/country-region-switch

DiscIO: Improve RegionSwitch/CountrySwitch
This commit is contained in:
Mat M 2018-10-12 10:25:45 -04:00 committed by GitHub
commit b3cd6158fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 73 additions and 50 deletions

View File

@ -298,7 +298,8 @@ DiscIO::Region TMDReader::GetRegion() const
if (GetTitleId() == Titles::SYSTEM_MENU) if (GetTitleId() == Titles::SYSTEM_MENU)
return DiscIO::GetSysMenuRegion(GetTitleVersion()); return DiscIO::GetSysMenuRegion(GetTitleVersion());
return DiscIO::RegionSwitchWii(static_cast<u8>(GetTitleId() & 0xff)); return DiscIO::CountryCodeToRegion(static_cast<u8>(GetTitleId() & 0xff),
DiscIO::Platform::WiiWAD);
} }
std::string TMDReader::GetGameID() const std::string TMDReader::GetGameID() const

View File

@ -97,12 +97,20 @@ static bool IsWiiTitle(const std::string& game_id)
static bool IsJapaneseGCTitle(const std::string& game_id) static bool IsJapaneseGCTitle(const std::string& game_id)
{ {
return IsGCTitle(game_id) && DiscIO::CountrySwitch(game_id[3]) == DiscIO::Country::Japan; if (!IsGCTitle(game_id))
return false;
return DiscIO::CountryCodeToCountry(game_id[3], DiscIO::Platform::GameCubeDisc) ==
DiscIO::Country::Japan;
} }
static bool IsNonJapaneseGCTitle(const std::string& game_id) static bool IsNonJapaneseGCTitle(const std::string& game_id)
{ {
return IsGCTitle(game_id) && DiscIO::CountrySwitch(game_id[3]) != DiscIO::Country::Japan; if (!IsGCTitle(game_id))
return false;
return DiscIO::CountryCodeToCountry(game_id[3], DiscIO::Platform::GameCubeDisc) !=
DiscIO::Country::Japan;
} }
// Note that this function will not overwrite entries that already are in the maps // Note that this function will not overwrite entries that already are in the maps

View File

@ -145,26 +145,35 @@ Country TypicalCountryForRegion(Region region)
} }
} }
Region RegionSwitchGC(u8 country_code) Region CountryCodeToRegion(u8 country_code, Platform platform, Region expected_region)
{
Region region = RegionSwitchWii(country_code);
return region == Region::NTSC_K ? Region::NTSC_J : region;
}
Region RegionSwitchWii(u8 country_code)
{ {
switch (country_code) switch (country_code)
{ {
case 'J': case 'J':
case 'W':
return Region::NTSC_J; return Region::NTSC_J;
case 'B': case 'W':
if (expected_region == Region::PAL)
return Region::PAL; // Only the Nordic version of Ratatouille (Wii)
else
return Region::NTSC_J; // Korean GC games in English or Taiwanese Wii games
case 'E': case 'E':
if (expected_region == Region::NTSC_J)
return Region::NTSC_J; // Korean GC games in English
else
return Region::NTSC_U; // The most common country code for NTSC-U
case 'B':
case 'N': case 'N':
case 'Z':
return Region::NTSC_U; return Region::NTSC_U;
case 'X':
case 'Y':
case 'Z':
// Additional language versions, store-exclusive versions, other special versions
return expected_region == Region::NTSC_U ? Region::NTSC_U : Region::PAL;
case 'D': case 'D':
case 'F': case 'F':
case 'H': case 'H':
@ -175,21 +184,21 @@ Region RegionSwitchWii(u8 country_code)
case 'R': case 'R':
case 'S': case 'S':
case 'U': case 'U':
case 'X': case 'V':
case 'Y':
return Region::PAL; return Region::PAL;
case 'K': case 'K':
case 'Q': case 'Q':
case 'T': case 'T':
return Region::NTSC_K; // All of these country codes are Korean, but the NTSC-K region doesn't exist on GC
return platform == Platform::GameCubeDisc ? Region::NTSC_J : Region::NTSC_K;
default: default:
return Region::Unknown; return Region::Unknown;
} }
} }
Country CountrySwitch(u8 country_code) Country CountryCodeToCountry(u8 country_code, Platform platform, Region region)
{ {
switch (country_code) switch (country_code)
{ {
@ -197,15 +206,29 @@ Country CountrySwitch(u8 country_code)
case 'A': case 'A':
return Country::World; return Country::World;
// Mixed regions
case 'X':
case 'Y':
case 'Z':
// Additional language versions, store-exclusive versions, other special versions
return region == Region::NTSC_U ? Country::USA : Country::Europe;
case 'W':
if (region == Region::PAL)
return Country::Europe; // Only the Nordic version of Ratatouille (Wii)
else if (platform == Platform::GameCubeDisc)
return Country::Korea; // GC games in English released in Korea
else
return Country::Taiwan; // Wii games in traditional Chinese released in Taiwan
// PAL // PAL
case 'D': case 'D':
return Country::Germany; return Country::Germany;
case 'X': // Used by a couple PAL games case 'L': // NTSC-J games released on PAL VC
case 'Y': // German, French case 'M': // NTSC-U games released on PAL VC
case 'L': // Japanese import to PAL regions case 'V': // Used by some Nordic Wii releases
case 'M': // Japanese import to PAL regions case 'P': // The most common country code for PAL
case 'P':
return Country::Europe; return Country::Europe;
case 'U': case 'U':
@ -228,21 +251,21 @@ Country CountrySwitch(u8 country_code)
// NTSC // NTSC
case 'E': case 'E':
case 'N': // Japanese import to USA and other NTSC regions if (region == Region::NTSC_J)
case 'Z': // Prince of Persia - The Forgotten Sands (Wii) return Country::Korea; // GC games in English released in Korea
case 'B': // Ufouria: The Saga (Virtual Console) else
return Country::USA; // The most common country code for NTSC-U
case 'B': // PAL games released on NTSC-U VC
case 'N': // NTSC-J games released on NTSC-U VC
return Country::USA; return Country::USA;
case 'J': case 'J':
return Country::Japan; return Country::Japan;
case 'K': case 'K': // Games in Korean released in Korea
case 'Q': // Korea with Japanese language case 'Q': // NTSC-J games released on NTSC-K VC
case 'T': // Korea with English language case 'T': // NTSC-U games released on NTSC-K VC
return Country::Korea;
case 'W':
return Country::Taiwan;
default: default:
if (country_code > 'A') // Silently ignore IOS wads if (country_code > 'A') // Silently ignore IOS wads

View File

@ -77,10 +77,9 @@ bool IsNTSC(Region region);
Country TypicalCountryForRegion(Region region); Country TypicalCountryForRegion(Region region);
// Avoid using this function if you can. Country codes aren't always reliable region indicators. // Avoid using this function if you can. Country codes aren't always reliable region indicators.
Region RegionSwitchGC(u8 country_code); Region CountryCodeToRegion(u8 country_code, Platform platform,
// Avoid using this function if you can. Country codes aren't always reliable region indicators. Region expected_region = Region::Unknown);
Region RegionSwitchWii(u8 country_code); Country CountryCodeToCountry(u8 country_code, Platform platform, Region region = Region::Unknown);
Country CountrySwitch(u8 country_code);
Region GetSysMenuRegion(u16 title_version); Region GetSysMenuRegion(u16 title_version);
std::string GetSysMenuVersionString(u16 title_version); std::string GetSysMenuVersionString(u16 title_version);

View File

@ -87,18 +87,10 @@ Country VolumeGC::GetCountry(const Partition& partition) const
const u8 country = ReadSwapped<u8>(3, partition).value_or(0); const u8 country = ReadSwapped<u8>(3, partition).value_or(0);
const Region region = GetRegion(); const Region region = GetRegion();
// Korean GC releases use NTSC-J. if (CountryCodeToRegion(country, Platform::GameCubeDisc, region) != region)
// E is normally used for America, but it's also used for English-language Korean GC releases.
// K is used by games that are in the Korean language.
// W means Taiwan for Wii games, but on the GC, it's used for English-language Korean releases.
// (There doesn't seem to be any pattern to which of E and W is used for Korean GC releases.)
if (region == Region::NTSC_J && (country == 'E' || country == 'K' || country == 'W'))
return Country::Korea;
if (RegionSwitchGC(country) != region)
return TypicalCountryForRegion(region); return TypicalCountryForRegion(region);
return CountrySwitch(country); return CountryCodeToCountry(country, Platform::GameCubeDisc, region);
} }
std::string VolumeGC::GetMakerID(const Partition& partition) const std::string VolumeGC::GetMakerID(const Partition& partition) const

View File

@ -88,7 +88,7 @@ Country VolumeWAD::GetCountry(const Partition& partition) const
if (country_code == 2) // SYSMENU if (country_code == 2) // SYSMENU
return TypicalCountryForRegion(GetSysMenuRegion(m_tmd.GetTitleVersion())); return TypicalCountryForRegion(GetSysMenuRegion(m_tmd.GetTitleVersion()));
return CountrySwitch(country_code); return CountryCodeToCountry(country_code, Platform::WiiWAD);
} }
const IOS::ES::TMDReader& VolumeWAD::GetTMD(const Partition& partition) const const IOS::ES::TMDReader& VolumeWAD::GetTMD(const Partition& partition) const

View File

@ -290,13 +290,13 @@ Region VolumeWii::GetRegion() const
Country VolumeWii::GetCountry(const Partition& partition) const Country VolumeWii::GetCountry(const Partition& partition) const
{ {
// The 0 that we use as a default value is mapped to Country::Unknown and Region::Unknown // The 0 that we use as a default value is mapped to Country::Unknown and Region::Unknown
u8 country_byte = ReadSwapped<u8>(3, partition).value_or(0); const u8 country_byte = ReadSwapped<u8>(3, partition).value_or(0);
const Region region = GetRegion(); const Region region = GetRegion();
if (RegionSwitchWii(country_byte) != region) if (CountryCodeToRegion(country_byte, Platform::WiiDisc, region) != region)
return TypicalCountryForRegion(region); return TypicalCountryForRegion(region);
return CountrySwitch(country_byte); return CountryCodeToCountry(country_byte, Platform::WiiDisc, region);
} }
std::string VolumeWii::GetMakerID(const Partition& partition) const std::string VolumeWii::GetMakerID(const Partition& partition) const