Add Discord RPC

This commit is contained in:
wheremyfoodat 2023-08-07 22:24:33 +03:00
commit 692c25c0b1
7 changed files with 107 additions and 3 deletions

View file

@ -106,6 +106,7 @@ set(SOURCE_FILES src/main.cpp src/emulator.cpp src/io_file.cpp src/config.cpp
src/core/CPU/cpu_dynarmic.cpp src/core/CPU/dynarmic_cycles.cpp src/core/CPU/cpu_dynarmic.cpp src/core/CPU/dynarmic_cycles.cpp
src/core/memory.cpp src/renderer.cpp src/core/renderer_null/renderer_null.cpp src/core/memory.cpp src/renderer.cpp src/core/renderer_null/renderer_null.cpp
src/http_server.cpp src/stb_image_write.c src/core/cheats.cpp src/core/action_replay.cpp src/http_server.cpp src/stb_image_write.c src/core/cheats.cpp src/core/action_replay.cpp
src/discord_rpc.cpp
) )
set(CRYPTO_SOURCE_FILES src/core/crypto/aes_engine.cpp) set(CRYPTO_SOURCE_FILES src/core/crypto/aes_engine.cpp)
set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limits.cpp set(KERNEL_SOURCE_FILES src/core/kernel/kernel.cpp src/core/kernel/resource_limits.cpp
@ -163,7 +164,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp
include/crypto/aes_engine.hpp include/metaprogramming.hpp include/PICA/pica_vertex.hpp include/crypto/aes_engine.hpp include/metaprogramming.hpp include/PICA/pica_vertex.hpp
include/config.hpp include/services/ir_user.hpp include/http_server.hpp include/cheats.hpp include/config.hpp include/services/ir_user.hpp include/http_server.hpp include/cheats.hpp
include/action_replay.hpp include/renderer_sw/renderer_sw.hpp include/compiler_builtins.hpp include/action_replay.hpp include/renderer_sw/renderer_sw.hpp include/compiler_builtins.hpp
include/fs/romfs.hpp include/fs/ivfc.hpp include/fs/romfs.hpp include/fs/ivfc.hpp include/discord_rpc.hpp
) )
set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp set(THIRD_PARTY_SOURCE_FILES third_party/imgui/imgui.cpp
@ -257,13 +258,14 @@ endif()
add_executable(Alber ${ALL_SOURCES}) add_executable(Alber ${ALL_SOURCES})
if(ENABLE_LTO OR ENABLE_USER_BUILD) if(ENABLE_LTO OR ENABLE_USER_BUILD)
set_target_properties(Alber PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) set_target_properties(Alber PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE)
endif() endif()
target_link_libraries(Alber PRIVATE dynarmic SDL2-static cryptopp glad) target_link_libraries(Alber PRIVATE dynarmic SDL2-static cryptopp glad)
if(ENABLE_DISCORD_RPC) if(ENABLE_DISCORD_RPC)
target_compile_definitions(Alber PUBLIC "PANDA3DS_ENABLE_DISCORD_RPC=1") target_compile_definitions(Alber PUBLIC "PANDA3DS_ENABLE_DISCORD_RPC=1")
target_link_libraries(Alber PRIVATE discord-rpc)
endif() endif()
if(ENABLE_OPENGL) if(ENABLE_OPENGL)

View file

@ -6,6 +6,7 @@
// Remember to initialize every field here to its default value otherwise bad things will happen // Remember to initialize every field here to its default value otherwise bad things will happen
struct EmulatorConfig { struct EmulatorConfig {
bool shaderJitEnabled = false; bool shaderJitEnabled = false;
bool discordRpcEnabled = false;
RendererType rendererType = RendererType::OpenGL; RendererType rendererType = RendererType::OpenGL;
EmulatorConfig(const std::filesystem::path& path); EmulatorConfig(const std::filesystem::path& path);

22
include/discord_rpc.hpp Normal file
View file

@ -0,0 +1,22 @@
#pragma once
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
#include <discord_rpc.h>
#include <cstdint>
namespace Discord {
enum class RPCStatus { Idling, Playing };
class RPC {
std::uint64_t startTimestamp;
bool enabled = false;
public:
void init();
void update(RPCStatus status);
void stop();
};
} // namespace Discord
#endif

View file

@ -11,6 +11,7 @@
#include "config.hpp" #include "config.hpp"
#include "cpu.hpp" #include "cpu.hpp"
#include "crypto/aes_engine.hpp" #include "crypto/aes_engine.hpp"
#include "discord_rpc.hpp"
#include "io_file.hpp" #include "io_file.hpp"
#include "memory.hpp" #include "memory.hpp"
@ -64,6 +65,11 @@ class Emulator {
friend struct HttpServer; friend struct HttpServer;
#endif #endif
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
Discord::RPC discordRpc;
void updateDiscord();
#endif
// Keep the handle for the ROM here to reload when necessary and to prevent deleting it // Keep the handle for the ROM here to reload when necessary and to prevent deleting it
// This is currently only used for ELFs, NCSDs use the IOFile API instead // This is currently only used for ELFs, NCSDs use the IOFile API instead
std::ifstream loadedELF; std::ifstream loadedELF;

View file

@ -29,6 +29,15 @@ void EmulatorConfig::load(const std::filesystem::path& path) {
return; return;
} }
if (data.contains("General")) {
auto generalResult = toml::expect<toml::value>(data.at("General"));
if (generalResult.is_ok()) {
auto general = generalResult.unwrap();
discordRpcEnabled = toml::find_or<toml::boolean>(general, "EnableDiscordRPC", false);
}
}
if (data.contains("GPU")) { if (data.contains("GPU")) {
auto gpuResult = toml::expect<toml::value>(data.at("GPU")); auto gpuResult = toml::expect<toml::value>(data.at("GPU"));
if (gpuResult.is_ok()) { if (gpuResult.is_ok()) {
@ -68,6 +77,7 @@ void EmulatorConfig::save(const std::filesystem::path& path) {
printf("Saving new configuration file %s\n", path.string().c_str()); printf("Saving new configuration file %s\n", path.string().c_str());
} }
data["General"]["EnableDiscordRPC"] = discordRpcEnabled;
data["GPU"]["EnableShaderJIT"] = shaderJitEnabled; data["GPU"]["EnableShaderJIT"] = shaderJitEnabled;
data["GPU"]["Renderer"] = std::string(Renderer::typeToString(rendererType)); data["GPU"]["Renderer"] = std::string(Renderer::typeToString(rendererType));

37
src/discord_rpc.cpp Normal file
View file

@ -0,0 +1,37 @@
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
#include "discord_rpc.hpp"
#include <cstring>
#include <ctime>
void Discord::RPC::init() {
DiscordEventHandlers handlers{};
Discord_Initialize("1138176975865909360", &handlers, 1, nullptr);
startTimestamp = time(nullptr);
enabled = true;
}
void Discord::RPC::update(Discord::RPCStatus status) {
DiscordRichPresence rpc{};
rpc.details = "Panda";
rpc.state = "Petting a panda";
rpc.largeImageKey = "pand";
rpc.largeImageText = "Panda3DS is a 3DS emulator for Windows, MacOS and Linux";
rpc.startTimestamp = startTimestamp;
Discord_UpdatePresence(&rpc);
}
void Discord::RPC::stop() {
if (enabled) {
enabled = false;
Discord_ClearPresence();
Discord_Shutdown();
}
}
#endif

View file

@ -34,6 +34,12 @@ Emulator::Emulator()
needOpenGL = needOpenGL || (config.rendererType == RendererType::OpenGL); needOpenGL = needOpenGL || (config.rendererType == RendererType::OpenGL);
#endif #endif
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
if (config.discordRpcEnabled) {
discordRpc.init();
}
#endif
if (needOpenGL) { if (needOpenGL) {
// Demand 3.3 core for software renderer, or 4.1 core for OpenGL renderer (max available on MacOS) // Demand 3.3 core for software renderer, or 4.1 core for OpenGL renderer (max available on MacOS)
// MacOS gets mad if we don't explicitly demand a core profile // MacOS gets mad if we don't explicitly demand a core profile
@ -80,7 +86,13 @@ Emulator::Emulator()
reset(ReloadOption::NoReload); reset(ReloadOption::NoReload);
} }
Emulator::~Emulator() { config.save(std::filesystem::current_path() / "config.toml"); } Emulator::~Emulator() {
config.save(std::filesystem::current_path() / "config.toml");
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
discordRpc.stop();
#endif
}
void Emulator::reset(ReloadOption reload) { void Emulator::reset(ReloadOption reload) {
cpu.reset(); cpu.reset();
@ -121,6 +133,7 @@ void Emulator::run() {
#ifdef PANDA3DS_ENABLE_HTTP_SERVER #ifdef PANDA3DS_ENABLE_HTTP_SERVER
httpServer.processActions(); httpServer.processActions();
#endif #endif
runFrame(); runFrame();
HIDService& hid = kernel.getServiceManager().getHID(); HIDService& hid = kernel.getServiceManager().getHID();
@ -431,6 +444,12 @@ bool Emulator::loadROM(const std::filesystem::path& path) {
if (success) { if (success) {
romPath = path; romPath = path;
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
if (config.discordRpcEnabled) {
updateDiscord();
}
#endif
} else { } else {
romPath = std::nullopt; romPath = std::nullopt;
romType = ROMType::None; romType = ROMType::None;
@ -487,3 +506,10 @@ bool Emulator::loadELF(std::ifstream& file) {
// Reset our graphics context and initialize the GPU's graphics context // Reset our graphics context and initialize the GPU's graphics context
void Emulator::initGraphicsContext() { gpu.initGraphicsContext(window); } void Emulator::initGraphicsContext() { gpu.initGraphicsContext(window); }
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
void Emulator::updateDiscord() {
auto status = running ? Discord::RPCStatus::Playing : Discord::RPCStatus::Idling;
discordRpc.update(status);
}
#endif