Merge pull request #4170 from FearlessTobi/port-stupid-fixes
citra_qt: Backport some review fixes of Lioncash
This commit is contained in:
commit
2396e58ee4
|
@ -44,18 +44,15 @@ function(check_submodules_present)
|
||||||
endfunction()
|
endfunction()
|
||||||
check_submodules_present()
|
check_submodules_present()
|
||||||
|
|
||||||
|
|
||||||
configure_file(${CMAKE_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc
|
configure_file(${CMAKE_SOURCE_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||||
${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
||||||
COPYONLY)
|
COPYONLY)
|
||||||
|
|
||||||
if (ENABLE_COMPATIBILITY_LIST_DOWNLOAD AND NOT EXISTS ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
if (ENABLE_COMPATIBILITY_LIST_DOWNLOAD AND NOT EXISTS ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
||||||
message(STATUS "Downloading compatibility list for citra...")
|
message(STATUS "Downloading compatibility list for citra...")
|
||||||
file(DOWNLOAD
|
file(DOWNLOAD
|
||||||
https://api.citra-emu.org/gamedb/
|
https://api.citra-emu.org/gamedb/
|
||||||
"${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json" SHOW_PROGRESS)
|
"${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json" SHOW_PROGRESS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (NOT EXISTS ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
if (NOT EXISTS ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json)
|
||||||
file(WRITE ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json "")
|
file(WRITE ${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.json "")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -133,8 +133,8 @@ set(UIS
|
||||||
)
|
)
|
||||||
|
|
||||||
file(GLOB COMPAT_LIST
|
file(GLOB COMPAT_LIST
|
||||||
${CMAKE_BINARY_DIR}/dist/compatibility_list/compatibility_list.qrc
|
${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.json)
|
||||||
file(GLOB_RECURSE ICONS ${CMAKE_SOURCE_DIR}/dist/icons/*)
|
file(GLOB_RECURSE ICONS ${CMAKE_SOURCE_DIR}/dist/icons/*)
|
||||||
file(GLOB_RECURSE THEMES ${CMAKE_SOURCE_DIR}/dist/qt_themes/*)
|
file(GLOB_RECURSE THEMES ${CMAKE_SOURCE_DIR}/dist/qt_themes/*)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <cinttypes>
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
|
@ -443,12 +442,7 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id) {
|
||||||
Service::AM::GetTitleContentPath(Service::FS::MediaType::SDMC, program_id)));
|
Service::AM::GetTitleContentPath(Service::FS::MediaType::SDMC, program_id)));
|
||||||
open_update_location->setEnabled(0x0004000000000000 <= program_id &&
|
open_update_location->setEnabled(0x0004000000000000 <= program_id &&
|
||||||
program_id <= 0x00040000FFFFFFFF);
|
program_id <= 0x00040000FFFFFFFF);
|
||||||
auto it = std::find_if(
|
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
||||||
compatibility_list.begin(), compatibility_list.end(),
|
|
||||||
[program_id](const std::pair<std::string, std::pair<QString, QString>>& element) {
|
|
||||||
std::string pid = Common::StringFromFormat("%016" PRIX64, program_id);
|
|
||||||
return element.first == pid;
|
|
||||||
});
|
|
||||||
navigate_to_gamedb_entry->setVisible(it != compatibility_list.end());
|
navigate_to_gamedb_entry->setVisible(it != compatibility_list.end());
|
||||||
|
|
||||||
connect(open_save_location, &QAction::triggered, [this, program_id] {
|
connect(open_save_location, &QAction::triggered, [this, program_id] {
|
||||||
|
@ -537,7 +531,7 @@ void GameList::LoadCompatibilityList() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compat_list.size() == 0) {
|
if (compat_list.size() == 0) {
|
||||||
LOG_ERROR(Frontend, "Game compatibility list is empty");
|
LOG_WARNING(Frontend, "Game compatibility list is empty");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,9 +556,9 @@ void GameList::LoadCompatibilityList() {
|
||||||
for (const QJsonValue& value : ids) {
|
for (const QJsonValue& value : ids) {
|
||||||
QJsonObject object = value.toObject();
|
QJsonObject object = value.toObject();
|
||||||
QString id = object["id"].toString();
|
QString id = object["id"].toString();
|
||||||
compatibility_list.insert(
|
compatibility_list.emplace(
|
||||||
std::make_pair(id.toUpper().toStdString(),
|
id.toUpper().toStdString(),
|
||||||
std::make_pair(QString::number(compatibility), directory)));
|
std::make_pair(QString::number(compatibility), directory));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -688,12 +682,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
||||||
return update_smdh;
|
return update_smdh;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
auto it = std::find_if(
|
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
||||||
compatibility_list.begin(), compatibility_list.end(),
|
|
||||||
[program_id](const std::pair<std::string, std::pair<QString, QString>>& element) {
|
|
||||||
std::string pid = Common::StringFromFormat("%016" PRIX64, program_id);
|
|
||||||
return element.first == pid;
|
|
||||||
});
|
|
||||||
|
|
||||||
// The game list uses this as compatibility number for untested games
|
// The game list uses this as compatibility number for untested games
|
||||||
QString compatibility("99");
|
QString compatibility("99");
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPainter>
|
|
||||||
#include <QRunnable>
|
#include <QRunnable>
|
||||||
#include <QStandardItem>
|
#include <QStandardItem>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
@ -60,21 +59,15 @@ static QPixmap GetDefaultIcon(bool large) {
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static auto FindMatchingCompatibilityEntry(
|
||||||
* Creates a circle pixmap from a specified color
|
const std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list,
|
||||||
* @param color The color the pixmap shall have
|
u64 program_id) {
|
||||||
* @return QPixmap circle pixmap
|
return std::find_if(
|
||||||
*/
|
compatibility_list.begin(), compatibility_list.end(),
|
||||||
static QPixmap CreateCirclePixmapFromColor(const QColor& color) {
|
[program_id](const std::pair<std::string, std::pair<QString, QString>>& element) {
|
||||||
QPixmap circle_pixmap(16, 16);
|
std::string pid = fmt::format("{:016X}", program_id);
|
||||||
circle_pixmap.fill(Qt::transparent);
|
return element.first == pid;
|
||||||
|
});
|
||||||
QPainter painter(&circle_pixmap);
|
|
||||||
painter.setPen(color);
|
|
||||||
painter.setBrush(color);
|
|
||||||
painter.drawEllipse(0, 0, 15, 15);
|
|
||||||
|
|
||||||
return circle_pixmap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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<QString, CompatStatus> 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 {
|
class GameListItem : public QStandardItem {
|
||||||
public:
|
public:
|
||||||
// used to access type from item index
|
// used to access type from item index
|
||||||
|
@ -223,13 +198,29 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameListItemCompat : public GameListItem {
|
class GameListItemCompat : public GameListItem {
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(GameListItemCompat)
|
||||||
public:
|
public:
|
||||||
static const int CompatNumberRole = SortRole;
|
static const int CompatNumberRole = SortRole;
|
||||||
|
|
||||||
GameListItemCompat() = default;
|
GameListItemCompat() = default;
|
||||||
explicit GameListItemCompat(const QString compatiblity) {
|
explicit GameListItemCompat(const QString& compatiblity) {
|
||||||
setData(type(), TypeRole);
|
setData(type(), TypeRole);
|
||||||
|
|
||||||
|
struct CompatStatus {
|
||||||
|
QString color;
|
||||||
|
const char* text;
|
||||||
|
const char* tooltip;
|
||||||
|
};
|
||||||
|
// clang-format off
|
||||||
|
static const std::map<QString, CompatStatus> 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);
|
auto iterator = status_data.find(compatiblity);
|
||||||
if (iterator == status_data.end()) {
|
if (iterator == status_data.end()) {
|
||||||
LOG_WARNING(Frontend, "Invalid compatibility number {}", compatiblity.toStdString());
|
LOG_WARNING(Frontend, "Invalid compatibility number {}", compatiblity.toStdString());
|
||||||
|
@ -237,8 +228,8 @@ public:
|
||||||
}
|
}
|
||||||
CompatStatus status = iterator->second;
|
CompatStatus status = iterator->second;
|
||||||
setData(compatiblity, CompatNumberRole);
|
setData(compatiblity, CompatNumberRole);
|
||||||
setText(QCoreApplication::translate("GameList", status.text));
|
setText(QObject::tr(status.text));
|
||||||
setToolTip(QCoreApplication::translate("GameList", status.tooltip));
|
setToolTip(QObject::tr(status.tooltip));
|
||||||
setData(CreateCirclePixmapFromColor(status.color), Qt::DecorationRole);
|
setData(CreateCirclePixmapFromColor(status.color), Qt::DecorationRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#define QT_NO_OPENGL
|
#define QT_NO_OPENGL
|
||||||
#include <cinttypes>
|
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
|
@ -59,6 +58,7 @@
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
|
#include "game_list_p.h"
|
||||||
|
|
||||||
#ifdef USE_DISCORD_PRESENCE
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
#include "citra_qt/discord_impl.h"
|
#include "citra_qt/discord_impl.h"
|
||||||
|
@ -917,14 +917,9 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(
|
||||||
u64 program_id,
|
u64 program_id,
|
||||||
std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list) {
|
std::unordered_map<std::string, std::pair<QString, QString>>& compatibility_list) {
|
||||||
|
|
||||||
auto it = std::find_if(
|
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
||||||
compatibility_list.begin(), compatibility_list.end(),
|
|
||||||
[program_id](const std::pair<std::string, std::pair<QString, QString>>& element) {
|
|
||||||
std::string pid = Common::StringFromFormat("%016" PRIX64, program_id);
|
|
||||||
return element.first == pid;
|
|
||||||
});
|
|
||||||
|
|
||||||
QString directory = "";
|
QString directory;
|
||||||
|
|
||||||
if (it != compatibility_list.end())
|
if (it != compatibility_list.end())
|
||||||
directory = it->second.second;
|
directory = it->second.second;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <QPainter>
|
||||||
#include "citra_qt/util/util.h"
|
#include "citra_qt/util/util.h"
|
||||||
|
|
||||||
QFont GetMonospaceFont() {
|
QFont GetMonospaceFont() {
|
||||||
|
@ -24,3 +25,13 @@ QString ReadableByteSize(qulonglong size) {
|
||||||
.arg(size / std::pow(1024, digit_groups), 0, 'f', 1)
|
.arg(size / std::pow(1024, digit_groups), 0, 'f', 1)
|
||||||
.arg(units[digit_groups]);
|
.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;
|
||||||
|
}
|
||||||
|
|
|
@ -12,3 +12,10 @@ QFont GetMonospaceFont();
|
||||||
|
|
||||||
/// Convert a size in bytes into a readable format (KiB, MiB, etc.)
|
/// Convert a size in bytes into a readable format (KiB, MiB, etc.)
|
||||||
QString ReadableByteSize(qulonglong size);
|
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);
|
||||||
|
|
Reference in New Issue