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:
		
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -34,3 +34,6 @@ | ||||
| [submodule "cubeb"] | ||||
|     path = externals/cubeb | ||||
|     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 | ||||
| ENABLE_COMPATIBILITY_REPORTING | ||||
| USE_DISCORD_PRESENCE | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| cd /citra | ||||
|  | ||||
| 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 | ||||
|  | ||||
| ctest -VV -C Release | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| cd /citra | ||||
|  | ||||
| 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 | ||||
|  | ||||
| ctest -VV -C Release | ||||
|   | ||||
| @@ -7,7 +7,7 @@ export Qt5_DIR=$(brew --prefix)/opt/qt5 | ||||
| export PATH="/usr/local/opt/ccache/libexec:$PATH" | ||||
|  | ||||
| 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 | ||||
|  | ||||
| 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(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF) | ||||
|  | ||||
| if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit) | ||||
|     message(STATUS "Copying pre-commit hook") | ||||
|     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} | ||||
|         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 | ||||
|           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 { | ||||
|           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 .. | ||||
|  | ||||
|   | ||||
							
								
								
									
										18
									
								
								externals/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								externals/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -62,6 +62,18 @@ endif() | ||||
| add_subdirectory(enet) | ||||
| 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) | ||||
|     # LibreSSL | ||||
|     set(LIBRESSL_SKIP_INSTALL ON CACHE BOOL "") | ||||
| @@ -80,9 +92,3 @@ if (ENABLE_WEB_SERVICE) | ||||
|     add_library(json-headers INTERFACE) | ||||
|     target_include_directories(json-headers INTERFACE ./json) | ||||
| 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
									
								
							 Submodule externals/discord-rpc added at 3d3ae7129d
									
								
							| @@ -68,6 +68,7 @@ add_executable(citra-qt | ||||
|     debugger/registers.h | ||||
|     debugger/wait_tree.cpp | ||||
|     debugger/wait_tree.h | ||||
|     discord.h | ||||
|     game_list.cpp | ||||
|     game_list.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 ${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) | ||||
|     install(TARGETS citra-qt RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") | ||||
| endif() | ||||
|   | ||||
| @@ -207,6 +207,8 @@ void Config::ReadValues() { | ||||
|  | ||||
|     qt_config->beginGroup("UI"); | ||||
|     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"); | ||||
|     UISettings::values.check_for_update_on_start = | ||||
| @@ -440,6 +442,7 @@ void Config::SaveValues() { | ||||
|  | ||||
|     qt_config->beginGroup("UI"); | ||||
|     WriteSetting("theme", UISettings::values.theme, UISettings::themes[0].second); | ||||
|     WriteSetting("enable_discord_presence", UISettings::values.enable_discord_presence, true); | ||||
|  | ||||
|     qt_config->beginGroup("Updater"); | ||||
|     WriteSetting("check_for_update_on_start", UISettings::values.check_for_update_on_start, true); | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include <QIcon> | ||||
| #include <QMessageBox> | ||||
| #include "citra_qt/configuration/configure_web.h" | ||||
| #include "citra_qt/ui_settings.h" | ||||
| #include "core/settings.h" | ||||
| #include "core/telemetry_session.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(this, &ConfigureWeb::LoginVerified, this, &ConfigureWeb::OnLoginVerified); | ||||
|  | ||||
| #ifndef USE_DISCORD_PRESENCE | ||||
|     ui->discord_group->setVisible(false); | ||||
| #endif | ||||
|     this->setConfiguration(); | ||||
| } | ||||
|  | ||||
| @@ -49,10 +53,13 @@ void ConfigureWeb::setConfiguration() { | ||||
|     ui->label_telemetry_id->setText( | ||||
|         tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper())); | ||||
|     user_verified = true; | ||||
|  | ||||
|     ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence); | ||||
| } | ||||
|  | ||||
| void ConfigureWeb::applyConfiguration() { | ||||
|     Settings::values.enable_telemetry = ui->toggle_telemetry->isChecked(); | ||||
|     UISettings::values.enable_discord_presence = ui->toggle_discordrpc->isChecked(); | ||||
|     if (user_verified) { | ||||
|         Settings::values.citra_username = ui->edit_username->text().toStdString(); | ||||
|         Settings::values.citra_token = ui->edit_token->text().toStdString(); | ||||
|   | ||||
| @@ -170,6 +170,22 @@ | ||||
|      </item> | ||||
|     </layout> | ||||
|    </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> | ||||
|     <spacer name="verticalSpacer"> | ||||
|      <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/registers.h" | ||||
| #include "citra_qt/debugger/wait_tree.h" | ||||
| #include "citra_qt/discord.h" | ||||
| #include "citra_qt/game_list.h" | ||||
| #include "citra_qt/hotkeys.h" | ||||
| #include "citra_qt/main.h" | ||||
| @@ -58,6 +59,10 @@ | ||||
| #include "core/loader/loader.h" | ||||
| #include "core/settings.h" | ||||
|  | ||||
| #ifdef USE_DISCORD_PRESENCE | ||||
| #include "citra_qt/discord_impl.h" | ||||
| #endif | ||||
|  | ||||
| #ifdef QT_STATICPLUGIN | ||||
| Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); | ||||
| #endif | ||||
| @@ -120,6 +125,9 @@ GMainWindow::GMainWindow() : config(new Config()), emu_thread(nullptr) { | ||||
|     default_theme_paths = QIcon::themeSearchPaths(); | ||||
|     UpdateUITheme(); | ||||
|  | ||||
|     SetDiscordEnabled(UISettings::values.enable_discord_presence); | ||||
|     discord_rpc->Update(); | ||||
|  | ||||
|     Network::Init(); | ||||
|  | ||||
|     InitializeWidgets(); | ||||
| @@ -748,6 +756,7 @@ void GMainWindow::BootGame(const QString& filename) { | ||||
| } | ||||
|  | ||||
| void GMainWindow::ShutdownGame() { | ||||
|     discord_rpc->Pause(); | ||||
|     emu_thread->RequestStop(); | ||||
|  | ||||
|     // Release emu threads from any breakpoints | ||||
| @@ -763,6 +772,8 @@ void GMainWindow::ShutdownGame() { | ||||
|     emu_thread->wait(); | ||||
|     emu_thread = nullptr; | ||||
|  | ||||
|     discord_rpc->Update(); | ||||
|  | ||||
|     Camera::QtMultimediaCameraHandler::ReleaseHandlers(); | ||||
|  | ||||
|     // 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_Restart->setEnabled(true); | ||||
|     ui.action_Report_Compatibility->setEnabled(true); | ||||
|  | ||||
|     discord_rpc->Update(); | ||||
| } | ||||
|  | ||||
| void GMainWindow::OnPauseGame() { | ||||
| @@ -1184,11 +1197,14 @@ void GMainWindow::OnConfigure() { | ||||
|     connect(&configureDialog, &ConfigureDialog::languageChanged, this, | ||||
|             &GMainWindow::OnLanguageChanged); | ||||
|     auto old_theme = UISettings::values.theme; | ||||
|     const bool old_discord_presence = UISettings::values.enable_discord_presence; | ||||
|     auto result = configureDialog.exec(); | ||||
|     if (result == QDialog::Accepted) { | ||||
|         configureDialog.applyConfiguration(); | ||||
|         if (UISettings::values.theme != old_theme) | ||||
|             UpdateUITheme(); | ||||
|         if (UISettings::values.enable_discord_presence != old_discord_presence) | ||||
|             SetDiscordEnabled(UISettings::values.enable_discord_presence); | ||||
|         emit UpdateThemedIcons(); | ||||
|         SyncMenuUISettings(); | ||||
|         config->Save(); | ||||
| @@ -1481,6 +1497,19 @@ void GMainWindow::RetranslateStatusBar() { | ||||
|     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 | ||||
| #undef main | ||||
| #endif | ||||
|   | ||||
| @@ -38,6 +38,9 @@ class QProgressBar; | ||||
| class RegistersWidget; | ||||
| class Updater; | ||||
| class WaitTreeWidget; | ||||
| namespace DiscordRPC { | ||||
| class DiscordInterface; | ||||
| } | ||||
|  | ||||
| class GMainWindow : public QMainWindow { | ||||
|     Q_OBJECT | ||||
| @@ -61,6 +64,7 @@ public: | ||||
|     ~GMainWindow(); | ||||
|  | ||||
|     GameList* game_list; | ||||
|     std::unique_ptr<DiscordRPC::DiscordInterface> discord_rpc; | ||||
|  | ||||
| signals: | ||||
|  | ||||
| @@ -108,6 +112,7 @@ private: | ||||
|     void ShowUpdatePrompt(); | ||||
|     void ShowNoUpdatePrompt(); | ||||
|     void CheckForUpdates(); | ||||
|     void SetDiscordEnabled(bool state); | ||||
|  | ||||
|     /** | ||||
|      * Stores the filename in the recently loaded files list. | ||||
|   | ||||
| @@ -58,6 +58,9 @@ struct Values { | ||||
|     bool update_on_close; | ||||
|     bool check_for_update_on_start; | ||||
|  | ||||
|     // Discord RPC | ||||
|     bool enable_discord_presence; | ||||
|  | ||||
|     QString roms_path; | ||||
|     QString symbols_path; | ||||
|     QString game_dir_deprecated; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Vamsi Krishna
					Vamsi Krishna