mirror of
https://github.com/sm64pc/sm64pc.git
synced 2025-04-12 00:05:59 +02:00
Merge pull request #301 from Jan200101/feature/discordrpc
add discord rpc
This commit is contained in:
commit
f6b3502b62
49
Makefile
49
Makefile
@ -46,6 +46,8 @@ EXT_OPTIONS_MENU ?= 1
|
||||
TEXTSAVES ?= 0
|
||||
# Load resources from external files
|
||||
EXTERNAL_DATA ?= 0
|
||||
# Enable Discord Rich Presence
|
||||
DISCORDRPC ?= 0
|
||||
|
||||
# Various workarounds for weird toolchains
|
||||
|
||||
@ -274,6 +276,10 @@ LEVEL_DIRS := $(patsubst levels/%,%,$(dir $(wildcard levels/*/header.h)))
|
||||
SRC_DIRS := src src/engine src/game src/audio src/menu src/buffers actors levels bin data assets src/pc src/pc/gfx src/pc/audio src/pc/controller src/pc/fs src/pc/fs/packtypes
|
||||
ASM_DIRS :=
|
||||
|
||||
ifeq ($(DISCORDRPC),1)
|
||||
SRC_DIRS += src/pc/discord
|
||||
endif
|
||||
|
||||
BIN_DIRS := bin bin/$(VERSION)
|
||||
|
||||
ULTRA_SRC_DIRS := lib/src lib/src/math
|
||||
@ -441,6 +447,18 @@ ULTRA_O_FILES := $(foreach file,$(ULTRA_S_FILES),$(BUILD_DIR)/$(file:.s=.o)) \
|
||||
|
||||
GODDARD_O_FILES := $(foreach file,$(GODDARD_C_FILES),$(BUILD_DIR)/$(file:.c=.o))
|
||||
|
||||
RPC_LIBS :=
|
||||
ifeq ($(DISCORDRPC),1)
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
RPC_LIBS := src/pc/discord/lib/libdiscord-rpc.dll
|
||||
else ifeq ($(OSX_BUILD),1)
|
||||
# needs testing
|
||||
RPC_LIBS := src/pc/discord/lib/libdiscord-rpc.dylib
|
||||
else
|
||||
RPC_LIBS := src/pc/discord/lib/libdiscord-rpc.so
|
||||
endif
|
||||
endif
|
||||
|
||||
# Automatic dependency files
|
||||
DEP_FILES := $(O_FILES:.o=.d) $(ULTRA_O_FILES:.o=.d) $(GODDARD_O_FILES:.o=.d) $(BUILD_DIR)/$(LD_SCRIPT).d
|
||||
|
||||
@ -468,7 +486,9 @@ endif
|
||||
|
||||
LD := $(CC)
|
||||
|
||||
ifeq ($(WINDOWS_BUILD),1)
|
||||
ifeq ($(DISCORDRPC),1)
|
||||
LD := $(CXX)
|
||||
else ifeq ($(WINDOWS_BUILD),1)
|
||||
ifeq ($(CROSS),i686-w64-mingw32.static-) # fixes compilation in MXE on Linux and WSL
|
||||
LD := $(CC)
|
||||
else ifeq ($(CROSS),x86_64-w64-mingw32.static-)
|
||||
@ -529,6 +549,12 @@ ifeq ($(NODRAWINGDISTANCE),1)
|
||||
CFLAGS += -DNODRAWINGDISTANCE
|
||||
endif
|
||||
|
||||
# Check for Discord Rich Presence option
|
||||
ifeq ($(DISCORDRPC),1)
|
||||
CC_CHECK += -DDISCORDRPC
|
||||
CFLAGS += -DDISCORDRPC
|
||||
endif
|
||||
|
||||
# Check for texture fix option
|
||||
ifeq ($(TEXTURE_FIX),1)
|
||||
CC_CHECK += -DTEXTURE_FIX
|
||||
@ -588,6 +614,9 @@ ifeq ($(OSX_BUILD),1)
|
||||
LDFLAGS := -lm -framework OpenGL `$(SDLCONFIG) --libs` -no-pie -lpthread `pkg-config --libs libusb-1.0 glfw3 glew`
|
||||
else
|
||||
LDFLAGS := $(BITS) -march=$(TARGET_ARCH) -lm -lGL `$(SDLCONFIG) --libs` -no-pie -lpthread
|
||||
ifeq ($(DISCORDRPC),1)
|
||||
LDFLAGS += -ldl -Wl,-rpath .
|
||||
endif
|
||||
endif
|
||||
endif # End of LDFLAGS
|
||||
|
||||
@ -623,6 +652,13 @@ ZEROTERM = $(PYTHON) $(TOOLS_DIR)/zeroterm.py
|
||||
|
||||
all: $(EXE)
|
||||
|
||||
# thank you apple very cool
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
CP := gcp
|
||||
else
|
||||
CP := cp
|
||||
endif
|
||||
|
||||
ifeq ($(EXTERNAL_DATA),1)
|
||||
|
||||
BASEPACK_PATH := $(BUILD_DIR)/$(BASEDIR)/$(BASEPACK)
|
||||
@ -669,6 +705,9 @@ test: $(ROM)
|
||||
load: $(ROM)
|
||||
$(LOADER) $(LOADER_FLAGS) $<
|
||||
|
||||
$(BUILD_DIR)/$(RPC_LIBS):
|
||||
@$(CP) -f $(RPC_LIBS) $(BUILD_DIR)
|
||||
|
||||
libultra: $(BUILD_DIR)/libultra.a
|
||||
|
||||
asm/boot.s: $(BUILD_DIR)/lib/bin/ipl3_font.bin
|
||||
@ -735,11 +774,17 @@ $(BUILD_DIR)/src/menu/star_select.o: $(BUILD_DIR)/include/text_strings.h $(BUILD
|
||||
$(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
|
||||
$(BUILD_DIR)/src/game/options_menu.o: $(BUILD_DIR)/include/text_strings.h $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
|
||||
O_FILES += $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
|
||||
ifeq ($(DISCORDRPC),1)
|
||||
$(BUILD_DIR)/src/pc/discord/discordrpc.o: $(BUILD_DIR)/include/text_strings.h $(BUILD_DIR)/bin/eu/translation_en.o $(BUILD_DIR)/bin/eu/translation_de.o $(BUILD_DIR)/bin/eu/translation_fr.o
|
||||
endif
|
||||
else
|
||||
$(BUILD_DIR)/src/menu/file_select.o: $(BUILD_DIR)/include/text_strings.h
|
||||
$(BUILD_DIR)/src/menu/star_select.o: $(BUILD_DIR)/include/text_strings.h
|
||||
$(BUILD_DIR)/src/game/ingame_menu.o: $(BUILD_DIR)/include/text_strings.h
|
||||
$(BUILD_DIR)/src/game/options_menu.o: $(BUILD_DIR)/include/text_strings.h
|
||||
ifeq ($(DISCORDRPC),1)
|
||||
$(BUILD_DIR)/src/pc/discord/discordrpc.o: $(BUILD_DIR)/include/text_strings.h
|
||||
endif
|
||||
endif
|
||||
|
||||
################################################################
|
||||
@ -922,7 +967,7 @@ $(BUILD_DIR)/%.o: %.s
|
||||
|
||||
|
||||
|
||||
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES)
|
||||
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/$(RPC_LIBS)
|
||||
$(LD) -L $(BUILD_DIR) -o $@ $(O_FILES) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
|
||||
|
||||
.PHONY: all clean distclean default diff test load libultra res
|
||||
|
@ -23,6 +23,10 @@
|
||||
|
||||
#include "gfx_dimensions.h"
|
||||
|
||||
#ifdef DISCORDRPC
|
||||
#include "pc/discord/discordrpc.h"
|
||||
#endif
|
||||
|
||||
struct SpawnInfo gPlayerSpawnInfos[1];
|
||||
struct GraphNode *D_8033A160[0x100];
|
||||
struct Area gAreaData[8];
|
||||
@ -421,4 +425,8 @@ void render_game(void) {
|
||||
|
||||
D_8032CE74 = NULL;
|
||||
D_8032CE78 = 0;
|
||||
|
||||
#ifdef DISCORDRPC
|
||||
discordUpdateRichPresence();
|
||||
#endif
|
||||
}
|
||||
|
@ -92,6 +92,9 @@ bool configCameraMouse = false;
|
||||
#endif
|
||||
unsigned int configSkipIntro = 0;
|
||||
bool configHUD = true;
|
||||
#ifdef DISCORDRPC
|
||||
bool configDiscordRPC = true;
|
||||
#endif
|
||||
|
||||
static const struct ConfigOption options[] = {
|
||||
{.name = "fullscreen", .type = CONFIG_TYPE_BOOL, .boolValue = &configWindow.fullscreen},
|
||||
@ -133,6 +136,9 @@ static const struct ConfigOption options[] = {
|
||||
{.name = "bettercam_degrade", .type = CONFIG_TYPE_UINT, .uintValue = &configCameraDegrade},
|
||||
#endif
|
||||
{.name = "skip_intro", .type = CONFIG_TYPE_UINT, .uintValue = &configSkipIntro}, // Add this back!
|
||||
#ifdef DISCORDRPC
|
||||
{.name = "discordrpc_enable", .type = CONFIG_TYPE_BOOL, .boolValue = &configDiscordRPC},
|
||||
#endif
|
||||
};
|
||||
|
||||
// Reads an entire line from a file (excluding the newline character) and returns an allocated string
|
||||
|
@ -52,6 +52,9 @@ extern bool configEnableCamera;
|
||||
extern bool configCameraMouse;
|
||||
#endif
|
||||
extern bool configHUD;
|
||||
#ifdef DISCORDRPC
|
||||
extern bool configDiscordRPC;
|
||||
#endif
|
||||
|
||||
void configfile_load(const char *filename);
|
||||
void configfile_save(const char *filename);
|
||||
|
341
src/pc/discord/discordrpc.c
Normal file
341
src/pc/discord/discordrpc.c
Normal file
@ -0,0 +1,341 @@
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "PR/ultratypes.h"
|
||||
#include "memory.h"
|
||||
#include "pc/configfile.h"
|
||||
#include "discordrpc.h"
|
||||
|
||||
#define DISCORDLIBFILE "libdiscord-rpc"
|
||||
|
||||
// Thanks Microsoft for being non posix compliant
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#define DISCORDLIBEXT ".dll"
|
||||
#define itoa(int, str) itoa(int, str, "10")
|
||||
#define dlopen(lib, flag) LoadLibrary(TEXT(lib))
|
||||
#define dlerror() ""
|
||||
#define dlsym(handle, func) GetProcAddress(handle, func)
|
||||
#define dlclose(handle) FreeLibrary(handle)
|
||||
#elif defined(__APPLE__)
|
||||
#include <dlfcn.h>
|
||||
#define DISCORDLIBEXT ".dylib"
|
||||
#elif defined(__linux__) || defined(__FreeBSD__) // lets make the bold assumption for FreeBSD
|
||||
#include <dlfcn.h>
|
||||
#define DISCORDLIBEXT ".so"
|
||||
#else
|
||||
#error Unknown System
|
||||
#endif
|
||||
#define DISCORDLIB DISCORDLIBFILE DISCORDLIBEXT
|
||||
|
||||
#define DISCORD_APP_ID "709083908708237342"
|
||||
#define DISCORD_UPDATE_RATE 5
|
||||
|
||||
time_t lastUpdatedTime;
|
||||
|
||||
DiscordRichPresence discordRichPresence;
|
||||
bool initd = false;
|
||||
|
||||
void* handle;
|
||||
|
||||
void (*Discord_Initialize)(const char*, DiscordEventHandlers*, int, const char*);
|
||||
void (*Discord_Shutdown)(void);
|
||||
void (*Discord_ClearPresence)(void);
|
||||
void (*Discord_UpdatePresence)(DiscordEventHandlers*);
|
||||
|
||||
extern s16 gCurrCourseNum;
|
||||
extern s16 gCurrActNum;
|
||||
s16 lastCourseNum = -1;
|
||||
s16 lastActNum = -1;
|
||||
|
||||
extern u8 seg2_course_name_table[];
|
||||
extern u8 seg2_act_name_table[];
|
||||
|
||||
#ifdef VERSION_EU
|
||||
extern s32 gInGameLanguage;
|
||||
#endif
|
||||
|
||||
char stage[188];
|
||||
char act[188];
|
||||
|
||||
char smallImageKey[5];
|
||||
char largeImageKey[5];
|
||||
|
||||
char charset[0xFF+1] = {
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 7
|
||||
' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', // 15
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 23
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 31
|
||||
'w', 'x', 'y', 'z', ' ', ' ', ' ', ' ', // 39
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 49
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 55
|
||||
' ', ' ', ' ', ' ', ' ', ' ', '\'', ' ', // 63
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 71
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 79
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 87
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 95
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 103
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ',', // 111
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 119
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 127
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 135
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 143
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 151
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', '-', // 159
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 167
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 175
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 183
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 192
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 199
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 207
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 215
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 223
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 231
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 239
|
||||
' ', ' ', '!', ' ', ' ', ' ', ' ', ' ', // 247
|
||||
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' // 255
|
||||
};
|
||||
|
||||
void convertstring(const u8 *str, char* output)
|
||||
{
|
||||
s32 strPos = 0;
|
||||
bool capitalizeChar = true;
|
||||
|
||||
while (str[strPos] != 0xFF)
|
||||
{
|
||||
if (str[strPos] < 0xFF)
|
||||
{
|
||||
output[strPos] = charset[str[strPos]];
|
||||
|
||||
// if the char is a letter we can capatalize it
|
||||
if (capitalizeChar && 0x0A <= str[strPos] && str[strPos] <= 0x23)
|
||||
{
|
||||
output[strPos] -= ('a' - 'A');
|
||||
capitalizeChar = false;
|
||||
}
|
||||
|
||||
}
|
||||
else output[strPos] = ' ';
|
||||
|
||||
switch (output[strPos]) // decide if the next character should be capitalized
|
||||
{
|
||||
case ' ':
|
||||
if (str[strPos] != 158) fprintf(stdout, "Unknown Character (%i)\n", str[strPos]); // inform that an unknown char was found
|
||||
case '-':
|
||||
capitalizeChar = true;
|
||||
break;
|
||||
default:
|
||||
capitalizeChar = false;
|
||||
break;
|
||||
}
|
||||
|
||||
strPos++;
|
||||
}
|
||||
|
||||
output[strPos] = '\0';
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
void reverse(char s[])
|
||||
{
|
||||
int i, j;
|
||||
char c;
|
||||
|
||||
for (i = 0, j = strlen(s)-1; i<j; i++, j--) {
|
||||
c = s[i];
|
||||
s[i] = s[j];
|
||||
s[j] = c;
|
||||
}
|
||||
}
|
||||
|
||||
void itoa(int n, char s[])
|
||||
{
|
||||
int i, sign;
|
||||
|
||||
if (n < 0)
|
||||
n = -n;
|
||||
i = 0;
|
||||
do {
|
||||
s[i++] = n % 10 + '0';
|
||||
} while ((n /= 10) > 0);
|
||||
|
||||
s[i] = '\0';
|
||||
reverse(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
void OnReady( const DiscordUser* user )
|
||||
{
|
||||
discordReset();
|
||||
}
|
||||
|
||||
void InitializeDiscord()
|
||||
{
|
||||
DiscordEventHandlers handlers;
|
||||
memset(&handlers, 0, sizeof(handlers));
|
||||
handlers.ready = OnReady;
|
||||
|
||||
Discord_Initialize(DISCORD_APP_ID, &handlers, false, "");
|
||||
|
||||
initd = true;
|
||||
}
|
||||
|
||||
void SetDetails()
|
||||
{
|
||||
if (lastCourseNum != gCurrCourseNum)
|
||||
{
|
||||
// If we are in in Course 0 we are in the castle which doesn't have a string
|
||||
if (gCurrCourseNum)
|
||||
{
|
||||
void **courseNameTbl;
|
||||
|
||||
#ifndef VERSION_EU
|
||||
courseNameTbl = segmented_to_virtual(seg2_course_name_table);
|
||||
#else
|
||||
switch (gInGameLanguage) {
|
||||
case LANGUAGE_ENGLISH:
|
||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_en);
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_fr);
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
courseNameTbl = segmented_to_virtual(course_name_table_eu_de);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
u8 *courseName = segmented_to_virtual(courseNameTbl[gCurrCourseNum - 1]);
|
||||
|
||||
convertstring(&courseName[3], stage);
|
||||
}
|
||||
else strcpy(stage, "Peach's Castle");
|
||||
|
||||
lastCourseNum = gCurrCourseNum;
|
||||
}
|
||||
}
|
||||
|
||||
void SetState()
|
||||
{
|
||||
if (lastActNum != gCurrActNum || lastCourseNum != gCurrCourseNum)
|
||||
{
|
||||
// when exiting a stage the act doesn't get reset
|
||||
if (gCurrActNum && gCurrCourseNum)
|
||||
{
|
||||
if (gCurrCourseNum < 19) // any stage over 19 is a special stage without acts
|
||||
{
|
||||
void **actNameTbl;
|
||||
#ifndef VERSION_EU
|
||||
actNameTbl = segmented_to_virtual(seg2_act_name_table);
|
||||
#else
|
||||
switch (gInGameLanguage) {
|
||||
case LANGUAGE_ENGLISH:
|
||||
actNameTbl = segmented_to_virtual(act_name_table_eu_en);
|
||||
break;
|
||||
case LANGUAGE_FRENCH:
|
||||
actNameTbl = segmented_to_virtual(act_name_table_eu_fr);
|
||||
break;
|
||||
case LANGUAGE_GERMAN:
|
||||
actNameTbl = segmented_to_virtual(act_name_table_eu_de);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
u8 *actName = actName = segmented_to_virtual(actNameTbl[(gCurrCourseNum - 1) * 6 + gCurrActNum - 1]);
|
||||
|
||||
convertstring(actName, act);
|
||||
}
|
||||
else
|
||||
{
|
||||
act[0] = '\0';
|
||||
gCurrActNum = 0;
|
||||
}
|
||||
}
|
||||
else act[0] = '\0';
|
||||
|
||||
lastActNum = gCurrActNum;
|
||||
}
|
||||
}
|
||||
|
||||
void SetLogo()
|
||||
{
|
||||
if (lastCourseNum)
|
||||
{
|
||||
itoa(lastCourseNum, largeImageKey);
|
||||
}
|
||||
else strcpy(largeImageKey, "0");
|
||||
|
||||
|
||||
/*
|
||||
if (lastActNum)
|
||||
{
|
||||
itoa(lastActNum, smallImageKey);
|
||||
}
|
||||
else smallImageKey[0] = '\0';
|
||||
*/
|
||||
|
||||
discordRichPresence.largeImageKey = largeImageKey;
|
||||
//discordRichPresence.largeImageText = "";
|
||||
//discordRichPresence.smallImageKey = smallImageKey;
|
||||
//discordRichPresence.smallImageText = "";
|
||||
}
|
||||
|
||||
void discordUpdateRichPresence()
|
||||
{
|
||||
if (!configDiscordRPC || !initd) return;
|
||||
if (time(NULL) < lastUpdatedTime + DISCORD_UPDATE_RATE) return;
|
||||
|
||||
lastUpdatedTime = time(NULL);
|
||||
|
||||
SetState();
|
||||
SetDetails();
|
||||
SetLogo();
|
||||
Discord_UpdatePresence(&discordRichPresence);
|
||||
}
|
||||
|
||||
void discordShutdown()
|
||||
{
|
||||
if (handle)
|
||||
{
|
||||
Discord_ClearPresence();
|
||||
Discord_Shutdown();
|
||||
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void discordInit()
|
||||
{
|
||||
if (configDiscordRPC)
|
||||
{
|
||||
handle = dlopen(DISCORDLIB, RTLD_LAZY);
|
||||
if (!handle) {
|
||||
fprintf(stderr, "Unable to load Discord\n%s\n", dlerror());
|
||||
return;
|
||||
}
|
||||
|
||||
Discord_Initialize = dlsym(handle, "Discord_Initialize");
|
||||
Discord_Shutdown = dlsym(handle, "Discord_Shutdown");
|
||||
Discord_ClearPresence = dlsym(handle, "Discord_ClearPresence");
|
||||
Discord_UpdatePresence = dlsym(handle, "Discord_UpdatePresence");
|
||||
|
||||
InitializeDiscord();
|
||||
|
||||
discordRichPresence.details = stage;
|
||||
discordRichPresence.state = act;
|
||||
|
||||
|
||||
lastUpdatedTime = 0;
|
||||
}
|
||||
};
|
||||
|
||||
void discordReset()
|
||||
{
|
||||
memset( &discordRichPresence, 0, sizeof( discordRichPresence ) );
|
||||
|
||||
SetState();
|
||||
SetDetails();
|
||||
SetLogo();
|
||||
(*Discord_UpdatePresence)(&discordRichPresence);
|
||||
}
|
||||
|
49
src/pc/discord/discordrpc.h
Normal file
49
src/pc/discord/discordrpc.h
Normal file
@ -0,0 +1,49 @@
|
||||
#ifndef DISCORDRPC_H
|
||||
#define DISCORDRPC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct DiscordRichPresence {
|
||||
const char* state; /* max 128 bytes */
|
||||
const char* details; /* max 128 bytes */
|
||||
int64_t startTimestamp;
|
||||
int64_t endTimestamp;
|
||||
const char* largeImageKey; /* max 32 bytes */
|
||||
const char* largeImageText; /* max 128 bytes */
|
||||
const char* smallImageKey; /* max 32 bytes */
|
||||
const char* smallImageText; /* max 128 bytes */
|
||||
const char* partyId; /* max 128 bytes */
|
||||
int partySize;
|
||||
int partyMax;
|
||||
const char* matchSecret; /* max 128 bytes */
|
||||
const char* joinSecret; /* max 128 bytes */
|
||||
const char* spectateSecret; /* max 128 bytes */
|
||||
int8_t instance;
|
||||
} DiscordRichPresence;
|
||||
|
||||
typedef struct DiscordUser {
|
||||
const char* userId;
|
||||
const char* username;
|
||||
const char* discriminator;
|
||||
const char* avatar;
|
||||
} DiscordUser;
|
||||
|
||||
typedef struct DiscordEventHandlers {
|
||||
void (*ready)(const DiscordUser* request);
|
||||
void (*disconnected)(int errorCode, const char* message);
|
||||
void (*errored)(int errorCode, const char* message);
|
||||
void (*joinGame)(const char* joinSecret);
|
||||
void (*spectateGame)(const char* spectateSecret);
|
||||
void (*joinRequest)(const DiscordUser* request);
|
||||
} DiscordEventHandlers;
|
||||
|
||||
#define DISCORD_REPLY_NO 0
|
||||
#define DISCORD_REPLY_YES 1
|
||||
#define DISCORD_REPLY_IGNORE 2
|
||||
|
||||
void discordUpdateRichPresence();
|
||||
void discordShutdown();
|
||||
void discordInit();
|
||||
void discordReset();
|
||||
|
||||
#endif // DISCORDRPC_H
|
BIN
src/pc/discord/lib/libdiscord-rpc.dll
Normal file
BIN
src/pc/discord/lib/libdiscord-rpc.dll
Normal file
Binary file not shown.
BIN
src/pc/discord/lib/libdiscord-rpc.dylib
Executable file
BIN
src/pc/discord/lib/libdiscord-rpc.dylib
Executable file
Binary file not shown.
BIN
src/pc/discord/lib/libdiscord-rpc.so
Normal file
BIN
src/pc/discord/lib/libdiscord-rpc.so
Normal file
Binary file not shown.
@ -32,6 +32,10 @@
|
||||
|
||||
#include "src/pc/controller/controller_keyboard.h"
|
||||
|
||||
#ifdef DISCORDRPC
|
||||
#include "pc/discord/discordrpc.h"
|
||||
#endif
|
||||
|
||||
// TODO: figure out if this shit even works
|
||||
#ifdef VERSION_EU
|
||||
# define FRAMERATE 25
|
||||
@ -194,6 +198,9 @@ static void gfx_sdl_init(void) {
|
||||
|
||||
static void gfx_sdl_main_loop(void (*run_one_game_iter)(void)) {
|
||||
Uint32 t;
|
||||
#ifdef DISCORDRPC
|
||||
discordInit();
|
||||
#endif
|
||||
while (1) {
|
||||
t = SDL_GetTicks();
|
||||
run_one_game_iter();
|
||||
@ -258,6 +265,9 @@ static void gfx_sdl_handle_events(void) {
|
||||
}
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
#ifdef DISCORDRPC
|
||||
discordShutdown();
|
||||
#endif
|
||||
game_exit();
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user