diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 5b263e45e6..7979038790 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -419,7 +419,7 @@ bool CBoot::BootUp() // Poor man's bootup if (_StartupPara.bWii) - SetupWiiMemory(DiscIO::Country::COUNTRY_UNKNOWN); + SetupWiiMemory(DiscIO::Region::UNKNOWN_REGION); else EmulatedBS2_GC(true); diff --git a/Source/Core/Core/Boot/Boot.h b/Source/Core/Core/Boot/Boot.h index 5299d260da..aa952d1199 100644 --- a/Source/Core/Core/Boot/Boot.h +++ b/Source/Core/Core/Boot/Boot.h @@ -9,10 +9,10 @@ namespace DiscIO { -enum class Country; +enum class Region; } -struct CountrySetting +struct RegionSetting { const std::string area; const std::string video; @@ -57,5 +57,5 @@ private: static bool Load_BS2(const std::string& _rBootROMFilename); static void Load_FST(bool _bIsWii); - static bool SetupWiiMemory(DiscIO::Country country); + static bool SetupWiiMemory(DiscIO::Region region); }; diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index 817c5d4bcc..5b44b297b4 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -181,28 +181,22 @@ bool CBoot::EmulatedBS2_GC(bool skipAppLoader) return true; } -bool CBoot::SetupWiiMemory(DiscIO::Country country) +bool CBoot::SetupWiiMemory(DiscIO::Region region) { - static const CountrySetting SETTING_EUROPE = {"EUR", "PAL", "EU", "LE"}; - static const CountrySetting SETTING_USA = {"USA", "NTSC", "US", "LU"}; - static const CountrySetting SETTING_JAPAN = {"JPN", "NTSC", "JP", "LJ"}; - static const CountrySetting SETTING_KOREA = {"KOR", "NTSC", "KR", "LKH"}; - static const std::map country_settings = { - {DiscIO::Country::COUNTRY_EUROPE, SETTING_EUROPE}, - {DiscIO::Country::COUNTRY_USA, SETTING_USA}, - {DiscIO::Country::COUNTRY_JAPAN, SETTING_JAPAN}, - {DiscIO::Country::COUNTRY_KOREA, SETTING_KOREA}, - // TODO: Determine if Taiwan have their own specific settings. - // Also determine if there are other specific settings - // for other countries. - {DiscIO::Country::COUNTRY_TAIWAN, SETTING_JAPAN}}; - auto entryPos = country_settings.find(country); - const CountrySetting& country_setting = - (entryPos != country_settings.end()) ? + static const RegionSetting SETTING_NTSC_J = {"JPN", "NTSC", "JP", "LJ"}; + static const RegionSetting SETTING_NTSC_U = {"USA", "NTSC", "US", "LU"}; + static const RegionSetting SETTING_PAL = {"EUR", "PAL", "EU", "LE"}; + static const RegionSetting SETTING_NTSC_K = {"KOR", "NTSC", "KR", "LKH"}; + static const std::map region_settings = { + {DiscIO::Region::NTSC_J, SETTING_NTSC_J}, + {DiscIO::Region::NTSC_U, SETTING_NTSC_U}, + {DiscIO::Region::PAL, SETTING_PAL}, + {DiscIO::Region::NTSC_K, SETTING_NTSC_K}}; + auto entryPos = region_settings.find(region); + const RegionSetting& region_setting = + (entryPos != region_settings.end()) ? entryPos->second : - (SConfig::GetInstance().bNTSC ? - SETTING_USA : - SETTING_EUROPE); // default to USA or EUR depending on game's video mode + (SConfig::GetInstance().bNTSC ? SETTING_NTSC_U : SETTING_PAL); SettingsHandler gen; std::string serno; @@ -233,15 +227,15 @@ bool CBoot::SetupWiiMemory(DiscIO::Country country) INFO_LOG(BOOT, "Using serial number: %s", serno.c_str()); } - std::string model = "RVL-001(" + country_setting.area + ")"; - gen.AddSetting("AREA", country_setting.area); + std::string model = "RVL-001(" + region_setting.area + ")"; + gen.AddSetting("AREA", region_setting.area); gen.AddSetting("MODEL", model); gen.AddSetting("DVD", "0"); gen.AddSetting("MPCH", "0x7FFE"); - gen.AddSetting("CODE", country_setting.code); + gen.AddSetting("CODE", region_setting.code); gen.AddSetting("SERNO", serno); - gen.AddSetting("VIDEO", country_setting.video); - gen.AddSetting("GAME", country_setting.game); + gen.AddSetting("VIDEO", region_setting.video); + gen.AddSetting("GAME", region_setting.game); File::CreateFullPath(settings_Filename); { @@ -336,10 +330,10 @@ bool CBoot::EmulatedBS2_Wii() INFO_LOG(BOOT, "Faking Wii BS2..."); // Setup Wii memory - DiscIO::Country country_code = DiscIO::Country::COUNTRY_UNKNOWN; + DiscIO::Region region_code = DiscIO::Region::UNKNOWN_REGION; if (DVDInterface::VolumeIsValid()) - country_code = DVDInterface::GetVolume().GetCountry(); - if (SetupWiiMemory(country_code) == false) + region_code = DVDInterface::GetVolume().GetRegion(); + if (SetupWiiMemory(region_code) == false) return false; // Execute the apploader diff --git a/Source/Core/Core/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Boot/Boot_WiiWAD.cpp index 3a54ee03ed..f7cc276f48 100644 --- a/Source/Core/Core/Boot/Boot_WiiWAD.cpp +++ b/Source/Core/Core/Boot/Boot_WiiWAD.cpp @@ -89,10 +89,10 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename) if (titleID == TITLEID_SYSMENU) HLE_IPC_CreateVirtualFATFilesystem(); // setup Wii memory - if (!SetupWiiMemory(ContentLoader.GetCountry())) + if (!SetupWiiMemory(ContentLoader.GetRegion())) return false; // this sets a bit that is used to detect NTSC-J - if (ContentLoader.GetCountry() == DiscIO::Country::COUNTRY_JAPAN) + if (ContentLoader.GetRegion() == DiscIO::Region::NTSC_J) { VideoInterface::SetRegionReg('J'); } diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 40b4019676..9b1545d123 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -794,31 +794,28 @@ void SConfig::LoadDefaults() m_revision = 0; } -static const char* GetRegionOfCountry(DiscIO::Country country) +static const char* GetDirectoryForRegion(DiscIO::Region region) { - switch (country) + switch (region) { - case DiscIO::Country::COUNTRY_USA: - return USA_DIR; - - case DiscIO::Country::COUNTRY_TAIWAN: - case DiscIO::Country::COUNTRY_KOREA: - // TODO: Should these have their own Region Dir? - case DiscIO::Country::COUNTRY_JAPAN: + case DiscIO::Region::NTSC_J: return JAP_DIR; - case DiscIO::Country::COUNTRY_AUSTRALIA: - case DiscIO::Country::COUNTRY_EUROPE: - case DiscIO::Country::COUNTRY_FRANCE: - case DiscIO::Country::COUNTRY_GERMANY: - case DiscIO::Country::COUNTRY_ITALY: - case DiscIO::Country::COUNTRY_NETHERLANDS: - case DiscIO::Country::COUNTRY_RUSSIA: - case DiscIO::Country::COUNTRY_SPAIN: - case DiscIO::Country::COUNTRY_WORLD: + case DiscIO::Region::NTSC_U: + return USA_DIR; + + case DiscIO::Region::PAL: return EUR_DIR; - case DiscIO::Country::COUNTRY_UNKNOWN: + case DiscIO::Region::NTSC_K: + // This function can't return a Korean directory name, because this + // function is only used for GameCube things (memory cards, IPL), and + // GameCube has no NTSC-K region. Since NTSC-K doesn't correspond to any + // GameCube region, let's return an arbitrary pick. Returning nullptr like + // with unknown regions would be inappropriate, because Dolphin expects + // to get valid memory card paths even when running an NTSC-K Wii game. + return JAP_DIR; + default: return nullptr; } @@ -870,17 +867,19 @@ bool SConfig::AutoSetup(EBootBS2 _BootBS2) // Check if we have a Wii disc bWii = pVolume->GetVolumeType() == DiscIO::Platform::WII_DISC; - const char* retrieved_region_dir = GetRegionOfCountry(pVolume->GetCountry()); + DiscIO::Region region = pVolume->GetRegion(); + const char* retrieved_region_dir = GetDirectoryForRegion(region); if (!retrieved_region_dir) { if (!PanicYesNoT("Your GCM/ISO file seems to be invalid (invalid country)." "\nContinue with PAL region?")) return false; + region = DiscIO::Region::PAL; retrieved_region_dir = EUR_DIR; } set_region_dir = retrieved_region_dir; - bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR; + bNTSC = region != DiscIO::Region::PAL; } else if (!strcasecmp(Extension.c_str(), ".elf")) { @@ -932,7 +931,7 @@ bool SConfig::AutoSetup(EBootBS2 _BootBS2) return false; // do not boot } - const char* retrieved_region_dir = GetRegionOfCountry(ContentLoader.GetCountry()); + const char* retrieved_region_dir = GetDirectoryForRegion(ContentLoader.GetRegion()); set_region_dir = retrieved_region_dir ? retrieved_region_dir : EUR_DIR; bNTSC = set_region_dir == USA_DIR || set_region_dir == JAP_DIR; diff --git a/Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp b/Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp index 5eb49b5c5e..47d9efeb18 100644 --- a/Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp +++ b/Source/Core/Core/HW/EXI_DeviceMemoryCard.cpp @@ -152,7 +152,7 @@ CEXIMemoryCard::CEXIMemoryCard(const int index, bool gciFolder) : card_index(ind void CEXIMemoryCard::SetupGciFolder(u16 sizeMb) { - DiscIO::Country country_code = DiscIO::Country::COUNTRY_UNKNOWN; + DiscIO::Region region = DiscIO::Region::UNKNOWN_REGION; std::string game_id = SConfig::GetInstance().m_strGameID; u32 CurrentGameId = 0; @@ -163,26 +163,28 @@ void CEXIMemoryCard::SetupGciFolder(u16 sizeMb) Common::FROM_SESSION_ROOT); if (SysMenu_Loader.IsValid()) { - country_code = DiscIO::CountrySwitch(SysMenu_Loader.GetCountryChar()); + region = DiscIO::RegionSwitchGC(SysMenu_Loader.GetCountryChar()); } } else if (game_id.length() >= 4) { - country_code = DiscIO::CountrySwitch(game_id.at(3)); + region = DiscIO::RegionSwitchGC(game_id.at(3)); CurrentGameId = BE32((u8*)game_id.c_str()); } bool shift_jis = false; std::string strDirectoryName = File::GetUserPath(D_GCUSER_IDX); - switch (country_code) + switch (region) { - case DiscIO::Country::COUNTRY_JAPAN: + case DiscIO::Region::NTSC_J: shift_jis = true; strDirectoryName += JAP_DIR DIR_SEP; break; - case DiscIO::Country::COUNTRY_USA: + case DiscIO::Region::NTSC_U: strDirectoryName += USA_DIR DIR_SEP; break; - case DiscIO::Country::COUNTRY_UNKNOWN: + case DiscIO::Region::PAL: + strDirectoryName += EUR_DIR DIR_SEP; + default: { // The current game's region is not passed down to the EXI device level. // Usually, we can retrieve the region from SConfig::GetInstance().m_strUniqueId. @@ -199,24 +201,25 @@ void CEXIMemoryCard::SetupGciFolder(u16 sizeMb) std::string memcardFilename = (card_index == 0) ? SConfig::GetInstance().m_strMemoryCardA : SConfig::GetInstance().m_strMemoryCardB; - std::string region = memcardFilename.substr(memcardFilename.size() - 7, 3); - if (region == JAP_DIR) + std::string region_string = memcardFilename.substr(memcardFilename.size() - 7, 3); + if (region_string == JAP_DIR) { - country_code = DiscIO::Country::COUNTRY_JAPAN; + region = DiscIO::Region::NTSC_J; shift_jis = true; strDirectoryName += JAP_DIR DIR_SEP; - break; } - else if (region == USA_DIR) + else if (region_string == USA_DIR) { - country_code = DiscIO::Country::COUNTRY_USA; + region = DiscIO::Region::NTSC_U; strDirectoryName += USA_DIR DIR_SEP; - break; } + else + { + region = DiscIO::Region::PAL; + strDirectoryName += EUR_DIR DIR_SEP; + } + break; } - default: - country_code = DiscIO::Country::COUNTRY_EUROPE; - strDirectoryName += EUR_DIR DIR_SEP; } strDirectoryName += StringFromFormat("Card %c", 'A' + card_index); @@ -243,7 +246,7 @@ void CEXIMemoryCard::SetupGciFolder(u16 sizeMb) } memorycard = std::make_unique(strDirectoryName + DIR_SEP, card_index, sizeMb, - shift_jis, country_code, CurrentGameId); + shift_jis, region, CurrentGameId); } void CEXIMemoryCard::SetupRawMemcard(u16 sizeMb) diff --git a/Source/Core/Core/HW/GCMemcard.h b/Source/Core/Core/HW/GCMemcard.h index 69f6c5c85e..f77ba05a68 100644 --- a/Source/Core/Core/HW/GCMemcard.h +++ b/Source/Core/Core/HW/GCMemcard.h @@ -103,7 +103,7 @@ struct Header // Offset Size Description // end Serial in libogc u8 deviceID[2]; // 0x0020 2 0 if formated in slot A 1 if formated in slot B u8 SizeMb[2]; // 0x0022 2 Size of memcard in Mbits - u16 Encoding; // 0x0024 2 Encoding (ASCII or Japanese) + u16 Encoding; // 0x0024 2 Encoding (Windows-1252 or Shift JIS) u8 Unused1[468]; // 0x0026 468 Unused (0xff) u16 UpdateCounter; // 0x01fa 2 Update Counter (?, probably unused) u16 Checksum; // 0x01fc 2 Additive Checksum diff --git a/Source/Core/Core/HW/GCMemcardDirectory.cpp b/Source/Core/Core/HW/GCMemcardDirectory.cpp index 8ef39e8649..69d177f052 100644 --- a/Source/Core/Core/HW/GCMemcardDirectory.cpp +++ b/Source/Core/Core/HW/GCMemcardDirectory.cpp @@ -24,7 +24,7 @@ const int NO_INDEX = -1; static const char* MC_HDR = "MC_SYSTEM_AREA"; -int GCMemcardDirectory::LoadGCI(const std::string& fileName, DiscIO::Country card_region, +int GCMemcardDirectory::LoadGCI(const std::string& fileName, DiscIO::Region card_region, bool currentGameOnly) { File::IOFile gcifile(fileName, "rb"); @@ -39,27 +39,12 @@ int GCMemcardDirectory::LoadGCI(const std::string& fileName, DiscIO::Country car return NO_INDEX; } - DiscIO::Country gci_region; - // check region - switch (gci.m_gci_header.Gamecode[3]) - { - case 'J': - gci_region = DiscIO::Country::COUNTRY_JAPAN; - break; - case 'E': - gci_region = DiscIO::Country::COUNTRY_USA; - break; - case 'C': - // Used by Datel Action Replay Save - // can be on any regions card - gci_region = card_region; - break; - default: - gci_region = DiscIO::Country::COUNTRY_EUROPE; - break; - } - - if (gci_region != card_region) + DiscIO::Region gci_region = DiscIO::RegionSwitchGC(gci.m_gci_header.Gamecode[3]); + // Some special save files have game IDs that we parse as UNKNOWN_REGION. For instance: + // - Datel Action Replay uses C as the fourth character. (Can be on any region's card.) + // - Homeland's network config file only uses null bytes. (Homeland is exclusive to Japan, + // but maybe the network config file ID was intended to be used in other regions too.) + if (card_region != gci_region && gci_region != DiscIO::Region::UNKNOWN_REGION) { PanicAlertT( "GCI save file was not loaded because it is the wrong region for this memory card:\n%s", @@ -146,7 +131,7 @@ int GCMemcardDirectory::LoadGCI(const std::string& fileName, DiscIO::Country car } GCMemcardDirectory::GCMemcardDirectory(const std::string& directory, int slot, u16 sizeMb, - bool shift_jis, DiscIO::Country card_region, int gameId) + bool shift_jis, DiscIO::Region card_region, int gameId) : MemoryCardBase(slot, sizeMb), m_GameId(gameId), m_LastBlock(-1), m_hdr(slot, sizeMb, shift_jis), m_bat1(sizeMb), m_saves(0), m_SaveDirectory(directory), m_exiting(false) diff --git a/Source/Core/Core/HW/GCMemcardDirectory.h b/Source/Core/Core/HW/GCMemcardDirectory.h index a291c3e095..711dfda026 100644 --- a/Source/Core/Core/HW/GCMemcardDirectory.h +++ b/Source/Core/Core/HW/GCMemcardDirectory.h @@ -22,9 +22,8 @@ void MigrateFromMemcardFile(const std::string& strDirectoryName, int card_index) class GCMemcardDirectory : public MemoryCardBase, NonCopyable { public: - GCMemcardDirectory(const std::string& directory, int slot = 0, u16 sizeMb = MemCard2043Mb, - bool shift_jis = false, - DiscIO::Country card_region = DiscIO::Country::COUNTRY_EUROPE, int gameId = 0); + GCMemcardDirectory(const std::string& directory, int slot, u16 sizeMb, bool shift_jis, + DiscIO::Region card_region, int gameId); ~GCMemcardDirectory(); void FlushToFile(); void FlushThread(); @@ -35,7 +34,7 @@ public: void DoState(PointerWrap& p) override; private: - int LoadGCI(const std::string& fileName, DiscIO::Country card_region, bool currentGameOnly); + int LoadGCI(const std::string& fileName, DiscIO::Region card_region, bool currentGameOnly); inline s32 SaveAreaRW(u32 block, bool writing = false); // s32 DirectoryRead(u32 offset, u32 length, u8* destaddress); s32 DirectoryWrite(u32 destaddress, u32 length, u8* srcaddress); diff --git a/Source/Core/DiscIO/Enums.cpp b/Source/Core/DiscIO/Enums.cpp index 385fff1317..6689470f32 100644 --- a/Source/Core/DiscIO/Enums.cpp +++ b/Source/Core/DiscIO/Enums.cpp @@ -13,6 +13,50 @@ namespace DiscIO { // Increment CACHE_REVISION (ISOFile.cpp & GameFile.cpp) if the code below is modified +Region RegionSwitchGC(u8 country_code) +{ + Region region = RegionSwitchWii(country_code); + return region == Region::NTSC_K ? Region::UNKNOWN_REGION : region; +} + +Region RegionSwitchWii(u8 country_code) +{ + switch (country_code) + { + case 'J': + case 'W': + return Region::NTSC_J; + + case 'B': + case 'E': + case 'N': + case 'Z': + return Region::NTSC_U; + + case 'D': + case 'F': + case 'H': + case 'I': + case 'L': + case 'M': + case 'P': + case 'R': + case 'S': + case 'U': + case 'X': + case 'Y': + return Region::PAL; + + case 'K': + case 'Q': + case 'T': + return Region::NTSC_K; + + default: + return Region::UNKNOWN_REGION; + } +} + Country CountrySwitch(u8 country_code) { switch (country_code) diff --git a/Source/Core/DiscIO/Enums.h b/Source/Core/DiscIO/Enums.h index 59f61561de..01f7ddb529 100644 --- a/Source/Core/DiscIO/Enums.h +++ b/Source/Core/DiscIO/Enums.h @@ -38,6 +38,16 @@ enum class Country NUMBER_OF_COUNTRIES }; +// Regions 0 - 2 and 4 match Nintendo's Wii region numbering. +enum class Region +{ + NTSC_J = 0, // Japan and Taiwan + NTSC_U = 1, // Mainly North America + PAL = 2, // Mainly Europe and Oceania + UNKNOWN_REGION = 3, // 3 seems to be unused? Anyway, we need an UNKNOWN_REGION. Let's put it here + NTSC_K = 4 // South Korea (Wii only) +}; + // Languages 0 - 9 match Nintendo's Wii language numbering. // Languages 1 - 6 match Nintendo's PAL GameCube languages 0 - 5. // NTSC GameCubes only support one language and thus don't number languages. @@ -56,6 +66,8 @@ enum class Language LANGUAGE_UNKNOWN }; +Region RegionSwitchGC(u8 country_code); +Region RegionSwitchWii(u8 country_code); Country CountrySwitch(u8 country_code); u8 GetSysMenuRegion(u16 title_version); std::string GetCompanyFromID(const std::string& company_id); diff --git a/Source/Core/DiscIO/NANDContentLoader.cpp b/Source/Core/DiscIO/NANDContentLoader.cpp index 5b3057efbf..2c5e0e87e7 100644 --- a/Source/Core/DiscIO/NANDContentLoader.cpp +++ b/Source/Core/DiscIO/NANDContentLoader.cpp @@ -311,12 +311,12 @@ std::vector CNANDContentLoader::GetKeyFromTicket(const std::vector& tick return AESDecode(common_key, iv, &ticket[0x01BF], 16); } -DiscIO::Country CNANDContentLoader::GetCountry() const +DiscIO::Region CNANDContentLoader::GetRegion() const { if (!IsValid()) - return DiscIO::Country::COUNTRY_UNKNOWN; + return DiscIO::Region::UNKNOWN_REGION; - return CountrySwitch(m_Country); + return RegionSwitchWii(m_Country); } CNANDContentManager::~CNANDContentManager() diff --git a/Source/Core/DiscIO/NANDContentLoader.h b/Source/Core/DiscIO/NANDContentLoader.h index 6643e2789c..f8d3bb6711 100644 --- a/Source/Core/DiscIO/NANDContentLoader.h +++ b/Source/Core/DiscIO/NANDContentLoader.h @@ -20,7 +20,7 @@ class IOFile; namespace DiscIO { -enum class Country; +enum class Region; bool AddTicket(u64 title_id, const std::vector& ticket); @@ -94,7 +94,7 @@ public: const std::vector& GetContent() const { return m_Content; } u16 GetTitleVersion() const { return m_TitleVersion; } u16 GetNumEntries() const { return m_NumEntries; } - DiscIO::Country GetCountry() const; + DiscIO::Region GetRegion() const; u8 GetCountryChar() const { return m_Country; } enum { diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h index 44af039cba..6f4a6defe4 100644 --- a/Source/Core/DiscIO/Volume.h +++ b/Source/Core/DiscIO/Volume.h @@ -55,6 +55,7 @@ public: virtual bool SupportsIntegrityCheck() const { return false; } virtual bool CheckIntegrity() const { return false; } virtual bool ChangePartition(u64 offset) { return false; } + virtual Region GetRegion() const = 0; virtual Country GetCountry() const = 0; virtual BlobType GetBlobType() const = 0; // Size of virtual disc (not always accurate) @@ -71,12 +72,7 @@ protected: // strnlen to trim NULLs std::string string(data, strnlen(data, sizeof(data))); - // There doesn't seem to be any GC discs with the country set to Taiwan... - // But maybe they would use Shift_JIS if they existed? Not sure - bool use_shift_jis = - (Country::COUNTRY_JAPAN == GetCountry() || Country::COUNTRY_TAIWAN == GetCountry()); - - if (use_shift_jis) + if (GetRegion() == Region::NTSC_J) return SHIFTJISToUTF8(string); else return CP1252ToUTF8(string); diff --git a/Source/Core/DiscIO/VolumeDirectory.cpp b/Source/Core/DiscIO/VolumeDirectory.cpp index 504d17c20f..40dda01d0d 100644 --- a/Source/Core/DiscIO/VolumeDirectory.cpp +++ b/Source/Core/DiscIO/VolumeDirectory.cpp @@ -166,6 +166,14 @@ void CVolumeDirectory::SetGameID(const std::string& id) memcpy(m_disk_header.data(), id.c_str(), std::min(id.length(), MAX_ID_LENGTH)); } +Region CVolumeDirectory::GetRegion() const +{ + if (m_is_wii) + return RegionSwitchWii(m_disk_header[3]); + + return RegionSwitchGC(m_disk_header[3]); +} + Country CVolumeDirectory::GetCountry() const { return CountrySwitch(m_disk_header[3]); diff --git a/Source/Core/DiscIO/VolumeDirectory.h b/Source/Core/DiscIO/VolumeDirectory.h index ab0a96400d..13a8799eda 100644 --- a/Source/Core/DiscIO/VolumeDirectory.h +++ b/Source/Core/DiscIO/VolumeDirectory.h @@ -26,6 +26,7 @@ namespace DiscIO enum class BlobType; enum class Country; enum class Language; +enum class Region; enum class Platform; class CVolumeDirectory : public IVolume @@ -56,6 +57,7 @@ public: std::string GetApploaderDate() const override; Platform GetVolumeType() const override; + Region GetRegion() const override; Country GetCountry() const override; BlobType GetBlobType() const override; diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index 58faed4fe8..fcba359931 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -61,13 +61,20 @@ std::string CVolumeGC::GetGameID() const return DecodeString(ID); } +Region CVolumeGC::GetRegion() const +{ + u8 country_code; + if (!m_pReader->Read(3, 1, &country_code)) + return Region::UNKNOWN_REGION; + + return RegionSwitchGC(country_code); +} + Country CVolumeGC::GetCountry() const { - if (!m_pReader) - return Country::COUNTRY_UNKNOWN; - u8 country_code; - m_pReader->Read(3, 1, &country_code); + if (!m_pReader->Read(3, 1, &country_code)) + return Country::COUNTRY_UNKNOWN; return CountrySwitch(country_code); } @@ -247,7 +254,7 @@ void CVolumeGC::ExtractBannerInformation(const GCBanner& banner_file, bool is_bn if (is_bnr1) // NTSC { - bool is_japanese = GetCountry() == Country::COUNTRY_JAPAN; + bool is_japanese = GetRegion() == Region::NTSC_J; number_of_languages = 1; start_language = is_japanese ? Language::LANGUAGE_JAPANESE : Language::LANGUAGE_ENGLISH; } diff --git a/Source/Core/DiscIO/VolumeGC.h b/Source/Core/DiscIO/VolumeGC.h index ca461949e2..ab424c6c50 100644 --- a/Source/Core/DiscIO/VolumeGC.h +++ b/Source/Core/DiscIO/VolumeGC.h @@ -19,6 +19,7 @@ namespace DiscIO enum class BlobType; enum class Country; enum class Language; +enum class Region; enum class Platform; class CVolumeGC : public IVolume @@ -42,6 +43,7 @@ public: u8 GetDiscNumber() const override; Platform GetVolumeType() const override; + Region GetRegion() const override; Country GetCountry() const override; BlobType GetBlobType() const override; u64 GetSize() const override; diff --git a/Source/Core/DiscIO/VolumeWad.cpp b/Source/Core/DiscIO/VolumeWad.cpp index 3254190be9..7c089ad10a 100644 --- a/Source/Core/DiscIO/VolumeWad.cpp +++ b/Source/Core/DiscIO/VolumeWad.cpp @@ -57,14 +57,21 @@ bool CVolumeWAD::Read(u64 _Offset, u64 _Length, u8* _pBuffer, bool decrypt) cons return m_pReader->Read(_Offset, _Length, _pBuffer); } +Region CVolumeWAD::GetRegion() const +{ + u8 country_code; + if (!Read(m_tmd_offset + 0x0193, 1, &country_code)) + return Region::UNKNOWN_REGION; + + return RegionSwitchWii(country_code); +} + Country CVolumeWAD::GetCountry() const { - if (!m_pReader) - return Country::COUNTRY_UNKNOWN; - // read the last digit of the titleID in the ticket u8 country_code; - Read(m_tmd_offset + 0x0193, 1, &country_code); + if (!Read(m_tmd_offset + 0x0193, 1, &country_code)) + return Country::COUNTRY_UNKNOWN; if (country_code == 2) // SYSMENU { diff --git a/Source/Core/DiscIO/VolumeWad.h b/Source/Core/DiscIO/VolumeWad.h index 68fc6a7612..0f28064387 100644 --- a/Source/Core/DiscIO/VolumeWad.h +++ b/Source/Core/DiscIO/VolumeWad.h @@ -21,6 +21,7 @@ namespace DiscIO enum class BlobType; enum class Country; enum class Language; +enum class Region; enum class Platform; class CVolumeWAD : public IVolume @@ -39,6 +40,7 @@ public: u64 GetFSTSize() const override { return 0; } std::string GetApploaderDate() const override { return ""; } Platform GetVolumeType() const override; + Region GetRegion() const override; Country GetCountry() const override; BlobType GetBlobType() const override; diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.cpp b/Source/Core/DiscIO/VolumeWiiCrypted.cpp index 09224e04aa..7976e1d758 100644 --- a/Source/Core/DiscIO/VolumeWiiCrypted.cpp +++ b/Source/Core/DiscIO/VolumeWiiCrypted.cpp @@ -153,51 +153,38 @@ std::string CVolumeWiiCrypted::GetGameID() const return DecodeString(ID); } +Region CVolumeWiiCrypted::GetRegion() const +{ + u32 region_code; + if (!ReadSwapped(0x4E000, ®ion_code, false)) + return Region::UNKNOWN_REGION; + + return static_cast(region_code); +} + Country CVolumeWiiCrypted::GetCountry() const { - if (!m_pReader) - return Country::COUNTRY_UNKNOWN; - u8 country_byte; if (!m_pReader->Read(3, 1, &country_byte)) return Country::COUNTRY_UNKNOWN; - Country country_value = CountrySwitch(country_byte); + const Region region = GetRegion(); - u32 region_code; - if (!ReadSwapped(0x4E000, ®ion_code, false)) - return country_value; + if (RegionSwitchWii(country_byte) == region) + return CountrySwitch(country_byte); - switch (region_code) + switch (region) { - case 0: - switch (country_value) - { - case Country::COUNTRY_TAIWAN: - return Country::COUNTRY_TAIWAN; - default: - return Country::COUNTRY_JAPAN; - } - case 1: + case Region::NTSC_J: + return Country::COUNTRY_JAPAN; + case Region::NTSC_U: return Country::COUNTRY_USA; - case 2: - switch (country_value) - { - case Country::COUNTRY_FRANCE: - case Country::COUNTRY_GERMANY: - case Country::COUNTRY_ITALY: - case Country::COUNTRY_NETHERLANDS: - case Country::COUNTRY_RUSSIA: - case Country::COUNTRY_SPAIN: - case Country::COUNTRY_AUSTRALIA: - return country_value; - default: - return Country::COUNTRY_EUROPE; - } - case 4: + case Region::PAL: + return Country::COUNTRY_EUROPE; + case Region::NTSC_K: return Country::COUNTRY_KOREA; default: - return country_value; + return Country::COUNTRY_UNKNOWN; } } diff --git a/Source/Core/DiscIO/VolumeWiiCrypted.h b/Source/Core/DiscIO/VolumeWiiCrypted.h index 9bb449980d..d578dd5ba0 100644 --- a/Source/Core/DiscIO/VolumeWiiCrypted.h +++ b/Source/Core/DiscIO/VolumeWiiCrypted.h @@ -20,6 +20,7 @@ namespace DiscIO enum class BlobType; enum class Country; enum class Language; +enum class Region; enum class Platform; class CVolumeWiiCrypted : public IVolume @@ -46,6 +47,7 @@ public: bool CheckIntegrity() const override; bool ChangePartition(u64 offset) override; + Region GetRegion() const override; Country GetCountry() const override; BlobType GetBlobType() const override; u64 GetSize() const override; diff --git a/Source/Core/DolphinQt2/GameList/GameFile.cpp b/Source/Core/DolphinQt2/GameList/GameFile.cpp index f27f3a6683..3f1d60d65f 100644 --- a/Source/Core/DolphinQt2/GameList/GameFile.cpp +++ b/Source/Core/DolphinQt2/GameList/GameFile.cpp @@ -155,6 +155,7 @@ bool GameFile::TryLoadVolume() m_descriptions = ConvertLanguageMap(volume->GetDescriptions()); m_disc_number = volume->GetDiscNumber(); m_platform = volume->GetVolumeType(); + m_region = volume->GetRegion(); m_country = volume->GetCountry(); m_blob_type = volume->GetBlobType(); m_raw_size = volume->GetRawSize(); @@ -174,6 +175,7 @@ bool GameFile::TryLoadElfDol() m_revision = 0; m_long_names[DiscIO::Language::LANGUAGE_ENGLISH] = m_file_name; m_platform = DiscIO::Platform::ELF_DOL; + m_region = DiscIO::Region::UNKNOWN_REGION; m_country = DiscIO::Country::COUNTRY_UNKNOWN; m_blob_type = DiscIO::BlobType::DIRECTORY; m_raw_size = m_size; diff --git a/Source/Core/DolphinQt2/GameList/GameFile.h b/Source/Core/DolphinQt2/GameList/GameFile.h index 99d9a143e2..9813a39054 100644 --- a/Source/Core/DolphinQt2/GameList/GameFile.h +++ b/Source/Core/DolphinQt2/GameList/GameFile.h @@ -16,6 +16,7 @@ namespace DiscIO enum class BlobType; enum class Country; enum class Language; +enum class Region; enum class Platform; class IVolume; } @@ -47,6 +48,7 @@ public: QString GetApploaderDate() const { return m_apploader_date; } DiscIO::Platform GetPlatformID() const { return m_platform; } QString GetPlatform() const; + DiscIO::Region GetRegion() const { return m_region; } DiscIO::Country GetCountryID() const { return m_country; } QString GetCountry() const; DiscIO::BlobType GetBlobType() const { return m_blob_type; } @@ -96,6 +98,7 @@ private: QMap m_descriptions; QString m_company; u8 m_disc_number = 0; + DiscIO::Region m_region; DiscIO::Platform m_platform; DiscIO::Country m_country; DiscIO::BlobType m_blob_type; diff --git a/Source/Core/DolphinWX/ISOFile.cpp b/Source/Core/DolphinWX/ISOFile.cpp index e1ee632406..5a46458d81 100644 --- a/Source/Core/DolphinWX/ISOFile.cpp +++ b/Source/Core/DolphinWX/ISOFile.cpp @@ -36,7 +36,7 @@ #include "DolphinWX/ISOFile.h" #include "DolphinWX/WxUtils.h" -static const u32 CACHE_REVISION = 0x127; // Last changed in PR 3309 +static const u32 CACHE_REVISION = 0x128; // Last changed in PR 4542 static std::string GetLanguageString(DiscIO::Language language, std::map strings) @@ -64,8 +64,9 @@ static std::string GetLanguageString(DiscIO::Language language, GameListItem::GameListItem(const std::string& _rFileName, const std::unordered_map& custom_titles) : m_FileName(_rFileName), m_title_id(0), m_emu_state(0), m_FileSize(0), - m_Country(DiscIO::Country::COUNTRY_UNKNOWN), m_Revision(0), m_Valid(false), m_ImageWidth(0), - m_ImageHeight(0), m_disc_number(0), m_has_custom_name(false) + m_region(DiscIO::Region::UNKNOWN_REGION), m_Country(DiscIO::Country::COUNTRY_UNKNOWN), + m_Revision(0), m_Valid(false), m_ImageWidth(0), m_ImageHeight(0), m_disc_number(0), + m_has_custom_name(false) { if (LoadFromCache()) { @@ -99,6 +100,7 @@ GameListItem::GameListItem(const std::string& _rFileName, if (m_company.empty()) m_company = GetLanguageString(DiscIO::Language::LANGUAGE_ENGLISH, volume->GetShortMakers()); + m_region = volume->GetRegion(); m_Country = volume->GetCountry(); m_blob_type = volume->GetBlobType(); m_FileSize = volume->GetRawSize(); @@ -214,6 +216,7 @@ void GameListItem::DoState(PointerWrap& p) p.Do(m_title_id); p.Do(m_FileSize); p.Do(m_VolumeSize); + p.Do(m_region); p.Do(m_Country); p.Do(m_blob_type); p.Do(m_pImage); diff --git a/Source/Core/DolphinWX/ISOFile.h b/Source/Core/DolphinWX/ISOFile.h index 3893c01777..836b453714 100644 --- a/Source/Core/DolphinWX/ISOFile.h +++ b/Source/Core/DolphinWX/ISOFile.h @@ -21,6 +21,7 @@ namespace DiscIO enum class BlobType; enum class Country; enum class Language; +enum class Region; enum class Platform; } @@ -48,6 +49,7 @@ public: u16 GetRevision() const { return m_Revision; } const std::string& GetGameID() const { return m_game_id; } const std::string GetWiiFSPath() const; + DiscIO::Region GetRegion() const { return m_region; } DiscIO::Country GetCountry() const { return m_Country; } DiscIO::Platform GetPlatform() const { return m_Platform; } DiscIO::BlobType GetBlobType() const { return m_blob_type; } @@ -82,6 +84,7 @@ private: u64 m_FileSize; u64 m_VolumeSize; + DiscIO::Region m_region; DiscIO::Country m_Country; DiscIO::Platform m_Platform; DiscIO::BlobType m_blob_type;