Add Discord Rich Presence Support (#3883)
* Initial Discord RPC support Build with Discord Presence ON Fix RPC detection Fix Time elapsed on pause; will now continue to count. * Fix CI builds with compile flag Addressed reviews Fix silly mistakes Fix 'Not in-game' display class instead of namespace Fix Revamped remove redundant code Using Pimpl pattern * Implement Null class * Fix config updation * Addressed All Reviews * externals/discord-rpc : Updated to latest commit
This commit is contained in:
parent
96c025e4c2
commit
6cb9a45154
19 changed files with 193 additions and 11 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -34,3 +34,6 @@
|
||||||
[submodule "cubeb"]
|
[submodule "cubeb"]
|
||||||
path = externals/cubeb
|
path = externals/cubeb
|
||||||
url = https://github.com/kinetiknz/cubeb.git
|
url = https://github.com/kinetiknz/cubeb.git
|
||||||
|
[submodule "discord-rpc"]
|
||||||
|
path = externals/discord-rpc
|
||||||
|
url = https://github.com/discordapp/discord-rpc.git
|
||||||
|
|
|
@ -13,3 +13,4 @@ TRAVIS_TAG
|
||||||
|
|
||||||
# citra specific flags
|
# citra specific flags
|
||||||
ENABLE_COMPATIBILITY_REPORTING
|
ENABLE_COMPATIBILITY_REPORTING
|
||||||
|
USE_DISCORD_PRESENCE
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
cd /citra
|
cd /citra
|
||||||
|
|
||||||
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"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
|
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 -DUSE_DISCORD_PRESENCE=ON
|
||||||
make -j4
|
make -j4
|
||||||
|
|
||||||
ctest -VV -C Release
|
ctest -VV -C Release
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
cd /citra
|
cd /citra
|
||||||
|
|
||||||
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"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
|
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 -DUSE_DISCORD_PRESENCE=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"} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON
|
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 -DUSE_DISCORD_PRESENCE=ON
|
||||||
make -j4
|
make -j4
|
||||||
|
|
||||||
ctest -VV -C Release
|
ctest -VV -C Release
|
||||||
|
|
|
@ -20,6 +20,8 @@ option(ENABLE_WEB_SERVICE "Enable web services (telemetry, etc.)" ON)
|
||||||
|
|
||||||
option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
|
option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
|
||||||
|
|
||||||
|
option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF)
|
||||||
|
|
||||||
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit)
|
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit)
|
||||||
message(STATUS "Copying pre-commit hook")
|
message(STATUS "Copying pre-commit hook")
|
||||||
file(COPY hooks/pre-commit
|
file(COPY hooks/pre-commit
|
||||||
|
|
|
@ -44,9 +44,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} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON .. 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 -DUSE_DISCORD_PRESENCE=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} -DENABLE_COMPATIBILITY_LIST_DOWNLOAD=ON .. 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 -DUSE_DISCORD_PRESENCE=ON .. 2>&1"
|
||||||
}
|
}
|
||||||
- cd ..
|
- cd ..
|
||||||
|
|
||||||
|
|
18
externals/CMakeLists.txt
vendored
18
externals/CMakeLists.txt
vendored
|
@ -62,6 +62,18 @@ endif()
|
||||||
add_subdirectory(enet)
|
add_subdirectory(enet)
|
||||||
target_include_directories(enet INTERFACE ./enet/include)
|
target_include_directories(enet INTERFACE ./enet/include)
|
||||||
|
|
||||||
|
# Cubeb
|
||||||
|
if (ENABLE_CUBEB)
|
||||||
|
set(BUILD_TESTS OFF CACHE BOOL "")
|
||||||
|
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# DiscordRPC
|
||||||
|
if (USE_DISCORD_PRESENCE)
|
||||||
|
add_subdirectory(discord-rpc)
|
||||||
|
target_include_directories(discord-rpc INTERFACE ./discord-rpc/include)
|
||||||
|
endif()
|
||||||
|
|
||||||
if (ENABLE_WEB_SERVICE)
|
if (ENABLE_WEB_SERVICE)
|
||||||
# LibreSSL
|
# LibreSSL
|
||||||
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
|
set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "")
|
||||||
|
@ -80,9 +92,3 @@ if (ENABLE_WEB_SERVICE)
|
||||||
add_library(json-headers INTERFACE)
|
add_library(json-headers INTERFACE)
|
||||||
target_include_directories(json-headers INTERFACE ./json)
|
target_include_directories(json-headers INTERFACE ./json)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Cubeb
|
|
||||||
if(ENABLE_CUBEB)
|
|
||||||
set(BUILD_TESTS OFF CACHE BOOL "")
|
|
||||||
add_subdirectory(cubeb EXCLUDE_FROM_ALL)
|
|
||||||
endif()
|
|
||||||
|
|
1
externals/discord-rpc
vendored
Submodule
1
externals/discord-rpc
vendored
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 3d3ae7129d17643bc706da0a2eea85aafd10ab3a
|
|
@ -68,6 +68,7 @@ add_executable(citra-qt
|
||||||
debugger/registers.h
|
debugger/registers.h
|
||||||
debugger/wait_tree.cpp
|
debugger/wait_tree.cpp
|
||||||
debugger/wait_tree.h
|
debugger/wait_tree.h
|
||||||
|
discord.h
|
||||||
game_list.cpp
|
game_list.cpp
|
||||||
game_list.h
|
game_list.h
|
||||||
game_list_p.h
|
game_list_p.h
|
||||||
|
@ -201,6 +202,15 @@ target_link_libraries(citra-qt PRIVATE audio_core common core input_common netwo
|
||||||
target_link_libraries(citra-qt PRIVATE Boost::boost glad nihstro-headers Qt5::OpenGL Qt5::Widgets Qt5::Multimedia)
|
target_link_libraries(citra-qt PRIVATE Boost::boost glad nihstro-headers Qt5::OpenGL Qt5::Widgets Qt5::Multimedia)
|
||||||
target_link_libraries(citra-qt PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
|
target_link_libraries(citra-qt PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
|
||||||
|
|
||||||
|
if (USE_DISCORD_PRESENCE)
|
||||||
|
target_sources(citra-qt PUBLIC
|
||||||
|
discord_impl.cpp
|
||||||
|
discord_impl.h
|
||||||
|
)
|
||||||
|
target_link_libraries(citra-qt PRIVATE discord-rpc)
|
||||||
|
target_compile_definitions(citra-qt PRIVATE -DUSE_DISCORD_PRESENCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
install(TARGETS citra-qt RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
|
install(TARGETS citra-qt RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin")
|
||||||
endif()
|
endif()
|
||||||
|
|
|
@ -207,6 +207,8 @@ void Config::ReadValues() {
|
||||||
|
|
||||||
qt_config->beginGroup("UI");
|
qt_config->beginGroup("UI");
|
||||||
UISettings::values.theme = ReadSetting("theme", UISettings::themes[0].second).toString();
|
UISettings::values.theme = ReadSetting("theme", UISettings::themes[0].second).toString();
|
||||||
|
UISettings::values.enable_discord_presence =
|
||||||
|
ReadSetting("enable_discord_presence", true).toBool();
|
||||||
|
|
||||||
qt_config->beginGroup("Updater");
|
qt_config->beginGroup("Updater");
|
||||||
UISettings::values.check_for_update_on_start =
|
UISettings::values.check_for_update_on_start =
|
||||||
|
@ -440,6 +442,7 @@ void Config::SaveValues() {
|
||||||
|
|
||||||
qt_config->beginGroup("UI");
|
qt_config->beginGroup("UI");
|
||||||
WriteSetting("theme", UISettings::values.theme, UISettings::themes[0].second);
|
WriteSetting("theme", UISettings::values.theme, UISettings::themes[0].second);
|
||||||
|
WriteSetting("enable_discord_presence", UISettings::values.enable_discord_presence, true);
|
||||||
|
|
||||||
qt_config->beginGroup("Updater");
|
qt_config->beginGroup("Updater");
|
||||||
WriteSetting("check_for_update_on_start", UISettings::values.check_for_update_on_start, true);
|
WriteSetting("check_for_update_on_start", UISettings::values.check_for_update_on_start, true);
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include "citra_qt/configuration/configure_web.h"
|
#include "citra_qt/configuration/configure_web.h"
|
||||||
|
#include "citra_qt/ui_settings.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "core/telemetry_session.h"
|
#include "core/telemetry_session.h"
|
||||||
#include "ui_configure_web.h"
|
#include "ui_configure_web.h"
|
||||||
|
@ -17,6 +18,9 @@ ConfigureWeb::ConfigureWeb(QWidget* parent)
|
||||||
connect(ui->button_verify_login, &QPushButton::clicked, this, &ConfigureWeb::VerifyLogin);
|
connect(ui->button_verify_login, &QPushButton::clicked, this, &ConfigureWeb::VerifyLogin);
|
||||||
connect(this, &ConfigureWeb::LoginVerified, this, &ConfigureWeb::OnLoginVerified);
|
connect(this, &ConfigureWeb::LoginVerified, this, &ConfigureWeb::OnLoginVerified);
|
||||||
|
|
||||||
|
#ifndef USE_DISCORD_PRESENCE
|
||||||
|
ui->discord_group->setVisible(false);
|
||||||
|
#endif
|
||||||
this->setConfiguration();
|
this->setConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,10 +53,13 @@ void ConfigureWeb::setConfiguration() {
|
||||||
ui->label_telemetry_id->setText(
|
ui->label_telemetry_id->setText(
|
||||||
tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
|
tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
|
||||||
user_verified = true;
|
user_verified = true;
|
||||||
|
|
||||||
|
ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWeb::applyConfiguration() {
|
void ConfigureWeb::applyConfiguration() {
|
||||||
Settings::values.enable_telemetry = ui->toggle_telemetry->isChecked();
|
Settings::values.enable_telemetry = ui->toggle_telemetry->isChecked();
|
||||||
|
UISettings::values.enable_discord_presence = ui->toggle_discordrpc->isChecked();
|
||||||
if (user_verified) {
|
if (user_verified) {
|
||||||
Settings::values.citra_username = ui->edit_username->text().toStdString();
|
Settings::values.citra_username = ui->edit_username->text().toStdString();
|
||||||
Settings::values.citra_token = ui->edit_token->text().toStdString();
|
Settings::values.citra_token = ui->edit_token->text().toStdString();
|
||||||
|
|
|
@ -170,6 +170,22 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="discord_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Discord Presence</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_21">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="toggle_discordrpc">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show Current Game in your Discord Status</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer name="verticalSpacer">
|
<spacer name="verticalSpacer">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
|
|
25
src/citra_qt/discord.h
Normal file
25
src/citra_qt/discord.h
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright 2018 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace DiscordRPC {
|
||||||
|
|
||||||
|
class DiscordInterface {
|
||||||
|
public:
|
||||||
|
virtual ~DiscordInterface() = default;
|
||||||
|
|
||||||
|
virtual void Pause() = 0;
|
||||||
|
virtual void Update() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NullImpl : public DiscordInterface {
|
||||||
|
public:
|
||||||
|
~NullImpl() = default;
|
||||||
|
|
||||||
|
void Pause() override {}
|
||||||
|
void Update() override {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace DiscordRPC
|
51
src/citra_qt/discord_impl.cpp
Normal file
51
src/citra_qt/discord_impl.cpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright 2018 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
#include <discord_rpc.h>
|
||||||
|
#include "citra_qt/discord_impl.h"
|
||||||
|
#include "citra_qt/ui_settings.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/core.h"
|
||||||
|
|
||||||
|
namespace DiscordRPC {
|
||||||
|
|
||||||
|
DiscordImpl::DiscordImpl() {
|
||||||
|
DiscordEventHandlers handlers{};
|
||||||
|
|
||||||
|
// The number is the client ID for Citra, it's used for images and the
|
||||||
|
// application name
|
||||||
|
Discord_Initialize("461729900748079114", &handlers, 1, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
DiscordImpl::~DiscordImpl() {
|
||||||
|
Discord_ClearPresence();
|
||||||
|
Discord_Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiscordImpl::Pause() {
|
||||||
|
Discord_ClearPresence();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DiscordImpl::Update() {
|
||||||
|
s64 start_time = std::chrono::duration_cast<std::chrono::seconds>(
|
||||||
|
std::chrono::system_clock::now().time_since_epoch())
|
||||||
|
.count();
|
||||||
|
std::string title;
|
||||||
|
if (Core::System::GetInstance().IsPoweredOn())
|
||||||
|
Core::System::GetInstance().GetAppLoader().ReadTitle(title);
|
||||||
|
DiscordRichPresence presence{};
|
||||||
|
presence.largeImageKey = "citra_logo";
|
||||||
|
presence.largeImageText = "Citra is an emulator for the Nintendo 3DS";
|
||||||
|
if (Core::System::GetInstance().IsPoweredOn()) {
|
||||||
|
presence.state = title.c_str();
|
||||||
|
presence.details = "Currently in game";
|
||||||
|
} else {
|
||||||
|
presence.details = "Not in game";
|
||||||
|
}
|
||||||
|
presence.startTimestamp = start_time;
|
||||||
|
Discord_UpdatePresence(&presence);
|
||||||
|
}
|
||||||
|
} // namespace DiscordRPC
|
20
src/citra_qt/discord_impl.h
Normal file
20
src/citra_qt/discord_impl.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// Copyright 2018 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "citra_qt/discord.h"
|
||||||
|
|
||||||
|
namespace DiscordRPC {
|
||||||
|
|
||||||
|
class DiscordImpl : public DiscordInterface {
|
||||||
|
public:
|
||||||
|
DiscordImpl();
|
||||||
|
~DiscordImpl();
|
||||||
|
|
||||||
|
void Pause() override;
|
||||||
|
void Update() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace DiscordRPC
|
|
@ -34,6 +34,7 @@
|
||||||
#include "citra_qt/debugger/profiler.h"
|
#include "citra_qt/debugger/profiler.h"
|
||||||
#include "citra_qt/debugger/registers.h"
|
#include "citra_qt/debugger/registers.h"
|
||||||
#include "citra_qt/debugger/wait_tree.h"
|
#include "citra_qt/debugger/wait_tree.h"
|
||||||
|
#include "citra_qt/discord.h"
|
||||||
#include "citra_qt/game_list.h"
|
#include "citra_qt/game_list.h"
|
||||||
#include "citra_qt/hotkeys.h"
|
#include "citra_qt/hotkeys.h"
|
||||||
#include "citra_qt/main.h"
|
#include "citra_qt/main.h"
|
||||||
|
@ -58,6 +59,10 @@
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
|
|
||||||
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
|
#include "citra_qt/discord_impl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef QT_STATICPLUGIN
|
#ifdef QT_STATICPLUGIN
|
||||||
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
|
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
|
||||||
#endif
|
#endif
|
||||||
|
@ -120,6 +125,9 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) {
|
||||||
default_theme_paths = QIcon::themeSearchPaths();
|
default_theme_paths = QIcon::themeSearchPaths();
|
||||||
UpdateUITheme();
|
UpdateUITheme();
|
||||||
|
|
||||||
|
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
||||||
|
discord_rpc->Update();
|
||||||
|
|
||||||
Network::Init();
|
Network::Init();
|
||||||
|
|
||||||
InitializeWidgets();
|
InitializeWidgets();
|
||||||
|
@ -748,6 +756,7 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::ShutdownGame() {
|
void GMainWindow::ShutdownGame() {
|
||||||
|
discord_rpc->Pause();
|
||||||
emu_thread->RequestStop();
|
emu_thread->RequestStop();
|
||||||
|
|
||||||
// Release emu threads from any breakpoints
|
// Release emu threads from any breakpoints
|
||||||
|
@ -763,6 +772,8 @@ void GMainWindow::ShutdownGame() {
|
||||||
emu_thread->wait();
|
emu_thread->wait();
|
||||||
emu_thread = nullptr;
|
emu_thread = nullptr;
|
||||||
|
|
||||||
|
discord_rpc->Update();
|
||||||
|
|
||||||
Camera::QtMultimediaCameraHandler::ReleaseHandlers();
|
Camera::QtMultimediaCameraHandler::ReleaseHandlers();
|
||||||
|
|
||||||
// The emulation is stopped, so closing the window or not does not matter anymore
|
// The emulation is stopped, so closing the window or not does not matter anymore
|
||||||
|
@ -1049,6 +1060,8 @@ void GMainWindow::OnStartGame() {
|
||||||
ui.action_Stop->setEnabled(true);
|
ui.action_Stop->setEnabled(true);
|
||||||
ui.action_Restart->setEnabled(true);
|
ui.action_Restart->setEnabled(true);
|
||||||
ui.action_Report_Compatibility->setEnabled(true);
|
ui.action_Report_Compatibility->setEnabled(true);
|
||||||
|
|
||||||
|
discord_rpc->Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnPauseGame() {
|
void GMainWindow::OnPauseGame() {
|
||||||
|
@ -1184,11 +1197,14 @@ void GMainWindow::OnConfigure() {
|
||||||
connect(&configureDialog, &ConfigureDialog::languageChanged, this,
|
connect(&configureDialog, &ConfigureDialog::languageChanged, this,
|
||||||
&GMainWindow::OnLanguageChanged);
|
&GMainWindow::OnLanguageChanged);
|
||||||
auto old_theme = UISettings::values.theme;
|
auto old_theme = UISettings::values.theme;
|
||||||
|
const bool old_discord_presence = UISettings::values.enable_discord_presence;
|
||||||
auto result = configureDialog.exec();
|
auto result = configureDialog.exec();
|
||||||
if (result == QDialog::Accepted) {
|
if (result == QDialog::Accepted) {
|
||||||
configureDialog.applyConfiguration();
|
configureDialog.applyConfiguration();
|
||||||
if (UISettings::values.theme != old_theme)
|
if (UISettings::values.theme != old_theme)
|
||||||
UpdateUITheme();
|
UpdateUITheme();
|
||||||
|
if (UISettings::values.enable_discord_presence != old_discord_presence)
|
||||||
|
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
||||||
emit UpdateThemedIcons();
|
emit UpdateThemedIcons();
|
||||||
SyncMenuUISettings();
|
SyncMenuUISettings();
|
||||||
config->Save();
|
config->Save();
|
||||||
|
@ -1481,6 +1497,19 @@ void GMainWindow::RetranslateStatusBar() {
|
||||||
multiplayer_state->retranslateUi();
|
multiplayer_state->retranslateUi();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GMainWindow::SetDiscordEnabled(bool state) {
|
||||||
|
#ifdef USE_DISCORD_PRESENCE
|
||||||
|
if (state) {
|
||||||
|
discord_rpc = std::make_unique<DiscordRPC::DiscordImpl>();
|
||||||
|
} else {
|
||||||
|
discord_rpc = std::make_unique<DiscordRPC::NullImpl>();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
discord_rpc = std::make_unique<DiscordRPC::NullImpl>();
|
||||||
|
#endif
|
||||||
|
discord_rpc->Update();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef main
|
#ifdef main
|
||||||
#undef main
|
#undef main
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,6 +38,9 @@ class QProgressBar;
|
||||||
class RegistersWidget;
|
class RegistersWidget;
|
||||||
class Updater;
|
class Updater;
|
||||||
class WaitTreeWidget;
|
class WaitTreeWidget;
|
||||||
|
namespace DiscordRPC {
|
||||||
|
class DiscordInterface;
|
||||||
|
}
|
||||||
|
|
||||||
class GMainWindow : public QMainWindow {
|
class GMainWindow : public QMainWindow {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
@ -61,6 +64,7 @@ public:
|
||||||
~GMainWindow();
|
~GMainWindow();
|
||||||
|
|
||||||
GameList* game_list;
|
GameList* game_list;
|
||||||
|
std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
@ -108,6 +112,7 @@ private:
|
||||||
void ShowUpdatePrompt();
|
void ShowUpdatePrompt();
|
||||||
void ShowNoUpdatePrompt();
|
void ShowNoUpdatePrompt();
|
||||||
void CheckForUpdates();
|
void CheckForUpdates();
|
||||||
|
void SetDiscordEnabled(bool state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the filename in the recently loaded files list.
|
* Stores the filename in the recently loaded files list.
|
||||||
|
|
|
@ -58,6 +58,9 @@ struct Values {
|
||||||
bool update_on_close;
|
bool update_on_close;
|
||||||
bool check_for_update_on_start;
|
bool check_for_update_on_start;
|
||||||
|
|
||||||
|
// Discord RPC
|
||||||
|
bool enable_discord_presence;
|
||||||
|
|
||||||
QString roms_path;
|
QString roms_path;
|
||||||
QString symbols_path;
|
QString symbols_path;
|
||||||
QString game_dir_deprecated;
|
QString game_dir_deprecated;
|
||||||
|
|
Loading…
Reference in a new issue