diff --git a/CMakeLists.txt b/CMakeLists.txt index 28d6dc3f5..46de712f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,18 +44,15 @@ function(check_submodules_present) endfunction() check_submodules_present() - configure_file(${CMAKE_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc COPYONLY) - if (ENABLE_COMPATIBILITY_LIST_DOWNLOAD AND NOT EXISTS ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json) message(STATUS "Downloading compatibility list for citra...") file(DOWNLOAD https://api.citra-emu.org/gamedb/ "${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json" SHOW_PROGRESS) endif() - if (NOT EXISTS ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json) file(WRITE ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json "") endif() diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index c459c1774..409136809 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -133,8 +133,8 @@ set(UIS ) file(GLOB COMPAT_LIST - ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc - ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json) + ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc + ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json) file(GLOB_RECURSE ICONS ${CMAKE_SOURCE_DIR}/dist/icons/*) file(GLOB_RECURSE THEMES ${CMAKE_SOURCE_DIR}/dist/qt_themes/*) diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp index 6ec24e8eb..e26c1032e 100644 --- a/src/citra_qt/game_list.cpp +++ b/src/citra_qt/game_list.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include #include #include #include @@ -443,12 +442,7 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id) { Service::AM::GetTitleContentPath(Service::FS::MediaType::SDMC, program_id))); open_update_location->setEnabled(0x0004000000000000 <= program_id && program_id <= 0x00040000FFFFFFFF); - auto it = std::find_if( - compatibility_list.begin(), compatibility_list.end(), - [program_id](const std::pair>& element) { - std::string pid = Common::StringFromFormat("%016" PRIX64, program_id); - return element.first == pid; - }); + auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); navigate_to_gamedb_entry->setVisible(it != compatibility_list.end()); connect(open_save_location, &QAction::triggered, [this, program_id] { @@ -537,7 +531,7 @@ void GameList::LoadCompatibilityList() { } if (compat_list.size() == 0) { - LOG_ERROR(Frontend, "Game compatibility list is empty"); + LOG_WARNING(Frontend, "Game compatibility list is empty"); return; } @@ -562,9 +556,9 @@ void GameList::LoadCompatibilityList() { for (const QJsonValue& value : ids) { QJsonObject object = value.toObject(); QString id = object["id"].toString(); - compatibility_list.insert( - std::make_pair(id.toUpper().toStdString(), - std::make_pair(QString::number(compatibility), directory))); + compatibility_list.emplace( + id.toUpper().toStdString(), + std::make_pair(QString::number(compatibility), directory)); } } } @@ -688,12 +682,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign return update_smdh; }(); - auto it = std::find_if( - compatibility_list.begin(), compatibility_list.end(), - [program_id](const std::pair>& element) { - std::string pid = Common::StringFromFormat("%016" PRIX64, program_id); - return element.first == pid; - }); + auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); // The game list uses this as compatibility number for untested games QString compatibility("99"); diff --git a/src/citra_qt/game_list_p.h b/src/citra_qt/game_list_p.h index aa8480eb5..925757ea8 100644 --- a/src/citra_qt/game_list_p.h +++ b/src/citra_qt/game_list_p.h @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -60,21 +59,15 @@ static QPixmap GetDefaultIcon(bool large) { return icon; } -/** - * Creates a circle pixmap from a specified color - * @param color The color the pixmap shall have - * @return QPixmap circle pixmap - */ -static QPixmap CreateCirclePixmapFromColor(const QColor& color) { - QPixmap circle_pixmap(16, 16); - circle_pixmap.fill(Qt::transparent); - - QPainter painter(&circle_pixmap); - painter.setPen(color); - painter.setBrush(color); - painter.drawEllipse(0, 0, 15, 15); - - return circle_pixmap; +static auto FindMatchingCompatibilityEntry( + const std::unordered_map>& compatibility_list, + u64 program_id) { + return std::find_if( + compatibility_list.begin(), compatibility_list.end(), + [program_id](const std::pair>& element) { + std::string pid = fmt::format("{:016X}", program_id); + return element.first == pid; + }); } /** @@ -120,24 +113,6 @@ static QString GetRegionFromSMDH(const Loader::SMDH& smdh) { } } -struct CompatStatus { - QString color; - const char* text; - const char* tooltip; -}; - -// When this is put in a class, MSVS builds crash when closing Citra -// clang-format off -const static inline std::map status_data = { -{ "0", { "#5c93ed", QT_TRANSLATE_NOOP("GameList", "Perfect"), QT_TRANSLATE_NOOP("GameList", "Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without\nany workarounds needed.") } }, -{ "1", { "#47d35c", QT_TRANSLATE_NOOP("GameList", "Great"), QT_TRANSLATE_NOOP("GameList", "Game functions with minor graphical or audio glitches and is playable from start to finish. May require some\nworkarounds.") } }, -{ "2", { "#94b242", QT_TRANSLATE_NOOP("GameList", "Okay"), QT_TRANSLATE_NOOP("GameList", "Game functions with major graphical or audio glitches, but game is playable from start to finish with\nworkarounds.") } }, -{ "3", { "#f2d624", QT_TRANSLATE_NOOP("GameList", "Bad"), QT_TRANSLATE_NOOP("GameList", "Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches\neven with workarounds.") } }, -{ "4", { "#FF0000", QT_TRANSLATE_NOOP("GameList", "Intro/Menu"), QT_TRANSLATE_NOOP("GameList", "Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start\nScreen.") } }, -{ "5", { "#828282", QT_TRANSLATE_NOOP("GameList", "Won't Boot"), QT_TRANSLATE_NOOP("GameList", "The game crashes when attempting to startup.") } }, -{ "99",{ "#000000", QT_TRANSLATE_NOOP("GameList", "Not Tested"), QT_TRANSLATE_NOOP("GameList", "The game has not yet been tested.") } }, }; -// clang-format on - class GameListItem : public QStandardItem { public: // used to access type from item index @@ -223,13 +198,29 @@ public: }; class GameListItemCompat : public GameListItem { + Q_DECLARE_TR_FUNCTIONS(GameListItemCompat) public: static const int CompatNumberRole = SortRole; - GameListItemCompat() = default; - explicit GameListItemCompat(const QString compatiblity) { + explicit GameListItemCompat(const QString& compatiblity) { setData(type(), TypeRole); + struct CompatStatus { + QString color; + const char* text; + const char* tooltip; + }; + // clang-format off + static const std::map status_data = { + {"0", {"#5c93ed", QT_TR_NOOP("Perfect"), QT_TR_NOOP("Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without\nany workarounds needed.")}}, + {"1", {"#47d35c", QT_TR_NOOP("Great"), QT_TR_NOOP("Game functions with minor graphical or audio glitches and is playable from start to finish. May require some\nworkarounds.")}}, + {"2", {"#94b242", QT_TR_NOOP("Okay"), QT_TR_NOOP("Game functions with major graphical or audio glitches, but game is playable from start to finish with\nworkarounds.")}}, + {"3", {"#f2d624", QT_TR_NOOP("Bad"), QT_TR_NOOP("Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches\neven with workarounds.")}}, + {"4", {"#ff0000", QT_TR_NOOP("Intro/Menu"), QT_TR_NOOP("Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start\nScreen.")}}, + {"5", {"#828282", QT_TR_NOOP("Won't Boot"), QT_TR_NOOP("The game crashes when attempting to startup.")}}, + {"99", {"#000000", QT_TR_NOOP("Not Tested"), QT_TR_NOOP("The game has not yet been tested.")}}}; + // clang-format on + auto iterator = status_data.find(compatiblity); if (iterator == status_data.end()) { LOG_WARNING(Frontend, "Invalid compatibility number {}", compatiblity.toStdString()); @@ -237,8 +228,8 @@ public: } CompatStatus status = iterator->second; setData(compatiblity, CompatNumberRole); - setText(QCoreApplication::translate("GameList", status.text)); - setToolTip(QCoreApplication::translate("GameList", status.tooltip)); + setText(QObject::tr(status.text)); + setToolTip(QObject::tr(status.tooltip)); setData(CreateCirclePixmapFromColor(status.color), Qt::DecorationRole); } diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 8ccc7c252..e95cf3c2d 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp @@ -7,7 +7,6 @@ #include #include #define QT_NO_OPENGL -#include #include #include #include @@ -59,6 +58,7 @@ #include "core/loader/loader.h" #include "core/movie.h" #include "core/settings.h" +#include "game_list_p.h" #ifdef USE_DISCORD_PRESENCE #include "citra_qt/discord_impl.h" @@ -917,14 +917,9 @@ void GMainWindow::OnGameListNavigateToGamedbEntry( u64 program_id, std::unordered_map>& compatibility_list) { - auto it = std::find_if( - compatibility_list.begin(), compatibility_list.end(), - [program_id](const std::pair>& element) { - std::string pid = Common::StringFromFormat("%016" PRIX64, program_id); - return element.first == pid; - }); + auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); - QString directory = ""; + QString directory; if (it != compatibility_list.end()) directory = it->second.second; diff --git a/src/citra_qt/util/util.cpp b/src/citra_qt/util/util.cpp index 02be92bbd..05df65da5 100644 --- a/src/citra_qt/util/util.cpp +++ b/src/citra_qt/util/util.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "citra_qt/util/util.h" QFont GetMonospaceFont() { @@ -24,3 +25,13 @@ QString ReadableByteSize(qulonglong size) { .arg(size / std::pow(1024, digit_groups), 0, 'f', 1) .arg(units[digit_groups]); } + +QPixmap CreateCirclePixmapFromColor(const QColor& color) { + QPixmap circle_pixmap(16, 16); + circle_pixmap.fill(Qt::transparent); + QPainter painter(&circle_pixmap); + painter.setPen(color); + painter.setBrush(color); + painter.drawEllipse(0, 0, 15, 15); + return circle_pixmap; +} diff --git a/src/citra_qt/util/util.h b/src/citra_qt/util/util.h index ab443ef9b..e6790f260 100644 --- a/src/citra_qt/util/util.h +++ b/src/citra_qt/util/util.h @@ -12,3 +12,10 @@ QFont GetMonospaceFont(); /// Convert a size in bytes into a readable format (KiB, MiB, etc.) QString ReadableByteSize(qulonglong size); + +/** + * Creates a circle pixmap from a specified color + * @param color The color the pixmap shall have + * @return QPixmap circle pixmap + */ +QPixmap CreateCirclePixmapFromColor(const QColor& color);