diff --git a/backends/module.mk b/backends/module.mk index 823c2f4bf3f..c2228d96fef 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -157,6 +157,11 @@ ifdef USE_OPENGL MODULE_OBJS += \ graphics/openglsdl/openglsdl-graphics.o endif + +ifdef USE_DISCORD +MODULE_OBJS += \ + presence/discord/discord.o +endif endif ifdef POSIX diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 85e56bd2083..8e92c97ed60 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -30,6 +30,10 @@ #include "common/translation.h" #include "common/encoding.h" +#ifdef USE_DISCORD +#include "backends/presence/discord/discord.h" +#endif + #include "backends/saves/default/default-saves.h" // Audio CD support was removed with SDL 2.0 @@ -128,6 +132,11 @@ OSystem_SDL::~OSystem_SDL() { delete _logger; _logger = 0; +#ifdef USE_DISCORD + delete _presence; + _presence = 0; +#endif + #ifdef USE_SDL_NET if (_initedSDLnet) SDLNet_Quit(); #endif @@ -263,6 +272,10 @@ void OSystem_SDL::initBackend() { // Setup a custom program icon. _window->setupIcon(); +#ifdef USE_DISCORD + _presence = new DiscordPresence(); +#endif + _inited = true; BaseBackend::initBackend(); @@ -284,9 +297,14 @@ void OSystem_SDL::engineInit() { // Add the started engine to the list of recent tasks _taskbarManager->addRecent(ConfMan.getActiveDomainName(), ConfMan.get("description")); - // Set the overlay icon the current running engine + // Set the overlay icon to the current running engine _taskbarManager->setOverlayIcon(ConfMan.getActiveDomainName(), ConfMan.get("description")); #endif +#ifdef USE_DISCORD + // Set the presence status to the current running engine + _presence->updateStatus(ConfMan.getActiveDomainName(), ConfMan.get("description")); +#endif + _eventSource->setEngineRunning(true); } @@ -298,6 +316,10 @@ void OSystem_SDL::engineDone() { #ifdef USE_TASKBAR // Remove overlay icon _taskbarManager->setOverlayIcon("", ""); +#endif +#ifdef USE_DISCORD + // Reset presence status + _presence->updateStatus("", ""); #endif _eventSource->setEngineRunning(false); } diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 763e74bde4a..19142c8a003 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -33,6 +33,10 @@ #include "common/array.h" +#ifdef USE_DISCORD +class DiscordPresence; +#endif + /** * Base OSystem class for all SDL ports. */ @@ -90,6 +94,10 @@ protected: bool _initedSDLnet; #endif +#ifdef USE_DISCORD + DiscordPresence *_presence; +#endif + /** * The path of the currently open log file, if any. * diff --git a/backends/presence/discord/discord.cpp b/backends/presence/discord/discord.cpp new file mode 100644 index 00000000000..8350e4ad01a --- /dev/null +++ b/backends/presence/discord/discord.cpp @@ -0,0 +1,70 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifdef USE_DISCORD + +#define FORBIDDEN_SYMBOL_EXCEPTION_time_h +#include "backends/presence/discord/discord.h" +#include "common/encoding.h" +#include "common/translation.h" + +#include +#include + +#define DISCORD_CLIENT_ID "714287866464698470" + +DiscordPresence::DiscordPresence() { + Discord_Initialize(DISCORD_CLIENT_ID, nullptr, 0, nullptr); + updateStatus("", ""); +} + +DiscordPresence::~DiscordPresence() { + Discord_ClearPresence(); + Discord_Shutdown(); +} + +void DiscordPresence::updateStatus(const Common::String &name, const Common::String &description) { + Common::String gameName = name.empty() ? "scummvm" : name; + Common::String gameDesc = description.empty() ? _("Launcher") : description; + + DiscordRichPresence presence; + memset(&presence, 0, sizeof(presence)); + presence.largeImageKey = gameName.c_str(); +#ifdef USE_TRANSLATION + char *gameDescUtf8 = Common::Encoding::convert("utf-8", TransMan.getCurrentCharset(), gameDesc.c_str(), gameDesc.size()); + presence.largeImageText = gameDescUtf8; + presence.details = gameDescUtf8; +#else + presence.largeImageText = gameDesc.c_str(); + presence.details = gameDesc.c_str(); +#endif + presence.smallImageKey = "scummvm"; + presence.smallImageText = "ScummVM"; + presence.startTimestamp = time(0); + Discord_UpdatePresence(&presence); + +#ifdef USE_TRANSLATION + free(gameDescUtf8); +#endif +} + +#endif diff --git a/backends/presence/discord/discord.h b/backends/presence/discord/discord.h new file mode 100644 index 00000000000..7236a4b9730 --- /dev/null +++ b/backends/presence/discord/discord.h @@ -0,0 +1,50 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BACKENDS_DISCORD_H +#define BACKENDS_DISCORD_H + +#ifdef USE_DISCORD + +#include "common/scummsys.h" +#include "common/str.h" + +/** + * Manager for interacting with the Discord Rich Presence API. + */ +class DiscordPresence { +public: + DiscordPresence(); + ~DiscordPresence(); + /** + * Updates the Discord presence status with game information. + * Blank parameters default to no game running (Launcher). + * + * @param name Game ID and icon to display. + * @param description Game name to display. + */ + void updateStatus(const Common::String &name, const Common::String &description); +}; + +#endif + +#endif diff --git a/configure b/configure index c868979edef..16b3bd2913f 100755 --- a/configure +++ b/configure @@ -169,6 +169,7 @@ _iconv=auto _tts=auto _gtk=auto _fribidi=auto +_discord=auto _test_cxx11=no # Default option behavior yes/no _debug_build=auto @@ -1158,6 +1159,9 @@ Optional Libraries: --with-iconv-prefix=DIR prefix where libiconv is installed (optional) --disable-iconv disable libiconv encoding conversion library [autodetect] + --with-discord-prefix=DIR prefix where discord-rpc is installed (optional) + --disable-discord disable Discord rich presence integration [autodetect] + Some influential environment variables: AR archiver command AS assembler command @@ -1289,6 +1293,8 @@ for ac_option in $@; do --disable-gtk) _gtk=no ;; --enable-bink) _bink=yes ;; --disable-bink) _bink=no ;; + --enable-discord) _discord=yes ;; + --disable-discord) _discord=no ;; --opengl-mode=*) _opengl_mode=`echo $ac_option | cut -d '=' -f 2` ;; @@ -1425,6 +1431,11 @@ for ac_option in $@; do ICONV_CFLAGS="-I$arg/include" ICONV_LIBS="-L$arg/lib" ;; + --with-discord-prefix=*) + arg=`echo $ac_option | cut -d '=' -f 2` + DISCORD_CFLAGS="-I$arg/include" + DISCORD_LIBS="-L$arg/lib" + ;; --backend=*) _backend=`echo $ac_option | cut -d '=' -f 2` ;; @@ -5441,6 +5452,25 @@ if test "$_pandocext" = "default"; then fi fi +# +# Check for Discord +# +echocheck "Discord RPC" +if test "$_discord" = auto ; then + _discord=no + cat > $TMPC << EOF +#include +int main(void) { Discord_Shutdown(); return 0; } +EOF + cc_check $DISCORD_CFLAGS $DISCORD_LIBS -ldiscord-rpc && _discord=yes +fi +if test "$_discord" = yes ; then + append_var LIBS "$DISCORD_LIBS -ldiscord-rpc" + append_var INCLUDES "$DISCORD_CFLAGS" +fi +define_in_config_if_yes "$_discord" 'USE_DISCORD' +echo "$_discord" + # # Enable vkeybd / event recorder # diff --git a/devtools/create_project/cmake.cpp b/devtools/create_project/cmake.cpp index a8fb03044ed..3c69a0d4089 100644 --- a/devtools/create_project/cmake.cpp +++ b/devtools/create_project/cmake.cpp @@ -52,6 +52,7 @@ const CMakeProvider::Library *CMakeProvider::getLibraryFromFeature(const char *f { "fluidsynth",kSDLVersionAny, 0, 0, 0, 0, "fluidsynth" }, { "faad", kSDLVersionAny, 0, 0, 0, 0, "faad" }, { "fribidi", kSDLVersionAny, 0, 0, 0, 0, "fribidi" }, + { "discord", kSDLVersionAny, 0, 0, 0, 0, "discord-rpc"}, { "libcurl", kSDLVersionAny, "FindCURL", "CURL", "CURL_INCLUDE_DIRS", "CURL_LIBRARIES", 0 }, { "sdlnet", kSDLVersion1, "FindSDL_net", "SDL_net", "SDL_NET_INCLUDE_DIRS", "SDL_NET_LIBRARIES", 0 }, { "sdlnet", kSDLVersion2, 0, 0, 0, 0, "SDL2_net" } diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp index 3054ac8e50e..079e5da8efd 100644 --- a/devtools/create_project/create_project.cpp +++ b/devtools/create_project/create_project.cpp @@ -1032,6 +1032,7 @@ const Feature s_features[] = { {"fluidsynth", "USE_FLUIDSYNTH", true, true, "FluidSynth support" }, { "libcurl", "USE_LIBCURL", true, true, "libcurl support" }, { "sdlnet", "USE_SDL_NET", true, true, "SDL_net support" }, + { "discord", "USE_DISCORD", true, false, "Discord support" }, // Feature flags { "bink", "USE_BINK", false, true, "Bink video support" }, diff --git a/devtools/create_project/msvc.cpp b/devtools/create_project/msvc.cpp index 75c53bfc105..2d02d70560b 100644 --- a/devtools/create_project/msvc.cpp +++ b/devtools/create_project/msvc.cpp @@ -74,6 +74,7 @@ std::string MSVCProvider::getLibraryFromFeature(const char *feature, const Build { "libcurl", "libcurl.lib", "libcurl-d.lib", "ws2_32.lib wldap32.lib crypt32.lib normaliz.lib", 0 }, { "sdlnet", "SDL_net.lib", 0, "iphlpapi.lib", 0 }, { "sdl2net", "SDL2_net.lib", 0, "iphlpapi.lib", "SDL_net.lib" }, + { "discord", "discord-rpc.lib", 0, 0, 0 }, // Feature flags with library dependencies { "updates", "winsparkle.lib", 0, 0, 0 }, { "tts", 0, 0, "sapi.lib", 0 } diff --git a/devtools/create_project/xcode.cpp b/devtools/create_project/xcode.cpp index 42f774d279c..368c5d250d7 100644 --- a/devtools/create_project/xcode.cpp +++ b/devtools/create_project/xcode.cpp @@ -497,6 +497,9 @@ void XcodeProvider::setupFrameworksBuildPhase(const BuildSetup &setup) { if (CONTAINS_DEFINE(setup.defines, "USE_ZLIB")) { DEF_SYSTBD("libz"); } + if (CONTAINS_DEFINE(setup.defines, "USE_DISCORD")) { + DEF_LOCALLIB_STATIC("libdiscord-rpc"); + } if (setup.useSDL2) { DEF_LOCALLIB_STATIC("libSDL2main"); diff --git a/po/POTFILES b/po/POTFILES index c7ef3158636..fcb2c0caa68 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -86,4 +86,5 @@ backends/platform/sdl/macosx/appmenu_osx.mm backends/platform/sdl/ps3/ps3.cpp backends/platform/symbian/src/SymbianActions.cpp backends/platform/wii/options.cpp +backends/presence/discord/discord.cpp backends/updates/macosx/macosx-updates.mm