More nice touches to DiscordRPC

This commit is contained in:
SimoneN64
2024-08-27 22:31:55 +02:00
parent 86bfeec8bd
commit 5f7a2fa65f
7 changed files with 83 additions and 46 deletions

View File

@@ -42,12 +42,12 @@ extern "C" DISCORD_EXPORT void Discord_Register(const char* applicationId, const
}
const char* desktopFileFormat = "[Desktop Entry]\n"
"Name=Game %s\n"
"Exec=%s %%u\n" // note: it really wants that %u in there
"Type=Application\n"
"NoDisplay=true\n"
"Categories=Discord;Games;\n"
"MimeType=x-scheme-handler/discord-%s;\n";
"Name=Game %s\n"
"Exec=%s %%u\n" // note: it really wants that %u in there
"Type=Application\n"
"NoDisplay=true\n"
"Categories=Discord;Games;\n"
"MimeType=x-scheme-handler/discord-%s;\n";
char desktopFile[2048];
int fileLen = snprintf(
desktopFile, sizeof(desktopFile), desktopFileFormat, applicationId, command, applicationId);

View File

@@ -5,42 +5,72 @@
#include <string>
namespace Util {
enum State {
Idling,
Playing,
MovieReplay,
Paused,
};
struct RPC {
enum State {
Idling,
Playing,
MovieReplay,
Paused,
};
FORCE_INLINE void UpdateRPC(State state, const std::string &game = "", const std::string &movieName = "") {
DiscordRichPresence presence{};
std::string textState, textDetails;
switch (state) {
case Idling:
textDetails = "Idling";
break;
case Playing:
textDetails = "In-game";
textState = "Playing \"" + game + "\"";
break;
case MovieReplay:
textDetails = "In-game";
textState = "Replaying movie \"" + movieName + "\" in \"" + game + "\"";
break;
case Paused:
textDetails = "In-game";
textState = "Playing \"" + game + "\" (Paused)";
break;
RPC() {
Discord_Initialize("1049669178124148806", &handlers, 1, nullptr);
startTimestamp = time(nullptr);
}
presence.details = textDetails.c_str();
presence.state = textState.c_str();
presence.startTimestamp = time(nullptr);
presence.largeImageText = "Kaizen";
presence.largeImageKey = "logo";
Discord_UpdatePresence(&presence);
}
static RPC &GetInstance() {
static RPC instance;
return instance;
}
FORCE_INLINE void ClearRPC() { Discord_ClearPresence(); }
[[nodiscard]] FORCE_INLINE const State &GetState() const { return currentState; }
FORCE_INLINE void Update(State state, const std::string &game = "", const std::string &movieName = "") {
DiscordRichPresence presence{};
std::string textState, textDetails;
currentState = state == Paused ? currentState : state;
switch (state) {
case Idling:
textDetails = "Idling";
break;
case Playing:
textDetails = "In-game";
textState = "Playing \"" + game + "\"";
break;
case MovieReplay:
textDetails = "In-game";
textState = "Replaying movie \"" + movieName + "\" in \"" + game + "\"";
break;
case Paused:
switch (currentState) {
case Playing:
textDetails = "In-game";
textState = "Playing \"" + game + "\"";
break;
case MovieReplay:
textDetails = "In-game";
textState = "Replaying movie \"" + movieName + "\" in \"" + game + "\"";
break;
default:;
}
textState += " (Paused)";
break;
}
presence.details = textDetails.c_str();
presence.state = textState.c_str();
presence.startTimestamp = startTimestamp;
presence.largeImageText = "Kaizen";
presence.largeImageKey = "logo";
Discord_UpdatePresence(&presence);
}
FORCE_INLINE void Clear() { Discord_ClearPresence(); }
private:
DiscordEventHandlers handlers{};
s64 startTimestamp{};
State currentState;
};
} // namespace Util

View File

@@ -3,7 +3,7 @@
#include <Scheduler.hpp>
namespace n64 {
Core::Core(ParallelRDP &parallel) : cpu(std::make_unique<JIT>(parallel)) {}
Core::Core(ParallelRDP &parallel) : cpu(std::make_unique<Interpreter>(parallel)) {}
void Core::Stop() {
render = false;

View File

@@ -29,6 +29,7 @@ union TASMovieControllerData {
static_assert(sizeof(TASMovieControllerData) == 4);
bool MupenMovie::Load(const fs::path &path) {
filename = path.stem().string();
loadedTasMovie = Util::ReadFileBinary(path.string());
if (!IsLoaded()) {
Util::error("Error loading movie!");

View File

@@ -51,9 +51,11 @@ struct MupenMovie {
bool Load(const fs::path &);
void Reset();
n64::Controller NextInputs();
bool IsLoaded() const { return !loadedTasMovie.empty(); }
[[nodiscard]] bool IsLoaded() const { return !loadedTasMovie.empty(); }
[[nodiscard]] const std::string &GetFilename() const { return filename; }
private:
std::string filename{};
std::vector<u8> loadedTasMovie = {};
TASMovieHeader loadedTasMovieHeader = {};
uint32_t loadedTasMovieIndex = 0;

View File

@@ -27,7 +27,9 @@ public:
void TogglePause() {
core.pause = !core.pause;
Util::UpdateRPC(core.pause ? Util::Idling : Util::Playing);
Util::RPC::GetInstance().Update(core.pause ? Util::RPC::Paused : Util::RPC::GetInstance().GetState(),
core.cpu->GetMem().rom.gameNameDB,
core.cpu->GetMem().mmio.si.pif.movie.GetFilename());
}
void SetRender(bool v) { core.render = v; }
@@ -40,7 +42,7 @@ public:
}
void Stop() {
Discord_ClearPresence();
Util::RPC::GetInstance().Update(Util::RPC::Idling);
core.rom = {};
core.pause = true;
core.Stop();

View File

@@ -15,6 +15,7 @@ KaizenQt::KaizenQt() noexcept : QWidget(nullptr) {
std::move(mainWindow->view.vulkanWidget->windowInfo), *settingsWindow);
ConnectMainWindowSignalsToSlots();
Util::RPC::GetInstance().Update(Util::RPC::Idling);
setAcceptDrops(true);
setFocusPolicy(Qt::StrongFocus);
@@ -54,7 +55,7 @@ void KaizenQt::LoadROM(const QString &fileName) noexcept {
emuThread->core.LoadROM(fileName.toStdString());
auto gameNameDB = emuThread->core.cpu->GetMem().rom.gameNameDB;
mainWindow->setWindowTitle(emuThread->core.cpu->GetMem().rom.gameNameDB.c_str());
UpdateRPC(Util::Playing, gameNameDB);
Util::RPC::GetInstance().Update(Util::RPC::Playing, gameNameDB);
}
void KaizenQt::Quit() noexcept {
@@ -69,7 +70,8 @@ void KaizenQt::Quit() noexcept {
void KaizenQt::LoadTAS(const QString &fileName) const noexcept {
emuThread->core.LoadTAS(fs::path(fileName.toStdString()));
auto gameNameDB = emuThread->core.cpu->GetMem().rom.gameNameDB;
UpdateRPC(Util::MovieReplay, gameNameDB, fileName.toStdString());
auto movieName = fs::path(fileName.toStdString()).stem().string();
Util::RPC::GetInstance().Update(Util::RPC::MovieReplay, gameNameDB, movieName);
}
void KaizenQt::keyPressEvent(QKeyEvent *e) {