Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DiscIO: Improve RegionSwitch/CountrySwitch #7471

Merged
merged 7 commits into from Oct 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion Source/Core/Core/IOS/ES/Formats.cpp
Expand Up @@ -298,7 +298,8 @@ DiscIO::Region TMDReader::GetRegion() const
if (GetTitleId() == Titles::SYSTEM_MENU)
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
Expand Down
12 changes: 10 additions & 2 deletions Source/Core/Core/TitleDatabase.cpp
Expand Up @@ -97,12 +97,20 @@ static bool IsWiiTitle(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)
{
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
Expand Down
81 changes: 52 additions & 29 deletions Source/Core/DiscIO/Enums.cpp
Expand Up @@ -145,26 +145,35 @@ Country TypicalCountryForRegion(Region region)
}
}

Region RegionSwitchGC(u8 country_code)
{
Region region = RegionSwitchWii(country_code);
return region == Region::NTSC_K ? Region::NTSC_J : region;
}

Region RegionSwitchWii(u8 country_code)
Region CountryCodeToRegion(u8 country_code, Platform platform, Region expected_region)
{
switch (country_code)
{
case 'J':
case 'W':
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':
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 'Z':
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 'F':
case 'H':
Expand All @@ -175,37 +184,51 @@ Region RegionSwitchWii(u8 country_code)
case 'R':
case 'S':
case 'U':
case 'X':
case 'Y':
case 'V':
return Region::PAL;

case 'K':
case 'Q':
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:
return Region::Unknown;
}
}

Country CountrySwitch(u8 country_code)
Country CountryCodeToCountry(u8 country_code, Platform platform, Region region)
{
switch (country_code)
{
// Worldwide
case 'A':
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
case 'D':
return Country::Germany;

case 'X': // Used by a couple PAL games
case 'Y': // German, French
case 'L': // Japanese import to PAL regions
case 'M': // Japanese import to PAL regions
case 'P':
case 'L': // NTSC-J games released on PAL VC
case 'M': // NTSC-U games released on PAL VC
case 'V': // Used by some Nordic Wii releases
case 'P': // The most common country code for PAL
return Country::Europe;

case 'U':
Expand All @@ -228,21 +251,21 @@ Country CountrySwitch(u8 country_code)

// NTSC
case 'E':
case 'N': // Japanese import to USA and other NTSC regions
case 'Z': // Prince of Persia - The Forgotten Sands (Wii)
case 'B': // Ufouria: The Saga (Virtual Console)
if (region == Region::NTSC_J)
return Country::Korea; // GC games in English released in Korea
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;

case 'J':
return Country::Japan;

case 'K':
case 'Q': // Korea with Japanese language
case 'T': // Korea with English language
return Country::Korea;

case 'W':
return Country::Taiwan;
case 'K': // Games in Korean released in Korea
case 'Q': // NTSC-J games released on NTSC-K VC
case 'T': // NTSC-U games released on NTSC-K VC

default:
if (country_code > 'A') // Silently ignore IOS wads
Expand Down
7 changes: 3 additions & 4 deletions Source/Core/DiscIO/Enums.h
Expand Up @@ -77,10 +77,9 @@ bool IsNTSC(Region region);

Country TypicalCountryForRegion(Region region);
// Avoid using this function if you can. Country codes aren't always reliable region indicators.
Region RegionSwitchGC(u8 country_code);
// Avoid using this function if you can. Country codes aren't always reliable region indicators.
Region RegionSwitchWii(u8 country_code);
Country CountrySwitch(u8 country_code);
Region CountryCodeToRegion(u8 country_code, Platform platform,
Region expected_region = Region::Unknown);
Country CountryCodeToCountry(u8 country_code, Platform platform, Region region = Region::Unknown);

Region GetSysMenuRegion(u16 title_version);
std::string GetSysMenuVersionString(u16 title_version);
Expand Down
12 changes: 2 additions & 10 deletions Source/Core/DiscIO/VolumeGC.cpp
Expand Up @@ -87,18 +87,10 @@ Country VolumeGC::GetCountry(const Partition& partition) const
const u8 country = ReadSwapped<u8>(3, partition).value_or(0);
const Region region = GetRegion();

// Korean GC releases use NTSC-J.
// 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.)

This comment was marked as off-topic.

if (region == Region::NTSC_J && (country == 'E' || country == 'K' || country == 'W'))
return Country::Korea;

if (RegionSwitchGC(country) != region)
if (CountryCodeToRegion(country, Platform::GameCubeDisc, region) != region)
return TypicalCountryForRegion(region);

return CountrySwitch(country);
return CountryCodeToCountry(country, Platform::GameCubeDisc, region);
}

std::string VolumeGC::GetMakerID(const Partition& partition) const
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/DiscIO/VolumeWad.cpp
Expand Up @@ -88,7 +88,7 @@ Country VolumeWAD::GetCountry(const Partition& partition) const
if (country_code == 2) // SYSMENU
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
Expand Down
6 changes: 3 additions & 3 deletions Source/Core/DiscIO/VolumeWii.cpp
Expand Up @@ -290,13 +290,13 @@ Region VolumeWii::GetRegion() 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
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();

if (RegionSwitchWii(country_byte) != region)
if (CountryCodeToRegion(country_byte, Platform::WiiDisc, region) != region)
return TypicalCountryForRegion(region);

return CountrySwitch(country_byte);
return CountryCodeToCountry(country_byte, Platform::WiiDisc, region);
}

std::string VolumeWii::GetMakerID(const Partition& partition) const
Expand Down