Qt: implement compatibility column

This commit is contained in:
Unknown 2017-12-04 21:59:28 +01:00 committed by Ivan
parent 970d2a06e0
commit 03814e8d02
8 changed files with 442 additions and 9 deletions

View File

@ -6,17 +6,17 @@ set(CMAKE_CXX_STANDARD 14)
include(CheckCXXCompilerFlag) include(CheckCXXCompilerFlag)
# Qt section # Qt section
find_package(Qt5 5.7 COMPONENTS Widgets) find_package(Qt5 5.7 COMPONENTS Widgets Network)
if(WIN32) if(WIN32)
find_package(Qt5 5.7 COMPONENTS WinExtras REQUIRED) find_package(Qt5 5.7 COMPONENTS WinExtras REQUIRED)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras) set(RPCS3_QT_LIBS Qt5::Widgets Qt5::WinExtras Qt5::Network)
else() else()
find_package(Qt5 5.7 COMPONENTS DBus) find_package(Qt5 5.7 COMPONENTS DBus)
if(Qt5DBus_FOUND) if(Qt5DBus_FOUND)
set(RPCS3_QT_LIBS Qt5::Widgets Qt5::DBus) set(RPCS3_QT_LIBS Qt5::Widgets Qt5::DBus Qt5::Network)
add_definitions(-DHAVE_QTDBUS) add_definitions(-DHAVE_QTDBUS)
else() else()
set(RPCS3_QT_LIBS Qt5::Widgets) set(RPCS3_QT_LIBS Qt5::Widgets Qt5::Network)
endif() endif()
endif() endif()

View File

@ -376,6 +376,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_game_compatibility.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_game_list_frame.cpp"> <ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_game_list_frame.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@ -511,6 +516,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_game_compatibility.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_game_list_frame.cpp"> <ClCompile Include="QTGeneratedFiles\Debug\moc_game_list_frame.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
@ -656,6 +666,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_game_compatibility.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_game_list_frame.cpp"> <ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_game_list_frame.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
@ -791,6 +806,11 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile> </ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_game_compatibility.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_game_list_frame.cpp"> <ClCompile Include="QTGeneratedFiles\Release\moc_game_list_frame.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
@ -893,6 +913,7 @@
</ClCompile> </ClCompile>
<ClCompile Include="rpcs3qt\about_dialog.cpp" /> <ClCompile Include="rpcs3qt\about_dialog.cpp" />
<ClCompile Include="rpcs3qt\gamepads_settings_dialog.cpp" /> <ClCompile Include="rpcs3qt\gamepads_settings_dialog.cpp" />
<ClCompile Include="rpcs3qt\game_compatibility.cpp" />
<ClCompile Include="rpcs3qt\game_list_grid.cpp" /> <ClCompile Include="rpcs3qt\game_list_grid.cpp" />
<ClCompile Include="rpcs3qt\game_list_grid_delegate.cpp" /> <ClCompile Include="rpcs3qt\game_list_grid_delegate.cpp" />
<ClCompile Include="rpcs3qt\progress_dialog.cpp" /> <ClCompile Include="rpcs3qt\progress_dialog.cpp" />
@ -1266,6 +1287,24 @@
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DLLVM_AVAILABLE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command> <Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DLLVM_AVAILABLE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
</CustomBuild> </CustomBuild>
<ClInclude Include="rpcs3qt\gamepads_settings_dialog.h" /> <ClInclude Include="rpcs3qt\gamepads_settings_dialog.h" />
<CustomBuild Include="rpcs3qt\game_compatibility.h">
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">Moc%27ing game_compatibility.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DLLVM_AVAILABLE -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Moc%27ing game_compatibility.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -D_SCL_SECURE_NO_WARNINGS -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Moc%27ing game_compatibility.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_NO_DEBUG -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">$(QTDIR)\bin\moc.exe;%(FullPath)</AdditionalInputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">Moc%27ing game_compatibility.h...</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">.\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug - LLVM|x64'">"$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -DQT_GUI_LIB -DQT_QML_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DLLVM_AVAILABLE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE "-I.\..\Vulkan\Vulkan-LoaderAndValidationLayers\include" "-I.\.." "-I.\..\3rdparty\minidx12\Include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtOpenGL" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtQuick" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtQml" "-I$(QTDIR)\include\QtNetwork" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)\." "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras"</Command>
</CustomBuild>
<ClInclude Include="rpcs3qt\game_list.h" /> <ClInclude Include="rpcs3qt\game_list.h" />
<ClInclude Include="rpcs3qt\game_list_grid_delegate.h" /> <ClInclude Include="rpcs3qt\game_list_grid_delegate.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />

View File

@ -569,6 +569,21 @@
<ClCompile Include="rpcs3qt\progress_dialog.cpp"> <ClCompile Include="rpcs3qt\progress_dialog.cpp">
<Filter>Gui\misc dialogs</Filter> <Filter>Gui\misc dialogs</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="QTGeneratedFiles\Release - LLVM\moc_game_compatibility.cpp">
<Filter>Generated Files\Release - LLVM</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug\moc_game_compatibility.cpp">
<Filter>Generated Files\Debug</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Release\moc_game_compatibility.cpp">
<Filter>Generated Files\Release</Filter>
</ClCompile>
<ClCompile Include="QTGeneratedFiles\Debug - LLVM\moc_game_compatibility.cpp">
<Filter>Generated Files\Debug - LLVM</Filter>
</ClCompile>
<ClCompile Include="rpcs3qt\game_compatibility.cpp">
<Filter>Gui\game list</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="\rpcs3qt\*.h"> <ClInclude Include="\rpcs3qt\*.h">
@ -762,6 +777,9 @@
<CustomBuild Include="rpcs3qt\progress_dialog.h"> <CustomBuild Include="rpcs3qt\progress_dialog.h">
<Filter>Gui\misc dialogs</Filter> <Filter>Gui\misc dialogs</Filter>
</CustomBuild> </CustomBuild>
<CustomBuild Include="rpcs3qt\game_compatibility.h">
<Filter>Gui\game list</Filter>
</CustomBuild>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Image Include="rpcs3.ico" /> <Image Include="rpcs3.ico" />

View File

@ -0,0 +1,240 @@
#include "game_compatibility.h"
#include <QMessageBox>
constexpr auto qstr = QString::fromStdString;
inline std::string sstr(const QString& _in) { return _in.toStdString(); }
game_compatibility::game_compatibility(std::shared_ptr<gui_settings> settings) : m_xgui_settings(settings)
{
m_filepath = m_xgui_settings->GetSettingsDir() + "/compat_database.dat";
m_url = "https://rpcs3.net/compatibility?api=v1&export";
m_network_request = QNetworkRequest(QUrl(m_url));
RequestCompatibility();
}
void game_compatibility::RequestCompatibility(bool online)
{
// Creates new map from database
auto ReadJSON = [=](const QJsonObject& json_data, bool after_download)
{
int return_code = json_data["return_code"].toInt();
if (return_code < 0)
{
if (after_download)
{
std::string error_message;
switch (return_code)
{
case -1:
error_message = "Server Error - Internal Error";
break;
case -2:
error_message = "Server Error - Maintenance Mode";
break;
default:
error_message = "Server Error - Unknown Error";
break;
}
LOG_ERROR(GENERAL, "Compatibility error: { %s: return code %d }", error_message, return_code);
Q_EMIT DownloadError(qstr(error_message) + " " + QString::number(return_code));
}
else
{
LOG_ERROR(GENERAL, "Compatibility error: { Database Error - Invalid: return code %d }", return_code);
}
return false;
}
if (!json_data["results"].isObject())
{
LOG_ERROR(GENERAL, "Compatibility error: { Database Error - No Results found }");
return false;
}
m_compat_database.clear();
QJsonObject json_results = json_data["results"].toObject();
// Retrieve status data for every valid entry
for (const auto& key : json_results.keys())
{
if (!json_results[key].isObject())
{
LOG_ERROR(GENERAL, "Compatibility error: { Database Error - Unusable object %s }", sstr(key));
continue;
}
QJsonObject json_result = json_results[key].toObject();
// Retrieve compatibility information from json
Compat_Status compat_status = Status_Data.at(json_result.value("status").toString("NoResult"));
// Add date if possible
compat_status.date = json_result.value("date").toString();
// Add status to map
m_compat_database.emplace(std::pair<std::string, Compat_Status>(sstr(key), compat_status));
}
return true;
};
if (!online)
{
// Retrieve database from file
QFile file(m_filepath);
if (!file.exists())
{
LOG_NOTICE(GENERAL, "Compatibility notice: { Database file not found: %s }", sstr(m_filepath));
return;
}
if (!file.open(QIODevice::ReadOnly))
{
LOG_ERROR(GENERAL, "Compatibility error: { Database Error - Could not read database from file: %s }", sstr(m_filepath));
return;
}
QByteArray data = file.readAll();
file.close();
LOG_NOTICE(GENERAL, "Compatibility notice: { Finished reading database from file: %s }", sstr(m_filepath));
// Create new map from database
ReadJSON(QJsonDocument::fromJson(data).object(), online);
return;
}
if (QSslSocket::supportsSsl() == false)
{
LOG_ERROR(GENERAL, "Can not retrieve the online database! Please make sure your system supports SSL.");
QMessageBox::warning(nullptr, tr("Warning!"), tr("Can not retrieve the online database! Please make sure your system supports SSL."));
return;
}
LOG_NOTICE(GENERAL, "SSL supported! Beginning compatibility database download from: %s", sstr(m_url));
// Send request and wait for response
m_network_access_manager.reset(new QNetworkAccessManager());
QNetworkReply* network_reply = m_network_access_manager->get(m_network_request);
// Show Progress
m_progress_dialog.reset(new QProgressDialog(tr(".Please wait."), tr("Abort"), 0, 100));
m_progress_dialog->setWindowTitle(tr("Downloading Database"));
m_progress_dialog->setFixedWidth(QLabel("This is the very length of the progressbar due to hidpi reasons.").sizeHint().width());
m_progress_dialog->setValue(0);
m_progress_dialog->show();
// Animate progress dialog a bit more
m_progress_timer.reset(new QTimer(this));
connect(m_progress_timer.get(), &QTimer::timeout, [&]()
{
switch (++m_timer_count % 3)
{
case 0:
m_timer_count = 0;
m_progress_dialog->setLabelText(tr(".Please wait."));
break;
case 1:
m_progress_dialog->setLabelText(tr("..Please wait.."));
break;
default:
m_progress_dialog->setLabelText(tr("...Please wait..."));
break;
}
});
m_progress_timer->start(500);
// Handle abort
connect(m_progress_dialog.get(), &QProgressDialog::rejected, network_reply, &QNetworkReply::abort);
// Handle progress
connect(network_reply, &QNetworkReply::downloadProgress, [&](qint64 bytesReceived, qint64 bytesTotal)
{
m_progress_dialog->setMaximum(bytesTotal);
m_progress_dialog->setValue(bytesReceived);
});
// Handle response according to its contents
connect(network_reply, &QNetworkReply::finished, [=]()
{
// Clean up Progress Dialog
if (m_progress_dialog)
{
m_progress_dialog->close();
}
if (m_progress_timer)
{
m_progress_timer->stop();
}
// Handle Errors
if (network_reply->error() != QNetworkReply::NoError)
{
// We failed to retrieve a new database, therefore refresh gamelist to old state
QString error = network_reply->errorString();
Q_EMIT DownloadError(error);
LOG_ERROR(GENERAL, "Compatibility error: { Network Error - %s }", sstr(error));
return;
}
LOG_NOTICE(GENERAL, "Compatibility notice: { Database download finished }");
// Read data from network reply
QByteArray data = network_reply->readAll();
network_reply->deleteLater();
// Create new map from database and write database to file if database was valid
if (ReadJSON(QJsonDocument::fromJson(data).object(), online))
{
// We have a new database in map, therefore refresh gamelist to new state
Q_EMIT DownloadFinished();
// Write database to file
QFile file(m_filepath);
if (file.exists())
{
LOG_NOTICE(GENERAL, "Compatibility notice: { Database file found: %s }", sstr(m_filepath));
}
if (!file.open(QIODevice::WriteOnly))
{
LOG_ERROR(GENERAL, "Compatibility error: { Database Error - Could not write database to file: %s }", sstr(m_filepath));
return;
}
file.write(data);
file.close();
LOG_SUCCESS(GENERAL, "Compatibility success: { Write database to file: %s }", sstr(m_filepath));
}
});
// We want to retrieve a new database, therefore refresh gamelist and indicate that
Q_EMIT DownloadStarted();
}
Compat_Status game_compatibility::GetCompatibility(const std::string& title_id)
{
if (m_compat_database.empty())
{
return Status_Data.at("NoData");
}
else if (m_compat_database.count(title_id) > 0)
{
return m_compat_database[title_id];
}
return Status_Data.at("NoResult");
}
Compat_Status game_compatibility::GetStatusData(const QString& status)
{
return Status_Data.at(status);
}

View File

@ -0,0 +1,74 @@
#pragma once
#include <memory>
#include <QPainter>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QTableWidget>
#include <QProgressDialog>
#include <QTimer>
#include "gui_settings.h"
class game_compatibility : public QObject
{
Q_OBJECT
const std::map<QString, Compat_Status> Status_Data =
{
{ "Playable", { "", "#2ecc71", QObject::tr("Playable"), QObject::tr("Games that can be properly played from start to finish") } },
{ "Ingame", { "", "#f1c40f", QObject::tr("Ingame"), QObject::tr("Games that go somewhere but not far enough to be considered playable") } },
{ "Intro", { "", "#f39c12", QObject::tr("Intro"), QObject::tr("Games that only display some screens") } },
{ "Loadable", { "", "#e74c3c", QObject::tr("Loadable"), QObject::tr("Games that display a black screen with an active framerate") } },
{ "Nothing", { "", "#2c3e50", QObject::tr("Nothing"), QObject::tr("Games that show nothing") } },
{ "NoResult", { "", "", QObject::tr("No results found"), QObject::tr("There is no entry for this game or application in the compatibility database yet.") } },
{ "NoData", { "", "", QObject::tr("Database missing"), QObject::tr("Right click here and download the current database.\nMake sure you are connected to the internet.") } },
{ "Download", { "", "", QObject::tr("Retrieving..."), QObject::tr("Downloading the compatibility database. Please wait...") } }
};
int m_timer_count = 0;
QString m_filepath;
QString m_url;
QNetworkRequest m_network_request;
std::shared_ptr<gui_settings> m_xgui_settings;
std::unique_ptr<QTimer> m_progress_timer;
std::unique_ptr<QProgressDialog> m_progress_dialog;
std::unique_ptr<QNetworkAccessManager> m_network_access_manager;
std::map<std::string, Compat_Status> m_compat_database;
public:
/** Handles reads, writes and downloads for the compatibility database */
game_compatibility(std::shared_ptr<gui_settings> settings);
/** Reads database. If online set to true: Downloads and writes the database to file */
void RequestCompatibility(bool online = false);
/** Returns the compatibility status for the requested title */
Compat_Status GetCompatibility(const std::string& title_id);
/** Returns the data for the requested status */
Compat_Status GetStatusData(const QString& status);
Q_SIGNALS:
void DownloadStarted();
void DownloadFinished();
void DownloadError(const QString& error);
};
class compat_pixmap : public QPixmap
{
public:
compat_pixmap(const QColor& color) : QPixmap(16, 16)
{
fill(Qt::transparent);
QPainter painter(this);
painter.setPen(color);
painter.setBrush(color);
painter.drawEllipse(0, 0, 15, 15);
}
};

View File

@ -172,6 +172,7 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
m_gameList->setHorizontalHeaderItem(gui::column_resolution, new QTableWidgetItem(tr("Supported Resolutions"))); m_gameList->setHorizontalHeaderItem(gui::column_resolution, new QTableWidgetItem(tr("Supported Resolutions")));
m_gameList->setHorizontalHeaderItem(gui::column_sound, new QTableWidgetItem(tr("Sound Formats"))); m_gameList->setHorizontalHeaderItem(gui::column_sound, new QTableWidgetItem(tr("Sound Formats")));
m_gameList->setHorizontalHeaderItem(gui::column_parental, new QTableWidgetItem(tr("Parental Level"))); m_gameList->setHorizontalHeaderItem(gui::column_parental, new QTableWidgetItem(tr("Parental Level")));
m_gameList->setHorizontalHeaderItem(gui::column_compat, new QTableWidgetItem(tr("Compatibility")));
// since this won't work somehow: gameList->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); // since this won't work somehow: gameList->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
for (int i = 0; i < m_gameList->horizontalHeader()->count(); i++) for (int i = 0; i < m_gameList->horizontalHeader()->count(); i++)
@ -179,6 +180,8 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
m_gameList->horizontalHeaderItem(i)->setTextAlignment(Qt::AlignLeft); m_gameList->horizontalHeaderItem(i)->setTextAlignment(Qt::AlignLeft);
} }
m_game_compat = std::make_unique<game_compatibility>(xgui_settings);
m_Central_Widget = new QStackedWidget(this); m_Central_Widget = new QStackedWidget(this);
m_Central_Widget->addWidget(m_gameList); m_Central_Widget->addWidget(m_gameList);
m_Central_Widget->addWidget(m_xgrid); m_Central_Widget->addWidget(m_xgrid);
@ -197,9 +200,10 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
QAction* showResolutionColAct = new QAction(tr("Show Supported Resolutions"), this); QAction* showResolutionColAct = new QAction(tr("Show Supported Resolutions"), this);
QAction* showSoundFormatColAct = new QAction(tr("Show Sound Formats"), this); QAction* showSoundFormatColAct = new QAction(tr("Show Sound Formats"), this);
QAction* showParentalLevelColAct = new QAction(tr("Show Parental Levels"), this); QAction* showParentalLevelColAct = new QAction(tr("Show Parental Levels"), this);
QAction* showCompatibilityAct = new QAction(tr("Show Compatibilities"), this);
m_columnActs = { showIconColAct, showNameColAct, showSerialColAct, showFWColAct, showAppVersionColAct, showCategoryColAct, showPathColAct, m_columnActs = { showIconColAct, showNameColAct, showSerialColAct, showFWColAct, showAppVersionColAct, showCategoryColAct, showPathColAct,
showResolutionColAct, showSoundFormatColAct, showParentalLevelColAct }; showResolutionColAct, showSoundFormatColAct, showParentalLevelColAct, showCompatibilityAct };
// Events // Events
connect(m_gameList, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); connect(m_gameList, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
@ -216,10 +220,39 @@ game_list_frame::game_list_frame(std::shared_ptr<gui_settings> guiSettings, std:
connect(m_xgrid, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot); connect(m_xgrid, &QTableWidget::doubleClicked, this, &game_list_frame::doubleClickedSlot);
connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu); connect(m_xgrid, &QTableWidget::customContextMenuRequested, this, &game_list_frame::ShowContextMenu);
connect(m_game_compat.get(), &game_compatibility::DownloadStarted, [=]()
{
for (auto& game : m_game_data)
{
game.compat = m_game_compat->GetStatusData("Download");
}
Refresh();
});
connect(m_game_compat.get(), &game_compatibility::DownloadFinished, [=]()
{
for (auto& game : m_game_data)
{
game.compat = m_game_compat->GetCompatibility(game.info.serial);
}
Refresh();
});
connect(m_game_compat.get(), &game_compatibility::DownloadError, [=](const QString& error)
{
for (auto& game : m_game_data)
{
game.compat = m_game_compat->GetCompatibility(game.info.serial);
}
Refresh();
QMessageBox::warning(this, tr("Warning!"), tr("Failed to retrieve the online compatibility database!\nFalling back to local database.\n\n") + tr(qPrintable(error)));
});
connect(m_Search_Bar, &QLineEdit::textChanged, this, &game_list_frame::SetSearchText); connect(m_Search_Bar, &QLineEdit::textChanged, this, &game_list_frame::SetSearchText);
connect(m_Slider_Size, &QSlider::valueChanged, this, &game_list_frame::RequestIconSizeActSet); connect(m_Slider_Size, &QSlider::valueChanged, this, &game_list_frame::RequestIconSizeActSet);
connect(m_Slider_Size, &QSlider::sliderReleased, this, [&]{ xgui_settings->SetValue(gui::gl_iconSize, m_Slider_Size->value()); }); connect(m_Slider_Size, &QSlider::sliderReleased, this, [&]
{
xgui_settings->SetValue(gui::gl_iconSize, m_Slider_Size->value());
});
connect(m_Slider_Size, &QSlider::actionTriggered, [&](int action) connect(m_Slider_Size, &QSlider::actionTriggered, [&](int action)
{ {
if (action != QAbstractSlider::SliderNoAction && action != QAbstractSlider::SliderMove) if (action != QAbstractSlider::SliderNoAction && action != QAbstractSlider::SliderMove)
@ -457,7 +490,7 @@ void game_list_frame::Refresh(const bool fromDrive, const bool scrollAfter)
QPixmap pxmap = PaintedPixmap(img, hasCustomConfig); QPixmap pxmap = PaintedPixmap(img, hasCustomConfig);
m_game_data.push_back({ game, img, pxmap, true, bootable, hasCustomConfig }); m_game_data.push_back({ game, m_game_compat->GetCompatibility(game.serial), img, pxmap, true, bootable, hasCustomConfig });
} }
auto op = [](const GUI_GameInfo& game1, const GUI_GameInfo& game2) auto op = [](const GUI_GameInfo& game1, const GUI_GameInfo& game2)
@ -638,6 +671,7 @@ void game_list_frame::ShowSpecifiedContextMenu(const QPoint &pos, int row)
QAction* openConfig = myMenu.addAction(tr("&Open Config Folder")); QAction* openConfig = myMenu.addAction(tr("&Open Config Folder"));
myMenu.addSeparator(); myMenu.addSeparator();
QAction* checkCompat = myMenu.addAction(tr("&Check Game Compatibility")); QAction* checkCompat = myMenu.addAction(tr("&Check Game Compatibility"));
QAction* downloadCompat = myMenu.addAction(tr("&Download Compatibility Database"));
connect(boot, &QAction::triggered, [=] connect(boot, &QAction::triggered, [=]
{ {
@ -711,6 +745,10 @@ void game_list_frame::ShowSpecifiedContextMenu(const QPoint &pos, int row)
QString link = "https://rpcs3.net/compatibility?g=" + qstr(currGame.serial); QString link = "https://rpcs3.net/compatibility?g=" + qstr(currGame.serial);
QDesktopServices::openUrl(QUrl(link)); QDesktopServices::openUrl(QUrl(link));
}); });
connect(downloadCompat, &QAction::triggered, [=]
{
m_game_compat->RequestCompatibility(true);
});
//Disable options depending on software category //Disable options depending on software category
QString category = qstr(currGame.category); QString category = qstr(currGame.category);
@ -1054,6 +1092,15 @@ int game_list_frame::PopulateGameList()
title_item->setIcon(QIcon(":/Icons/cog_black.png")); title_item->setIcon(QIcon(":/Icons/cog_black.png"));
} }
// Compatibility
QTableWidgetItem* compat_item = new QTableWidgetItem;
compat_item->setFlags(compat_item->flags() & ~Qt::ItemIsEditable);
compat_item->setText(game.compat.text + (game.compat.date.isEmpty() ? "" : " (" + game.compat.date + ")"));
compat_item->setToolTip(game.compat.tooltip);
if (!game.compat.color.isEmpty())
{
compat_item->setData(Qt::DecorationRole, compat_pixmap(game.compat.color));
}
m_gameList->setItem(row, gui::column_icon, icon_item); m_gameList->setItem(row, gui::column_icon, icon_item);
m_gameList->setItem(row, gui::column_name, title_item); m_gameList->setItem(row, gui::column_name, title_item);
m_gameList->setItem(row, gui::column_serial, l_GetItem(game.info.serial)); m_gameList->setItem(row, gui::column_serial, l_GetItem(game.info.serial));
@ -1064,8 +1111,12 @@ int game_list_frame::PopulateGameList()
m_gameList->setItem(row, gui::column_resolution, l_GetItem(GetStringFromU32(game.info.resolution, resolution::mode, true))); m_gameList->setItem(row, gui::column_resolution, l_GetItem(GetStringFromU32(game.info.resolution, resolution::mode, true)));
m_gameList->setItem(row, gui::column_sound, l_GetItem(GetStringFromU32(game.info.sound_format, sound::format, true))); m_gameList->setItem(row, gui::column_sound, l_GetItem(GetStringFromU32(game.info.sound_format, sound::format, true)));
m_gameList->setItem(row, gui::column_parental, l_GetItem(GetStringFromU32(game.info.parental_lvl, parental::level))); m_gameList->setItem(row, gui::column_parental, l_GetItem(GetStringFromU32(game.info.parental_lvl, parental::level)));
m_gameList->setItem(row, gui::column_compat, compat_item);
if (selected_item == game.info.icon_path) result = row; if (selected_item == game.info.icon_path)
{
result = row;
}
row++; row++;
} }

View File

@ -5,8 +5,8 @@
#include "game_list.h" #include "game_list.h"
#include "game_list_grid.h" #include "game_list_grid.h"
#include "gui_settings.h"
#include "emu_settings.h" #include "emu_settings.h"
#include "game_compatibility.h"
#include <QDockWidget> #include <QDockWidget>
#include <QMainWindow> #include <QMainWindow>
@ -163,6 +163,7 @@ namespace sound
struct GUI_GameInfo struct GUI_GameInfo
{ {
GameInfo info; GameInfo info;
Compat_Status compat;
QImage icon; QImage icon;
QPixmap pxmap; QPixmap pxmap;
bool isVisible; bool isVisible;
@ -259,6 +260,7 @@ private:
// Game List // Game List
game_list* m_gameList; game_list* m_gameList;
std::unique_ptr<game_compatibility> m_game_compat;
QList<QAction*> m_columnActs; QList<QAction*> m_columnActs;
Qt::SortOrder m_colSortOrder; Qt::SortOrder m_colSortOrder;
int m_sortColumn; int m_sortColumn;

View File

@ -10,6 +10,14 @@
#include <QBitmap> #include <QBitmap>
#include <QLabel> #include <QLabel>
struct Compat_Status
{
QString date;
QString color;
QString text;
QString tooltip;
};
struct gui_save struct gui_save
{ {
QString key; QString key;
@ -53,6 +61,7 @@ namespace gui
column_resolution, column_resolution,
column_sound, column_sound,
column_parental, column_parental,
column_compat,
column_count column_count
}; };