diff --git a/scripts/appimage/make-appimage.sh b/scripts/appimage/make-appimage.sh index 31b7898d6..747b8f308 100755 --- a/scripts/appimage/make-appimage.sh +++ b/scripts/appimage/make-appimage.sh @@ -56,6 +56,7 @@ APPDIRNAME=DuckStation.AppDir STRIP=strip declare -a MANUAL_LIBS=( + "libdiscord-rpc.so" "libshaderc_shared.so" "libspirv-cross-c-shared.so" ) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 6218ee8be..02c661d31 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -182,11 +182,6 @@ if(CPU_ARCH_RISCV64) message(STATUS "Building RISC-V 64-bit recompiler.") endif() -if(NOT ANDROID) - target_compile_definitions(core PUBLIC -DENABLE_DISCORD_PRESENCE=1) - target_link_libraries(core PRIVATE DiscordRPC::discord-rpc) -endif() - # Copy the provided data directory to the output directory. Borrowed from PCSX2. function(add_resources target path basedir) get_filename_component(dir ${path} DIRECTORY) diff --git a/src/core/achievements.cpp b/src/core/achievements.cpp index e688da1f6..61fbbdd5c 100644 --- a/src/core/achievements.cpp +++ b/src/core/achievements.cpp @@ -801,11 +801,9 @@ void Achievements::UpdateRichPresence(std::unique_lock& lo INFO_LOG("Rich presence updated: {}", s_rich_presence_string); Host::OnAchievementsRefreshed(); -#ifdef ENABLE_DISCORD_PRESENCE lock.unlock(); - System::UpdateDiscordPresence(false); + System::UpdateRichPresence(false); lock.lock(); -#endif } void Achievements::GameChanged(const std::string& path, CDImage* image) diff --git a/src/core/core.props b/src/core/core.props index 23de0f982..ca0ad89c5 100644 --- a/src/core/core.props +++ b/src/core/core.props @@ -4,7 +4,6 @@ - ENABLE_DISCORD_PRESENCE=1;%(PreprocessorDefinitions) ENABLE_RAINTEGRATION=1;%(PreprocessorDefinitions) ENABLE_RECOMPILER=1;%(PreprocessorDefinitions) ENABLE_MMAP_FASTMEM=1;%(PreprocessorDefinitions) diff --git a/src/core/fullscreen_ui.cpp b/src/core/fullscreen_ui.cpp index c87efa5f2..39306c864 100644 --- a/src/core/fullscreen_ui.cpp +++ b/src/core/fullscreen_ui.cpp @@ -3148,12 +3148,10 @@ void FullscreenUI::DrawInterfaceSettingsPage() } } -#ifdef ENABLE_DISCORD_PRESENCE MenuHeading(FSUI_CSTR("Integration")); DrawToggleSetting(bsi, FSUI_ICONSTR(ICON_FA_CHARGING_STATION, "Enable Discord Presence"), FSUI_CSTR("Shows the game you are currently playing as part of your profile in Discord."), "Main", "EnableDiscordPresence", false); -#endif MenuHeading(FSUI_CSTR("On-Screen Display")); DrawIntSpinBoxSetting(bsi, FSUI_ICONSTR(ICON_FA_SEARCH, "OSD Scale"), diff --git a/src/core/system.cpp b/src/core/system.cpp index 83e828334..116e3b4c6 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -47,6 +47,7 @@ #include "util/state_wrapper.h" #include "common/align.h" +#include "common/dynamic_library.h" #include "common/error.h" #include "common/file_system.h" #include "common/log.h" @@ -77,11 +78,8 @@ Log_SetChannel(System); #include #endif -#ifdef ENABLE_DISCORD_PRESENCE -#include "discord_rpc.h" -#endif - #ifndef __ANDROID__ +#define ENABLE_DISCORD_PRESENCE 1 #define ENABLE_PINE_SERVER 1 #define ENABLE_GDB_SERVER 1 #define ENABLE_SOCKET_MULTIPLEXER 1 @@ -1957,9 +1955,7 @@ void System::ClearRunningGame() Achievements::GameChanged(s_running_game_path, nullptr); -#ifdef ENABLE_DISCORD_PRESENCE - UpdateDiscordPresence(true); -#endif + UpdateRichPresence(true); } void System::Execute() @@ -3791,9 +3787,7 @@ void System::UpdateRunningGame(const char* path, CDImage* image, bool booting) else SaveStateSelectorUI::ClearList(); -#ifdef ENABLE_DISCORD_PRESENCE - UpdateDiscordPresence(booting); -#endif + UpdateRichPresence(booting); Host::OnGameChanged(s_running_game_path, s_running_game_serial, s_running_game_title); } @@ -5467,16 +5461,80 @@ void System::ReleaseSocketMultiplexer() #ifdef ENABLE_DISCORD_PRESENCE +#include "discord_rpc.h" + +#define DISCORD_RPC_FUNCTIONS(X) \ + X(Discord_Initialize) \ + X(Discord_Shutdown) \ + X(Discord_RunCallbacks) \ + X(Discord_UpdatePresence) \ + X(Discord_ClearPresence) + +namespace dyn_libs { +static bool OpenDiscordRPC(Error* error); +static void CloseDiscordRPC(); + +static DynamicLibrary s_discord_rpc_library; + +#define ADD_FUNC(F) static decltype(&::F) F; +DISCORD_RPC_FUNCTIONS(ADD_FUNC) +#undef ADD_FUNC +} // namespace dyn_libs + +bool dyn_libs::OpenDiscordRPC(Error* error) +{ + if (s_discord_rpc_library.IsOpen()) + return true; + + const std::string libname = DynamicLibrary::GetVersionedFilename("discord-rpc"); + if (!s_discord_rpc_library.Open(libname.c_str(), error)) + { + Error::AddPrefix(error, "Failed to load discord-rpc: "); + return false; + } + +#define LOAD_FUNC(F) \ + if (!s_discord_rpc_library.GetSymbol(#F, &F)) \ + { \ + Error::SetStringFmt(error, "Failed to find function {}", #F); \ + CloseDiscordRPC(); \ + return false; \ + } + DISCORD_RPC_FUNCTIONS(LOAD_FUNC) +#undef LOAD_FUNC + + return true; +} + +void dyn_libs::CloseDiscordRPC() +{ + if (!s_discord_rpc_library.IsOpen()) + return; + +#define UNLOAD_FUNC(F) F = nullptr; + DISCORD_RPC_FUNCTIONS(UNLOAD_FUNC) +#undef UNLOAD_FUNC + + s_discord_rpc_library.Close(); +} + void System::InitializeDiscordPresence() { if (s_discord_presence_active) return; + Error error; + if (!dyn_libs::OpenDiscordRPC(&error)) + { + ERROR_LOG("Failed to open discord-rpc: {}", error.GetDescription()); + return; + } + DiscordEventHandlers handlers = {}; - Discord_Initialize("705325712680288296", &handlers, 0, nullptr); + dyn_libs::Discord_Initialize("705325712680288296", &handlers, 0, nullptr); s_discord_presence_active = true; - UpdateDiscordPresence(true); + UpdateRichPresence(true); } void System::ShutdownDiscordPresence() @@ -5484,12 +5542,14 @@ void System::ShutdownDiscordPresence() if (!s_discord_presence_active) return; - Discord_ClearPresence(); - Discord_Shutdown(); + dyn_libs::Discord_ClearPresence(); + dyn_libs::Discord_Shutdown(); + dyn_libs::CloseDiscordRPC(); + s_discord_presence_active = false; } -void System::UpdateDiscordPresence(bool update_session_time) +void System::UpdateRichPresence(bool update_session_time) { if (!s_discord_presence_active) return; @@ -5525,7 +5585,7 @@ void System::UpdateDiscordPresence(bool update_session_time) rp.state = state_string.c_str(); } - Discord_UpdatePresence(&rp); + dyn_libs::Discord_UpdatePresence(&rp); } void System::PollDiscordPresence() @@ -5533,7 +5593,13 @@ void System::PollDiscordPresence() if (!s_discord_presence_active) return; - Discord_RunCallbacks(); + dyn_libs::Discord_RunCallbacks(); +} + +#else + +void System::UpdateRichPresence(bool update_session_time) +{ } #endif diff --git a/src/core/system.h b/src/core/system.h index 19119ee79..1230242c3 100644 --- a/src/core/system.h +++ b/src/core/system.h @@ -495,10 +495,8 @@ void SetRunaheadReplayFlag(); SocketMultiplexer* GetSocketMultiplexer(); void ReleaseSocketMultiplexer(); -#ifdef ENABLE_DISCORD_PRESENCE /// Called when rich presence changes. -void UpdateDiscordPresence(bool update_session_time); -#endif +void UpdateRichPresence(bool update_session_time); namespace Internal { /// Performs mandatory hardware checks. diff --git a/src/util/util.props b/src/util/util.props index 0c90a3fdb..486fd31e3 100644 --- a/src/util/util.props +++ b/src/util/util.props @@ -27,7 +27,7 @@ %(AdditionalIncludeDirectories);$(DepsIncludeDir)SDL2 - %(AdditionalDependencies);cpuinfo.lib;discord-rpc.lib;freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;SDL2.lib;zlib.lib;zstd.lib + %(AdditionalDependencies);cpuinfo.lib;freetype.lib;libjpeg.lib;libpng16.lib;libwebp.lib;SDL2.lib;zlib.lib;zstd.lib