diff --git a/Makefile.common b/Makefile.common
index 5dd66d7a87..06ff9f83eb 100644
--- a/Makefile.common
+++ b/Makefile.common
@@ -1623,6 +1623,19 @@ ifeq ($(HAVE_NETWORKING), 1)
$(LIBRETRO_COMM_DIR)/utils/md5.o
endif
+ ifeq ($(HAVE_DISCORD), 1)
+ DEFINES += -DHAVE_DISCORD
+ DEFINES += -Ideps/discord-rpc/include/ -Ideps/discord-rpc/thirdparty/rapidjson-1.1.0/include/
+ OBJ += deps/discord-rpc/src/connection_win.o \
+ deps/discord-rpc/src/discord_register_win.o \
+ deps/discord-rpc/src/discord_rpc.o \
+ deps/discord-rpc/src/rpc_connection.o \
+ deps/discord-rpc/src/serialization.o \
+ discord/discord.o
+ LIBS += -lpsapi -ladvapi32
+
+ endif
+
ifeq ($(HAVE_NETWORKGAMEPAD), 1)
OBJ += input/input_remote.o \
cores/libretro-net-retropad/net_retropad_core.o
diff --git a/command.c b/command.c
index 1606ec41a4..693d32cfa1 100644
--- a/command.c
+++ b/command.c
@@ -44,6 +44,10 @@
#include "cheevos/var.h"
#endif
+#ifdef HAVE_DISCORD
+#include "discord/discord.h"
+#endif
+
#ifdef HAVE_MENU
#include "menu/menu_driver.h"
#include "menu/menu_content.h"
@@ -1275,8 +1279,8 @@ static bool command_event_init_core(enum rarch_core_type *data)
if (!core_load(settings->uints.input_poll_type_behavior))
return false;
- rarch_ctl(RARCH_CTL_SET_FRAME_LIMIT, NULL);
+ rarch_ctl(RARCH_CTL_SET_FRAME_LIMIT, NULL);
return true;
}
diff --git a/discord/discord.c b/discord/discord.c
new file mode 100644
index 0000000000..c8b5f527f7
--- /dev/null
+++ b/discord/discord.c
@@ -0,0 +1,121 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2018 - Andrés Suárez
+ *
+ * RetroArch 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 Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch 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 RetroArch.
+ * If not, see .
+ */
+
+#include "discord.h"
+
+static const char* APPLICATION_ID = "450822022025576457";
+static int FrustrationLevel = 0;
+static int64_t start_time;
+
+static bool discord_ready = false;
+static unsigned discord_status = 0;
+
+DiscordRichPresence discord_presence;
+
+static void handle_discord_ready(const DiscordUser* connectedUser)
+{
+ RARCH_LOG("[discord] connected to user %s#%s - %s\n",
+ connectedUser->username,
+ connectedUser->discriminator,
+ connectedUser->userId);
+}
+
+static void handle_discord_disconnected(int errcode, const char* message)
+{
+ RARCH_LOG("[discord] disconnected (%d: %s)\n", errcode, message);
+}
+
+static void handle_discord_error(int errcode, const char* message)
+{
+ RARCH_LOG("[discord] error (%d: %s)\n", errcode, message);
+}
+
+static void handle_discord_join(const char* secret)
+{
+ RARCH_LOG("[discord] join (%s)\n", secret);
+}
+
+static void handle_discord_spectate(const char* secret)
+{
+ RARCH_LOG("[discord] spectate (%s)\n", secret);
+}
+
+static void handle_discord_join_request(const DiscordUser* request)
+{
+ int response = -1;
+ char yn[4];
+ RARCH_LOG("[discord] join request from %s#%s - %s\n",
+ request->username,
+ request->discriminator,
+ request->userId);
+}
+
+void discord_update(unsigned presence)
+{
+ if (!discord_ready || discord_status != DISCORD_PRESENCE_MENU && discord_status == presence)
+ return;
+
+ RARCH_LOG("[discord] updating (%d)\n", presence);
+ memset(&discord_presence, 0, sizeof(discord_presence));
+
+ switch (presence)
+ {
+ case DISCORD_PRESENCE_MENU:
+ discord_presence.state = "In-Menu";
+ discord_presence.largeImageKey = "icon";
+ discord_presence.instance = 0;
+ discord_presence.startTimestamp = start_time;
+ break;
+ case DISCORD_PRESENCE_GAME:
+ start_time = time(0);
+ discord_presence.state = "Link's House";
+ discord_presence.details = "Legend of Zelda, The - Link's Awakening DX";
+ discord_presence.largeImageKey = "icon";
+ //discord_presence.smallImageKey = "icon";
+ discord_presence.instance = 0;
+ discord_presence.startTimestamp = start_time;
+ break;
+ default:
+ break;
+ }
+ Discord_UpdatePresence(&discord_presence);
+ discord_status = presence;
+}
+
+void discord_init()
+{
+ RARCH_LOG("[discord] initializing\n");
+ start_time = time(0);
+
+ DiscordEventHandlers handlers;
+ memset(&handlers, 0, sizeof(handlers));
+ handlers.ready = handle_discord_ready;
+ handlers.disconnected = handle_discord_disconnected;
+ handlers.errored = handle_discord_error;
+ handlers.joinGame = handle_discord_join;
+ handlers.spectateGame = handle_discord_spectate;
+ handlers.joinRequest = handle_discord_join_request;
+ Discord_Initialize(APPLICATION_ID, &handlers, 1, NULL);
+
+ discord_ready = true;
+}
+
+void discord_shutdown()
+{
+ RARCH_LOG("[discord] shutting down\n");
+ Discord_ClearPresence();
+ Discord_Shutdown();
+ discord_ready = false;
+}
\ No newline at end of file
diff --git a/discord/discord.h b/discord/discord.h
new file mode 100644
index 0000000000..0db386bc5e
--- /dev/null
+++ b/discord/discord.h
@@ -0,0 +1,47 @@
+/* RetroArch - A frontend for libretro.
+ * Copyright (C) 2018 - Andrés Suárez
+ *
+ * RetroArch 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 Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * RetroArch 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 RetroArch.
+ * If not, see .
+ */
+
+#ifndef __RARCH_DISCORD_H
+#define __RARCH_DISCORD_H
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#include "discord_rpc.h"
+#include "verbosity.h"
+
+enum discord_presence
+{
+ DISCORD_PRESENCE_MENU = 0,
+ DISCORD_PRESENCE_GAME,
+ DISCORD_PRESENCE_CHEEVO_UNLOCKED,
+ DISCORD_PRESENCE_NETPLAY_HOSTING,
+ DISCORD_PRESENCE_NETPLAY_CLIENT
+};
+
+
+void discord_init();
+void discord_shutdown();
+void discord_update(unsigned presence);
+
+#endif /* __RARCH_DISCORD_H */
diff --git a/media/canvas.png b/media/canvas.png
index 9db4f97136..4bc25c0035 100644
Binary files a/media/canvas.png and b/media/canvas.png differ
diff --git a/qb/config.libs.sh b/qb/config.libs.sh
index e36974ceef..ab7bf0f0d6 100644
--- a/qb/config.libs.sh
+++ b/qb/config.libs.sh
@@ -213,6 +213,7 @@ else
HAVE_NETWORK_CMD='no'
HAVE_NETWORKGAMEPAD='no'
HAVE_CHEEVOS='no'
+ HAVE_DISCORD='no'
fi
check_lib '' STDIN_CMD "$CLIB" fcntl
diff --git a/qb/config.params.sh b/qb/config.params.sh
index 487bc003a5..af48758f53 100644
--- a/qb/config.params.sh
+++ b/qb/config.params.sh
@@ -105,6 +105,7 @@ HAVE_QT=auto # Qt companion support
C89_QT=no
HAVE_XSHM=no # XShm video driver support
HAVE_CHEEVOS=yes # Retro Achievements
+HAVE_DISCORD=yes # Discord Integration
HAVE_SHADERPIPELINE=yes # Additional shader-based pipelines
C89_SHADERPIPELINE=no
HAVE_VULKAN=auto # Vulkan support
diff --git a/retroarch.c b/retroarch.c
index e26f3128a9..d20b2fc28e 100644
--- a/retroarch.c
+++ b/retroarch.c
@@ -70,6 +70,10 @@
#include "cheevos/cheevos.h"
#endif
+#ifdef HAVE_DISCORD
+#include "discord/discord.h"
+#endif
+
#ifdef HAVE_NETWORKING
#include "network/netplay/netplay.h"
#endif
@@ -1374,9 +1378,13 @@ bool retroarch_main_init(int argc, char *argv[])
rarch_error_on_init = false;
rarch_is_inited = true;
+#ifdef HAVE_DISCORD
+ discord_init();
+ discord_update(DISCORD_PRESENCE_MENU);
+#endif
+
if (rarch_first_start)
rarch_first_start = false;
-
return true;
error:
@@ -1384,7 +1392,7 @@ error:
rarch_is_inited = false;
if (rarch_first_start)
- rarch_first_start = false;
+ rarch_first_start = false;
return false;
}
@@ -2322,6 +2330,10 @@ bool retroarch_main_quit(void)
runloop_shutdown_initiated = true;
rarch_menu_running_finished();
+#ifdef HAVE_DISCORD
+ discord_shutdown();
+#endif
+
return true;
}
@@ -3325,6 +3337,9 @@ int runloop_iterate(unsigned *sleep_ms)
if (runloop_check_cheevos())
cheevos_test();
#endif
+#ifdef HAVE_DISCORD
+ discord_update(DISCORD_PRESENCE_GAME);
+#endif
for (i = 0; i < max_users; i++)
{