mirror of
https://github.com/Lime3DS/Lime3DS
synced 2024-12-27 01:22:37 -06:00
Merge pull request #3463 from FearlessTobi/game-list-compat
citra-qt: Show Game Compatibility within Citra
This commit is contained in:
commit
a2ab91fa31
11 changed files with 153 additions and 11 deletions
|
@ -20,7 +20,7 @@ echo y | sh cmake-3.10.1-Linux-x86_64.sh --prefix=cmake
|
||||||
export PATH=/citra/cmake/cmake-3.10.1-Linux-x86_64/bin:$PATH
|
export PATH=/citra/cmake/cmake-3.10.1-Linux-x86_64/bin:$PATH
|
||||||
|
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"}
|
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
|
||||||
make -j4
|
make -j4
|
||||||
|
|
||||||
ctest -VV -C Release
|
ctest -VV -C Release
|
||||||
|
|
|
@ -11,7 +11,7 @@ echo y | sh cmake-3.10.1-Linux-x86_64.sh --prefix=cmake
|
||||||
export PATH=/citra/cmake/cmake-3.10.1-Linux-x86_64/bin:$PATH
|
export PATH=/citra/cmake/cmake-3.10.1-Linux-x86_64/bin:$PATH
|
||||||
|
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"}
|
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/lib/ccache/gcc -DCMAKE_CXX_COMPILER=/usr/lib/ccache/g++ -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
|
||||||
make -j4
|
make -j4
|
||||||
|
|
||||||
ctest -VV -C Release
|
ctest -VV -C Release
|
||||||
|
|
|
@ -7,7 +7,7 @@ export Qt5_DIR=$(brew --prefix)/opt/qt5
|
||||||
export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||||
|
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"}
|
cmake .. -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h" -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${ENABLE_COMPATIBILITY_REPORTING:-"OFF"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
|
||||||
make -j4
|
make -j4
|
||||||
|
|
||||||
ctest -VV -C Release
|
ctest -VV -C Release
|
||||||
|
|
|
@ -40,6 +40,22 @@ function(check_submodules_present)
|
||||||
endfunction()
|
endfunction()
|
||||||
check_submodules_present()
|
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/titleid/
|
||||||
|
"${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()
|
||||||
|
|
||||||
# Detect current compilation architecture and create standard definitions
|
# Detect current compilation architecture and create standard definitions
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,9 @@ before_build:
|
||||||
$COMPAT = if ($env:ENABLE_COMPATIBILITY_REPORTING -eq $null) {0} else {$env:ENABLE_COMPATIBILITY_REPORTING}
|
$COMPAT = if ($env:ENABLE_COMPATIBILITY_REPORTING -eq $null) {0} else {$env:ENABLE_COMPATIBILITY_REPORTING}
|
||||||
if ($env:BUILD_TYPE -eq 'msvc') {
|
if ($env:BUILD_TYPE -eq 'msvc') {
|
||||||
# redirect stderr and change the exit code to prevent powershell from cancelling the build if cmake prints a warning
|
# redirect stderr and change the exit code to prevent powershell from cancelling the build if cmake prints a warning
|
||||||
cmd /C 'cmake -G "Visual Studio 15 2017 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} .. 2>&1 && exit 0'
|
cmd /C 'cmake -G "Visual Studio 15 2017 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON .. 2>&1 && exit 0'
|
||||||
} else {
|
} else {
|
||||||
C:\msys64\usr\bin\bash.exe -lc "cmake -G 'MSYS Makefiles' -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} .. 2>&1"
|
C:\msys64\usr\bin\bash.exe -lc "cmake -G 'MSYS Makefiles' -DCMAKE_BUILD_TYPE=Release -DENABLE_QT_TRANSLATION=ON -DCITRA_ENABLE_COMPATIBILITY_REPORTING=${COMPAT} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON .. 2>&1"
|
||||||
}
|
}
|
||||||
- cd ..
|
- cd ..
|
||||||
|
|
||||||
|
|
5
dist/compatibility_list/compatibility_list.qrc
vendored
Normal file
5
dist/compatibility_list/compatibility_list.qrc
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<RCC>
|
||||||
|
<qresource prefix="compatibility_list">
|
||||||
|
<file>compatibility_list.json</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
|
@ -85,6 +85,9 @@ set(UIS
|
||||||
compatdb.ui
|
compatdb.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
|
file(GLOB COMPAT_LIST
|
||||||
|
${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 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/*)
|
||||||
|
|
||||||
|
@ -125,6 +128,7 @@ endif()
|
||||||
|
|
||||||
target_sources(citra-qt
|
target_sources(citra-qt
|
||||||
PRIVATE
|
PRIVATE
|
||||||
|
${COMPAT_LIST}
|
||||||
${ICONS}
|
${ICONS}
|
||||||
${THEMES}
|
${THEMES}
|
||||||
${UI_HDRS}
|
${UI_HDRS}
|
||||||
|
|
|
@ -2,11 +2,14 @@
|
||||||
// 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>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
|
@ -227,6 +230,7 @@ GameList::GameList(GMainWindow* parent) : QWidget{parent} {
|
||||||
|
|
||||||
item_model->insertColumns(0, COLUMN_COUNT);
|
item_model->insertColumns(0, COLUMN_COUNT);
|
||||||
item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, "Name");
|
item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, "Name");
|
||||||
|
item_model->setHeaderData(COLUMN_COMPATIBILITY, Qt::Horizontal, "Compatibility");
|
||||||
item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, "File type");
|
item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, "File type");
|
||||||
item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, "Size");
|
item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, "Size");
|
||||||
|
|
||||||
|
@ -337,6 +341,39 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
|
||||||
context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
|
context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameList::LoadCompatibilityList() {
|
||||||
|
QFile compat_list{":compatibility_list/compatibility_list.json"};
|
||||||
|
|
||||||
|
if (!compat_list.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
|
NGLOG_ERROR(Frontend, "Unable to open game compatibility list");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compat_list.size() == 0) {
|
||||||
|
NGLOG_ERROR(Frontend, "Game compatibility list is empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QByteArray content = compat_list.readAll();
|
||||||
|
if (content.isEmpty()) {
|
||||||
|
NGLOG_ERROR(Frontend, "Unable to completely read game compatibility list");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString string_content = content;
|
||||||
|
QJsonDocument json = QJsonDocument::fromJson(string_content.toUtf8());
|
||||||
|
QJsonObject list = json.object();
|
||||||
|
QStringList game_ids = list.keys();
|
||||||
|
for (QString id : game_ids) {
|
||||||
|
QJsonObject game = list[id].toObject();
|
||||||
|
|
||||||
|
if (game.contains("compatibility") && game["compatibility"].isString()) {
|
||||||
|
QString compatibility = game["compatibility"].toString();
|
||||||
|
compatibility_list.insert(std::make_pair(id.toUpper().toStdString(), compatibility));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
|
void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
|
||||||
if (!FileUtil::Exists(dir_path.toStdString()) ||
|
if (!FileUtil::Exists(dir_path.toStdString()) ||
|
||||||
!FileUtil::IsDirectory(dir_path.toStdString())) {
|
!FileUtil::IsDirectory(dir_path.toStdString())) {
|
||||||
|
@ -351,7 +388,7 @@ void GameList::PopulateAsync(const QString& dir_path, bool deep_scan) {
|
||||||
|
|
||||||
emit ShouldCancelWorker();
|
emit ShouldCancelWorker();
|
||||||
|
|
||||||
GameListWorker* worker = new GameListWorker(dir_path, deep_scan);
|
GameListWorker* worker = new GameListWorker(dir_path, deep_scan, compatibility_list);
|
||||||
|
|
||||||
connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection);
|
connect(worker, &GameListWorker::EntryReady, this, &GameList::AddEntry, Qt::QueuedConnection);
|
||||||
connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating,
|
connect(worker, &GameListWorker::Finished, this, &GameList::DonePopulating,
|
||||||
|
@ -436,8 +473,21 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign
|
||||||
return update_smdh;
|
return update_smdh;
|
||||||
}();
|
}();
|
||||||
|
|
||||||
|
auto it = std::find_if(compatibility_list.begin(), compatibility_list.end(),
|
||||||
|
[program_id](const std::pair<std::string, 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
|
||||||
|
QString compatibility("99");
|
||||||
|
if (it != compatibility_list.end())
|
||||||
|
compatibility = it->second;
|
||||||
|
|
||||||
emit EntryReady({
|
emit EntryReady({
|
||||||
new GameListItemPath(QString::fromStdString(physical_name), smdh, program_id),
|
new GameListItemPath(QString::fromStdString(physical_name), smdh, program_id),
|
||||||
|
new GameListItemCompat(compatibility),
|
||||||
new GameListItem(
|
new GameListItem(
|
||||||
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
|
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))),
|
||||||
new GameListItemSize(FileUtil::GetSize(physical_name)),
|
new GameListItemSize(FileUtil::GetSize(physical_name)),
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -29,6 +30,7 @@ class GameList : public QWidget {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
COLUMN_NAME,
|
COLUMN_NAME,
|
||||||
|
COLUMN_COMPATIBILITY,
|
||||||
COLUMN_FILE_TYPE,
|
COLUMN_FILE_TYPE,
|
||||||
COLUMN_SIZE,
|
COLUMN_SIZE,
|
||||||
COLUMN_COUNT, // Number of columns
|
COLUMN_COUNT, // Number of columns
|
||||||
|
@ -68,6 +70,7 @@ public:
|
||||||
void setFilterFocus();
|
void setFilterFocus();
|
||||||
void setFilterVisible(bool visibility);
|
void setFilterVisible(bool visibility);
|
||||||
|
|
||||||
|
void LoadCompatibilityList();
|
||||||
void PopulateAsync(const QString& dir_path, bool deep_scan);
|
void PopulateAsync(const QString& dir_path, bool deep_scan);
|
||||||
|
|
||||||
void SaveInterfaceLayout();
|
void SaveInterfaceLayout();
|
||||||
|
@ -100,6 +103,7 @@ private:
|
||||||
QStandardItemModel* item_model = nullptr;
|
QStandardItemModel* item_model = nullptr;
|
||||||
GameListWorker* current_worker = nullptr;
|
GameListWorker* current_worker = nullptr;
|
||||||
QFileSystemWatcher* watcher = nullptr;
|
QFileSystemWatcher* watcher = nullptr;
|
||||||
|
std::unordered_map<std::string, QString> compatibility_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(GameListOpenTarget);
|
Q_DECLARE_METATYPE(GameListOpenTarget);
|
||||||
|
|
|
@ -5,11 +5,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <map>
|
||||||
|
#include <unordered_map>
|
||||||
#include <QImage>
|
#include <QImage>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPainter>
|
||||||
#include <QRunnable>
|
#include <QRunnable>
|
||||||
#include <QStandardItem>
|
#include <QStandardItem>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include "citra_qt/util/util.h"
|
#include "citra_qt/util/util.h"
|
||||||
|
#include "common/logging/log.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/loader/smdh.h"
|
#include "core/loader/smdh.h"
|
||||||
|
|
||||||
|
@ -39,6 +44,23 @@ static QPixmap GetDefaultIcon(bool large) {
|
||||||
return icon;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the short game title from SMDH data.
|
* Gets the short game title from SMDH data.
|
||||||
* @param smdh SMDH data
|
* @param smdh SMDH data
|
||||||
|
@ -50,8 +72,25 @@ static QString GetQStringShortTitleFromSMDH(const Loader::SMDH& smdh,
|
||||||
return QString::fromUtf16(smdh.GetShortTitle(language).data());
|
return QString::fromUtf16(smdh.GetShortTitle(language).data());
|
||||||
}
|
}
|
||||||
|
|
||||||
class GameListItem : public QStandardItem {
|
struct CompatStatus {
|
||||||
|
QString color;
|
||||||
|
QString text;
|
||||||
|
QString 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", GameList::tr("Perfect"), GameList::tr("Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without\nany workarounds needed.") } },
|
||||||
|
{ "1", { "#47d35c", GameList::tr("Great"), GameList::tr("Game functions with minor graphical or audio glitches and is playable from start to finish. May require some\nworkarounds.") } },
|
||||||
|
{ "2", { "#94b242", GameList::tr("Okay"), GameList::tr("Game functions with major graphical or audio glitches, but game is playable from start to finish with\nworkarounds.") } },
|
||||||
|
{ "3", { "#f2d624", GameList::tr("Bad"), GameList::tr("Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches\neven with workarounds.") } },
|
||||||
|
{ "4", { "#FF0000", GameList::tr("Intro/Menu"), GameList::tr("Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start\nScreen.") } },
|
||||||
|
{ "5", { "#828282", GameList::tr("Won't Boot"), GameList::tr("The game crashes when attempting to startup.") } },
|
||||||
|
{ "99",{ "#000000", GameList::tr("Not Tested"), GameList::tr("The game has not yet been tested.") } }, };
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
class GameListItem : public QStandardItem {
|
||||||
public:
|
public:
|
||||||
GameListItem() : QStandardItem() {}
|
GameListItem() : QStandardItem() {}
|
||||||
GameListItem(const QString& string) : QStandardItem(string) {}
|
GameListItem(const QString& string) : QStandardItem(string) {}
|
||||||
|
@ -65,7 +104,6 @@ public:
|
||||||
* If this class receives valid SMDH data, it will also display game icons and titles.
|
* If this class receives valid SMDH data, it will also display game icons and titles.
|
||||||
*/
|
*/
|
||||||
class GameListItemPath : public GameListItem {
|
class GameListItemPath : public GameListItem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int FullPathRole = Qt::UserRole + 1;
|
static const int FullPathRole = Qt::UserRole + 1;
|
||||||
static const int TitleRole = Qt::UserRole + 2;
|
static const int TitleRole = Qt::UserRole + 2;
|
||||||
|
@ -107,13 +145,34 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GameListItemCompat : public GameListItem {
|
||||||
|
public:
|
||||||
|
static const int CompatNumberRole = Qt::UserRole + 1;
|
||||||
|
GameListItemCompat() = default;
|
||||||
|
explicit GameListItemCompat(const QString compatiblity) {
|
||||||
|
auto iterator = status_data.find(compatiblity);
|
||||||
|
if (iterator == status_data.end()) {
|
||||||
|
NGLOG_WARNING(Frontend, "Invalid compatibility number {}", compatiblity.toStdString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CompatStatus status = iterator->second;
|
||||||
|
setData(compatiblity, CompatNumberRole);
|
||||||
|
setText(status.text);
|
||||||
|
setToolTip(status.tooltip);
|
||||||
|
setData(CreateCirclePixmapFromColor(status.color), Qt::DecorationRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const QStandardItem& other) const override {
|
||||||
|
return data(CompatNumberRole) < other.data(CompatNumberRole);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specialization of GameListItem for size values.
|
* A specialization of GameListItem for size values.
|
||||||
* This class ensures that for every numerical size value it holds (in bytes), a correct
|
* This class ensures that for every numerical size value it holds (in bytes), a correct
|
||||||
* human-readable string representation will be displayed to the user.
|
* human-readable string representation will be displayed to the user.
|
||||||
*/
|
*/
|
||||||
class GameListItemSize : public GameListItem {
|
class GameListItemSize : public GameListItem {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int SizeRole = Qt::UserRole + 1;
|
static const int SizeRole = Qt::UserRole + 1;
|
||||||
|
|
||||||
|
@ -152,8 +211,10 @@ class GameListWorker : public QObject, public QRunnable {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GameListWorker(QString dir_path, bool deep_scan)
|
GameListWorker(QString dir_path, bool deep_scan,
|
||||||
: QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan) {}
|
const std::unordered_map<std::string, QString>& compatibility_list)
|
||||||
|
: QObject(), QRunnable(), dir_path(dir_path), deep_scan(deep_scan),
|
||||||
|
compatibility_list(compatibility_list) {}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/// Starts the processing of directory tree information.
|
/// Starts the processing of directory tree information.
|
||||||
|
@ -179,6 +240,7 @@ private:
|
||||||
QStringList watch_list;
|
QStringList watch_list;
|
||||||
QString dir_path;
|
QString dir_path;
|
||||||
bool deep_scan;
|
bool deep_scan;
|
||||||
|
const std::unordered_map<std::string, QString>& compatibility_list;
|
||||||
std::atomic_bool stop_processing;
|
std::atomic_bool stop_processing;
|
||||||
|
|
||||||
void AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion = 0);
|
void AddFstEntriesToGameList(const std::string& dir_path, unsigned int recursion = 0);
|
||||||
|
|
|
@ -131,6 +131,7 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
|
||||||
|
|
||||||
show();
|
show();
|
||||||
|
|
||||||
|
game_list->LoadCompatibilityList();
|
||||||
game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
|
game_list->PopulateAsync(UISettings::values.gamedir, UISettings::values.gamedir_deepscan);
|
||||||
|
|
||||||
// Show one-time "callout" messages to the user
|
// Show one-time "callout" messages to the user
|
||||||
|
|
Loading…
Reference in a new issue