diff --git a/Source/Core/DolphinWX/Cheats/CreateCodeDialog.cpp b/Source/Core/DolphinWX/Cheats/CreateCodeDialog.cpp index 5239a1817a..60c600702b 100644 --- a/Source/Core/DolphinWX/Cheats/CreateCodeDialog.cpp +++ b/Source/Core/DolphinWX/Cheats/CreateCodeDialog.cpp @@ -87,7 +87,7 @@ void CreateCodeDialog::PressOK(wxCommandEvent& ev) // pretty hacky - add the code to the gameini { - CISOProperties isoprops(SConfig::GetInstance().m_LastFilename, this); + CISOProperties isoprops(GameListItem(SConfig::GetInstance().m_LastFilename, std::unordered_map()), this); // add the code to the isoproperties arcode list arCodes->push_back(new_cheat); // save the gameini diff --git a/Source/Core/DolphinWX/GameListCtrl.cpp b/Source/Core/DolphinWX/GameListCtrl.cpp index c22992df97..8d5ed1d61a 100644 --- a/Source/Core/DolphinWX/GameListCtrl.cpp +++ b/Source/Core/DolphinWX/GameListCtrl.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -83,13 +84,10 @@ static int CompareGameListItems(const GameListItem* iso1, const GameListItem* is sortData = -sortData; } - DiscIO::IVolume::ELanguage languageOne = SConfig::GetInstance().GetCurrentLanguage(iso1->GetPlatform() != DiscIO::IVolume::GAMECUBE_DISC); - DiscIO::IVolume::ELanguage languageOther = SConfig::GetInstance().GetCurrentLanguage(iso2->GetPlatform() != DiscIO::IVolume::GAMECUBE_DISC); - switch (sortData) { case CGameListCtrl::COLUMN_TITLE: - if (!strcasecmp(iso1->GetName(languageOne).c_str(), iso2->GetName(languageOther).c_str())) + if (!strcasecmp(iso1->GetName().c_str(), iso2->GetName().c_str())) { if (iso1->GetUniqueID() != iso2->GetUniqueID()) return t * (iso1->GetUniqueID() > iso2->GetUniqueID() ? 1 : -1); @@ -98,8 +96,7 @@ static int CompareGameListItems(const GameListItem* iso1, const GameListItem* is if (iso1->GetDiscNumber() != iso2->GetDiscNumber()) return t * (iso1->GetDiscNumber() > iso2->GetDiscNumber() ? 1 : -1); } - return strcasecmp(iso1->GetName(languageOne).c_str(), - iso2->GetName(languageOther).c_str()) * t; + return strcasecmp(iso1->GetName().c_str(), iso2->GetName().c_str()) * t; case CGameListCtrl::COLUMN_MAKER: return strcasecmp(iso1->GetCompany().c_str(), iso2->GetCompany().c_str()) * t; case CGameListCtrl::COLUMN_ID: @@ -388,46 +385,6 @@ void CGameListCtrl::InsertItemInReportView(long _Index) wxString name = StrToWxStr(rISOFile.GetName()); - // Attempt to load game titles from titles.txt - // http://www.gametdb.com/Wii/Downloads - std::ifstream titlestxt; - OpenFStream(titlestxt, File::GetUserPath(D_LOAD_IDX) + "titles.txt", std::ios::in); - - if (!titlestxt.is_open()) - { - OpenFStream(titlestxt, File::GetUserPath(D_LOAD_IDX) + "wiitdb.txt", std::ios::in); - } - - if (titlestxt.is_open() && rISOFile.GetUniqueID().size() > 3) - { - while (!titlestxt.eof()) - { - std::string line; - - if (!std::getline(titlestxt, line) && titlestxt.eof()) - break; - - const size_t equals_index = line.find('='); - std::string game_id = rISOFile.GetUniqueID(); - - // Ignore publisher ID for WAD files - if (rISOFile.GetPlatform() == DiscIO::IVolume::WII_WAD) - game_id.erase(game_id.size() - 2); - - if (line.substr(0, equals_index - 1) == game_id) - { - name = StrToWxStr(StripSpaces(line.substr(equals_index + 1))); - break; - } - } - titlestxt.close(); - } - - std::string title; - IniFile gameini = SConfig::LoadGameIni(rISOFile.GetUniqueID(), rISOFile.GetRevision()); - if (gameini.GetIfExists("EmuState", "Title", &title)) - name = StrToWxStr(title); - int disc_number = rISOFile.GetDiscNumber() + 1; if (disc_number > 1 && name.Lower().find(wxString::Format("disc %i", disc_number)) == std::string::npos && name.Lower().find(wxString::Format("disc%i", disc_number)) == std::string::npos) @@ -483,6 +440,28 @@ void CGameListCtrl::ScanForISOs() { ClearIsoFiles(); + // Load custom game titles from titles.txt + // http://www.gametdb.com/Wii/Downloads + std::unordered_map custom_title_map; + std::ifstream titlestxt; + OpenFStream(titlestxt, File::GetUserPath(D_LOAD_IDX) + "titles.txt", std::ios::in); + + if (!titlestxt.is_open()) + OpenFStream(titlestxt, File::GetUserPath(D_LOAD_IDX) + "wiitdb.txt", std::ios::in); + + if (titlestxt.is_open()) + { + std::string line; + while (!titlestxt.eof() && std::getline(titlestxt, line)) + { + const size_t equals_index = line.find('='); + if (equals_index != std::string::npos) + custom_title_map.emplace(StripSpaces(line.substr(0, equals_index)), + StripSpaces(line.substr(equals_index + 1))); + } + titlestxt.close(); + } + std::vector Extensions; if (SConfig::GetInstance().m_ListGC) @@ -529,7 +508,7 @@ void CGameListCtrl::ScanForISOs() if (dialog.WasCancelled()) break; - auto iso_file = std::make_unique(rFilenames[i]); + auto iso_file = std::make_unique(rFilenames[i], custom_title_map); if (iso_file->IsValid()) { @@ -624,7 +603,7 @@ void CGameListCtrl::ScanForISOs() for (const auto& drive : drives) { - auto gli = std::make_unique(drive); + auto gli = std::make_unique(drive, custom_title_map); if (gli->IsValid()) m_ISOFiles.push_back(gli.release()); @@ -1035,7 +1014,7 @@ void CGameListCtrl::OnProperties(wxCommandEvent& WXUNUSED (event)) if (!iso) return; - CISOProperties* ISOProperties = new CISOProperties(iso->GetFileName(), this); + CISOProperties* ISOProperties = new CISOProperties(*iso, this); ISOProperties->Show(); } diff --git a/Source/Core/DolphinWX/ISOFile.cpp b/Source/Core/DolphinWX/ISOFile.cpp index 026dda93d8..28051d0fb0 100644 --- a/Source/Core/DolphinWX/ISOFile.cpp +++ b/Source/Core/DolphinWX/ISOFile.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -62,7 +63,7 @@ static std::string GetLanguageString(DiscIO::IVolume::ELanguage language, std::m return ""; } -GameListItem::GameListItem(const std::string& _rFileName) +GameListItem::GameListItem(const std::string& _rFileName, const std::unordered_map& custom_titles) : m_FileName(_rFileName) , m_emu_state(0) , m_FileSize(0) @@ -73,6 +74,7 @@ GameListItem::GameListItem(const std::string& _rFileName) , m_ImageWidth(0) , m_ImageHeight(0) , m_disc_number(0) + , m_has_custom_name(false) { if (LoadFromCache()) { @@ -130,6 +132,24 @@ GameListItem::GameListItem(const std::string& _rFileName) IniFile ini = SConfig::LoadGameIni(m_UniqueID, m_Revision); ini.GetIfExists("EmuState", "EmulationStateId", &m_emu_state); ini.GetIfExists("EmuState", "EmulationIssues", &m_issues); + m_has_custom_name = ini.GetIfExists("EmuState", "Title", &m_custom_name); + + if (!m_has_custom_name) + { + std::string game_id = m_UniqueID; + + // Ignore publisher ID for WAD files + if (m_Platform == DiscIO::IVolume::WII_WAD) + game_id.erase(game_id.size() - 2); + + auto end = custom_titles.end(); + auto it = custom_titles.find(game_id); + if (it != end) + { + m_custom_name = it->second; + m_has_custom_name = true; + } + } } if (!IsValid() && IsElfOrDol()) @@ -200,12 +220,10 @@ void GameListItem::DoState(PointerWrap &p) bool GameListItem::IsElfOrDol() const { - const std::string name = GetName(); - const size_t pos = name.rfind('.'); - + const size_t pos = m_FileName.rfind('.'); if (pos != std::string::npos) { - std::string ext = name.substr(pos); + std::string ext = m_FileName.substr(pos); std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); return ext == ".elf" || ext == ".dol"; @@ -290,17 +308,18 @@ std::string GameListItem::GetName(DiscIO::IVolume::ELanguage language) const std::string GameListItem::GetName() const { + if (m_has_custom_name) + return m_custom_name; + bool wii = m_Platform != DiscIO::IVolume::GAMECUBE_DISC; std::string name = GetName(SConfig::GetInstance().GetCurrentLanguage(wii)); - if (name.empty()) - { - std::string ext; + if (!name.empty()) + return name; - // No usable name, return filename (better than nothing) - SplitPath(GetFileName(), nullptr, &name, &ext); - return name + ext; - } - return name; + // No usable name, return filename (better than nothing) + std::string ext; + SplitPath(GetFileName(), nullptr, &name, &ext); + return name + ext; } std::vector GameListItem::GetLanguages() const diff --git a/Source/Core/DolphinWX/ISOFile.h b/Source/Core/DolphinWX/ISOFile.h index 4ede1a11c9..d0e89e7a7e 100644 --- a/Source/Core/DolphinWX/ISOFile.h +++ b/Source/Core/DolphinWX/ISOFile.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include @@ -17,10 +18,10 @@ #endif class PointerWrap; -class GameListItem : NonCopyable +class GameListItem { public: - GameListItem(const std::string& _rFileName); + GameListItem(const std::string& _rFileName, const std::unordered_map& custom_titles); ~GameListItem(); bool IsValid() const {return m_Valid;} @@ -78,6 +79,9 @@ private: int m_ImageWidth, m_ImageHeight; u8 m_disc_number; + std::string m_custom_name; + bool m_has_custom_name; + bool LoadFromCache(); void SaveToCache(); diff --git a/Source/Core/DolphinWX/ISOProperties.cpp b/Source/Core/DolphinWX/ISOProperties.cpp index 3f98d301a6..38487227b6 100644 --- a/Source/Core/DolphinWX/ISOProperties.cpp +++ b/Source/Core/DolphinWX/ISOProperties.cpp @@ -99,11 +99,12 @@ BEGIN_EVENT_TABLE(CISOProperties, wxDialog) EVT_CHOICE(ID_LANG, CISOProperties::OnChangeBannerLang) END_EVENT_TABLE() -CISOProperties::CISOProperties(const std::string& fileName, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) +CISOProperties::CISOProperties(const GameListItem& game_list_item, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style) : wxDialog(parent, id, title, position, size, style) + , OpenGameListItem(game_list_item) { // Load ISO data - OpenISO = DiscIO::CreateVolumeFromFilename(fileName); + OpenISO = DiscIO::CreateVolumeFromFilename(OpenGameListItem.GetFileName()); // Is it really necessary to use GetTitleID if GetUniqueID fails? game_id = OpenISO->GetUniqueID(); @@ -122,8 +123,6 @@ CISOProperties::CISOProperties(const std::string& fileName, wxWindow* parent, wx GameIniLocal = SConfig::LoadLocalGameIni(game_id, OpenISO->GetRevision()); // Setup GUI - OpenGameListItem = new GameListItem(fileName); - bRefreshList = false; CreateGUIControls(); @@ -191,7 +190,7 @@ CISOProperties::CISOProperties(const std::string& fileName, wxWindow* parent, wx bool wii = OpenISO->GetVolumeType() != DiscIO::IVolume::GAMECUBE_DISC; ChangeBannerDetails(SConfig::GetInstance().GetCurrentLanguage(wii)); - m_Banner->SetBitmap(OpenGameListItem->GetBitmap()); + m_Banner->SetBitmap(OpenGameListItem.GetBitmap()); m_Banner->Bind(wxEVT_RIGHT_DOWN, &CISOProperties::RightClickOnBanner, this); // Filesystem browser/dumper @@ -205,7 +204,7 @@ CISOProperties::CISOProperties(const std::string& fileName, wxWindow* parent, wx { for (u32 i = 0; i < 0xFFFFFFFF; i++) // yes, technically there can be OVER NINE THOUSAND partitions... { - std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(fileName, group, i)); + std::unique_ptr volume(DiscIO::CreateVolumeFromFilename(OpenGameListItem.GetFileName(), group, i)); if (volume != nullptr) { std::unique_ptr file_system(DiscIO::CreateFileSystem(volume.get())); @@ -247,7 +246,6 @@ CISOProperties::~CISOProperties() { if (OpenISO->GetVolumeType() == DiscIO::IVolume::GAMECUBE_DISC && pFileSystem) delete pFileSystem; - delete OpenGameListItem; delete OpenISO; } @@ -497,7 +495,7 @@ void CISOProperties::CreateGUIControls() bool wii = OpenISO->GetVolumeType() != DiscIO::IVolume::GAMECUBE_DISC; DiscIO::IVolume::ELanguage preferred_language = SConfig::GetInstance().GetCurrentLanguage(wii); - std::vector languages = OpenGameListItem->GetLanguages(); + std::vector languages = OpenGameListItem.GetLanguages(); int preferred_language_index = 0; for (size_t i = 0; i < languages.size(); ++i) { @@ -1248,7 +1246,7 @@ void CISOProperties::OnComputeMD5Sum(wxCommandEvent& WXUNUSED (event)) u64 read_offset = 0; md5_context ctx; - File::IOFile file(OpenGameListItem->GetFileName(), "rb"); + File::IOFile file(OpenGameListItem.GetFileName(), "rb"); u64 game_size = file.GetSize(); wxProgressDialog progressDialog( @@ -1497,14 +1495,14 @@ void CISOProperties::ActionReplayButtonClicked(wxCommandEvent& event) void CISOProperties::OnChangeBannerLang(wxCommandEvent& event) { - ChangeBannerDetails(OpenGameListItem->GetLanguages()[event.GetSelection()]); + ChangeBannerDetails(OpenGameListItem.GetLanguages()[event.GetSelection()]); } void CISOProperties::ChangeBannerDetails(DiscIO::IVolume::ELanguage language) { - wxString const name = StrToWxStr(OpenGameListItem->GetName(language)); - wxString const comment = StrToWxStr(OpenGameListItem->GetDescription(language)); - wxString const maker = StrToWxStr(OpenGameListItem->GetCompany()); + wxString const name = StrToWxStr(OpenGameListItem.GetName(language)); + wxString const comment = StrToWxStr(OpenGameListItem.GetDescription(language)); + wxString const maker = StrToWxStr(OpenGameListItem.GetCompany()); // Updates the information shown in the window m_Name->SetValue(name); @@ -1512,8 +1510,8 @@ void CISOProperties::ChangeBannerDetails(DiscIO::IVolume::ELanguage language) m_Maker->SetValue(maker);//dev too std::string filename, extension; - SplitPath(OpenGameListItem->GetFileName(), nullptr, &filename, &extension); + SplitPath(OpenGameListItem.GetFileName(), nullptr, &filename, &extension); // Also sets the window's title SetTitle(StrToWxStr(StringFromFormat("%s%s: %s - ", filename.c_str(), - extension.c_str(), OpenGameListItem->GetUniqueID().c_str())) + name); + extension.c_str(), OpenGameListItem.GetUniqueID().c_str())) + name); } diff --git a/Source/Core/DolphinWX/ISOProperties.h b/Source/Core/DolphinWX/ISOProperties.h index c325c44572..fd1735830a 100644 --- a/Source/Core/DolphinWX/ISOProperties.h +++ b/Source/Core/DolphinWX/ISOProperties.h @@ -19,6 +19,7 @@ #include "DiscIO/Volume.h" #include "DiscIO/VolumeCreator.h" #include "DolphinWX/ARCodeAddEdit.h" +#include "DolphinWX/ISOFile.h" #include "DolphinWX/PatchAddEdit.h" class GameListItem; @@ -58,7 +59,7 @@ struct PHackData class CISOProperties : public wxDialog { public: - CISOProperties(const std::string& fileName, + CISOProperties(const GameListItem& game_list_item, wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Properties"), @@ -215,7 +216,7 @@ private: void SetRefresh(wxCommandEvent& event); void OnChangeBannerLang(wxCommandEvent& event); - GameListItem* OpenGameListItem; + const GameListItem OpenGameListItem; typedef std::vector::iterator fileIter;