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++) {