Discord Presence support

Issue #1289
This commit is contained in:
Flyinghead 2024-03-01 12:34:49 +01:00
parent 588035d9eb
commit dac5c008ab
8 changed files with 131 additions and 5 deletions

View File

@ -18,11 +18,11 @@ jobs:
matrix:
config:
- {name: i686-pc-windows-msvc, os: windows-latest, shell: cmd, arch: x86, cmakeArgs: -G Ninja, buildType: Release}
- {name: apple-darwin, os: macos-latest, shell: sh, cmakeArgs: -G Xcode -DAPPLE_BREAKPAD=ON, destDir: osx, buildType: RelWithDebInfo}
- {name: apple-darwin, os: macos-latest, shell: sh, cmakeArgs: -G Xcode -DAPPLE_BREAKPAD=ON -DUSE_DISCORD=ON, destDir: osx, buildType: RelWithDebInfo}
- {name: apple-ios, os: macos-latest, shell: sh, cmakeArgs: -DCMAKE_SYSTEM_NAME=iOS -G Xcode, destDir: ios, buildType: Release}
- {name: x86_64-pc-linux-gnu, os: ubuntu-20.04, shell: sh, cmakeArgs: -G Ninja, destDir: linux, buildType: RelWithDebInfo}
- {name: x86_64-pc-windows-msvc, os: windows-latest, shell: cmd, arch: x64, cmakeArgs: -G Ninja, buildType: Release}
- {name: x86_64-w64-mingw32, os: windows-latest, shell: 'msys2 {0}', cmakeArgs: -G Ninja, destDir: win, buildType: RelWithDebInfo}
- {name: x86_64-pc-linux-gnu, os: ubuntu-20.04, shell: sh, cmakeArgs: -G Ninja -DUSE_DISCORD=ON, destDir: linux, buildType: RelWithDebInfo}
- {name: x86_64-pc-windows-msvc, os: windows-latest, shell: cmd, arch: x64, cmakeArgs: -G Ninja -DUSE_DISCORD=ON, buildType: Release}
- {name: x86_64-w64-mingw32, os: windows-latest, shell: 'msys2 {0}', cmakeArgs: -G Ninja -DUSE_DISCORD=ON, destDir: win, buildType: RelWithDebInfo}
- {name: libretro-x86_64-pc-linux-gnu, os: ubuntu-latest, shell: sh, cmakeArgs: -DLIBRETRO=ON -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE -G Ninja, buildType: Release}
- {name: libretro-x86_64-w64-mingw32, os: windows-latest, shell: 'msys2 {0}', cmakeArgs: -DLIBRETRO=ON -G Ninja, buildType: Release}
@ -69,7 +69,7 @@ jobs:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: true
submodules: recursive
- name: Compile a universal OpenMP (macOS)
run: HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew reinstall --build-from-source --formula ./shell/apple/libomp.rb

3
.gitmodules vendored
View File

@ -29,3 +29,6 @@
[submodule "core/deps/Spout"]
path = core/deps/Spout
url = https://github.com/vkedwardli/Spout2.git
[submodule "core/deps/discord-rpc"]
path = core/deps/discord-rpc
url = https://github.com/flyinghead/discord-rpc

View File

@ -68,6 +68,7 @@ option(APPLE_BREAKPAD "macOS: Build breakpad client and dump symbols" OFF)
option(ENABLE_GDB_SERVER "Build with GDB debugging support" OFF)
option(ENABLE_DC_PROFILER "Build with support for target machine (SH4) profiler" OFF)
option(ENABLE_FC_PROFILER "Build with support for host app (Flycast) profiler" OFF)
option(USE_DISCORD "Use Discord Presence API" OFF)
if(IOS AND NOT LIBRETRO)
set(USE_VULKAN OFF CACHE BOOL "Force vulkan off" FORCE)
@ -716,6 +717,15 @@ endif()
target_sources(${PROJECT_NAME} PRIVATE core/deps/xbrz/xbrz.cpp)
target_sources(${PROJECT_NAME} PRIVATE core/deps/md5/md5.cpp)
if(USE_DISCORD)
option(BUILD_EXAMPLES "Build example apps" OFF)
add_subdirectory(core/deps/discord-rpc)
target_include_directories(${PROJECT_NAME} PRIVATE core/deps/discord-rpc/include)
target_link_libraries(${PROJECT_NAME} PRIVATE discord-rpc)
target_compile_definitions(${PROJECT_NAME} PRIVATE USE_DISCORD)
target_sources(${PROJECT_NAME} PRIVATE core/discord.cpp)
endif()
cmrc_add_resource_library(flycast-resources ALIAS flycast::res NAMESPACE flycast)
target_link_libraries(${PROJECT_NAME} PRIVATE flycast::res)

View File

@ -129,6 +129,7 @@ Option<bool> OpenGlChecks("OpenGlChecks", false, "validate");
Option<std::vector<std::string>, false> ContentPath("Dreamcast.ContentPath");
Option<bool, false> HideLegacyNaomiRoms("Dreamcast.HideLegacyNaomiRoms", true);
Option<bool, false> UploadCrashLogs("UploadCrashLogs", true);
Option<bool, false> DiscordPresence("DiscordPresence", true);
// Profiler
Option<bool> ProfilerEnabled("Profiler.Enabled");

View File

@ -495,6 +495,7 @@ extern Option<bool> OpenGlChecks;
extern Option<std::vector<std::string>, false> ContentPath;
extern Option<bool, false> HideLegacyNaomiRoms;
extern Option<bool, false> UploadCrashLogs;
extern Option<bool, false> DiscordPresence;
// Profiling
extern Option<bool> ProfilerEnabled;

1
core/deps/discord-rpc Submodule

@ -0,0 +1 @@
Subproject commit c1197e1a1e2ff09c077e84541bd88cf90581648c

107
core/discord.cpp Normal file
View File

@ -0,0 +1,107 @@
/*
Copyright 2024 flyinghead
This file is part of Flycast.
Flycast 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.
Flycast 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 Flycast. If not, see <https://www.gnu.org/licenses/>.
*/
#include "types.h"
#include "emulator.h"
#include "stdclass.h"
#include "cfg/option.h"
#include "discord_rpc.h"
#include <cstring>
#include <time.h>
#define FLYCAST_APPID "1212789289851559946"
class DiscordPresence
{
public:
DiscordPresence()
{
EventManager::listen(Event::Start, handleEmuEvent, this);
EventManager::listen(Event::Terminate, handleEmuEvent, this);
EventManager::listen(Event::Resume, handleEmuEvent, this);
}
~DiscordPresence()
{
shutdown();
EventManager::unlisten(Event::Start, handleEmuEvent, this);
EventManager::unlisten(Event::Terminate, handleEmuEvent, this);
EventManager::unlisten(Event::Resume, handleEmuEvent, this);
}
private:
void initialize()
{
if (!initialized)
Discord_Initialize(FLYCAST_APPID, nullptr, 0, nullptr);
initialized = true;
}
void shutdown()
{
if (initialized)
Discord_Shutdown();
initialized = false;
}
void sendPresence()
{
initialize();
DiscordRichPresence discordPresence{};
std::string state = settings.content.title.substr(0, 128);
discordPresence.state = state.c_str();
discordPresence.startTimestamp = time(0);
discordPresence.largeImageKey = "icon-512";
Discord_UpdatePresence(&discordPresence);
}
static void handleEmuEvent(Event event, void *p)
{
if (settings.naomi.slave || settings.naomi.drivingSimSlave != 0)
return;
DiscordPresence *inst = (DiscordPresence *)p;
switch (event)
{
case Event::Start:
if (config::DiscordPresence)
inst->sendPresence();
break;
case Event::Resume:
if (config::DiscordPresence && !inst->initialized)
// Discord presence enabled
inst->sendPresence();
else if (!config::DiscordPresence && inst->initialized)
{
// Discord presence disabled
Discord_ClearPresence();
inst->shutdown();
}
break;
case Event::Terminate:
if (inst->initialized)
Discord_ClearPresence();
break;
default:
break;
}
}
bool initialized = false;
};
static DiscordPresence discordPresence;

View File

@ -1694,6 +1694,9 @@ static void gui_display_settings()
OptionCheckbox("Save", config::AutoSaveState,
"Save the state of the game when stopping");
OptionCheckbox("Naomi Free Play", config::ForceFreePlay, "Configure Naomi games in Free Play mode.");
#if USE_DISCORD
OptionCheckbox("Discord Presence", config::DiscordPresence, "Show which game you are playing on Discord");
#endif
ImGui::PopStyleVar();
ImGui::EndTabItem();