mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-09 04:30:49 -04:00
Merge remote-tracking branch 'origin/main' into mods
This commit is contained in:
@@ -338,6 +338,48 @@ if (DUSK_MOVIE_SUPPORT)
|
||||
list(APPEND GAME_COMPILE_DEFS MOVIE_SUPPORT=1)
|
||||
endif ()
|
||||
|
||||
option(DUSK_ENABLE_DISCORD_RPC "Enable Discord Rich Presence support" ON)
|
||||
if (DUSK_ENABLE_DISCORD_RPC AND NOT ANDROID AND NOT IOS AND NOT TVOS)
|
||||
|
||||
FetchContent_Populate(discord_rpc
|
||||
URL https://github.com/discord/discord-rpc/archive/refs/tags/v3.4.0.tar.gz
|
||||
URL_HASH SHA256=e13427019027acd187352dacba6c65953af66fdf3c35fcf38fc40b454a9d7855
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
)
|
||||
# RapidJSON is a git submodule absent from the discord-rpc tarball; fetch separately.
|
||||
FetchContent_Populate(rapidjson
|
||||
URL https://github.com/Tencent/rapidjson/archive/refs/tags/v1.1.0.tar.gz
|
||||
URL_HASH SHA256=bf7ced29704a1e696fbccf2a2b4ea068e7774fa37f6d7dd4039d0787f8bed98e
|
||||
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
|
||||
)
|
||||
|
||||
if (NOT TARGET discord-rpc)
|
||||
set(_drpc ${discord_rpc_SOURCE_DIR}/src)
|
||||
set(_drpc_src
|
||||
${_drpc}/discord_rpc.cpp
|
||||
${_drpc}/rpc_connection.cpp
|
||||
${_drpc}/serialization.cpp
|
||||
)
|
||||
if (WIN32)
|
||||
list(APPEND _drpc_src ${_drpc}/connection_win.cpp ${_drpc}/discord_register_win.cpp)
|
||||
elseif (APPLE)
|
||||
list(APPEND _drpc_src ${_drpc}/connection_unix.cpp ${_drpc}/discord_register_osx.m)
|
||||
else ()
|
||||
list(APPEND _drpc_src ${_drpc}/connection_unix.cpp ${_drpc}/discord_register_linux.cpp)
|
||||
endif ()
|
||||
add_library(discord-rpc STATIC ${_drpc_src})
|
||||
target_include_directories(discord-rpc PUBLIC
|
||||
${discord_rpc_SOURCE_DIR}/include
|
||||
${rapidjson_SOURCE_DIR}/include
|
||||
)
|
||||
if (UNIX)
|
||||
target_link_libraries(discord-rpc PUBLIC pthread)
|
||||
endif ()
|
||||
endif ()
|
||||
list(APPEND GAME_LIBS discord-rpc)
|
||||
list(APPEND GAME_COMPILE_DEFS DUSK_DISCORD_RPC=1)
|
||||
endif ()
|
||||
|
||||
# Edit & Continue
|
||||
if (MSVC)
|
||||
if ("${CMAKE_MSVC_DEBUG_INFORMATION_FORMAT}" STREQUAL "" AND CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
||||
+4
-1
@@ -358,7 +358,10 @@
|
||||
"inherits": [
|
||||
"relwithdebinfo",
|
||||
"ci"
|
||||
]
|
||||
],
|
||||
"cacheVariables": {
|
||||
"AURORA_SDL3_PROVIDER": "vendor"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x-linux-ci-gcc",
|
||||
|
||||
@@ -1391,4 +1391,5 @@ set(DUSK_FILES
|
||||
src/dusk/mod_loader.cpp
|
||||
src/dusk/imgui/ImGuiMenuMods.cpp
|
||||
src/dusk/gx_helper.cpp
|
||||
src/dusk/discord_presence.cpp
|
||||
)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef DUSK_DISCORD_RPC
|
||||
|
||||
namespace dusk {
|
||||
namespace discord {
|
||||
|
||||
void Initialize();
|
||||
|
||||
void RunCallbacks();
|
||||
|
||||
void UpdatePresence();
|
||||
|
||||
void Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DUSK_DISCORD_RPC
|
||||
@@ -37,18 +37,40 @@ void daAlink_c::setCrawlMoveDirectionArrow() {
|
||||
}
|
||||
|
||||
if (field_0x3198 & 4) {
|
||||
if (!bvar) {
|
||||
direction |= data_80452F38;
|
||||
} else {
|
||||
direction |= data_80452F39;
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
if (!bvar) {
|
||||
direction |= data_80452F39;
|
||||
} else {
|
||||
direction |= data_80452F38;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (!bvar) {
|
||||
direction |= data_80452F38;
|
||||
} else {
|
||||
direction |= data_80452F39;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (field_0x3198 & 8) {
|
||||
if (!bvar) {
|
||||
direction |= data_80452F39;
|
||||
} else {
|
||||
direction |= data_80452F38;
|
||||
#if TARGET_PC
|
||||
if (dusk::getSettings().game.enableMirrorMode) {
|
||||
if (!bvar) {
|
||||
direction |= data_80452F38;
|
||||
} else {
|
||||
direction |= data_80452F39;
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
if (!bvar) {
|
||||
direction |= data_80452F39;
|
||||
} else {
|
||||
direction |= data_80452F38;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
#ifdef DUSK_DISCORD_RPC
|
||||
|
||||
#include "dusk/discord_presence.hpp"
|
||||
#include "dusk/logging.h"
|
||||
#include "dusk/main.h"
|
||||
#include "dusk/map_loader_definitions.h"
|
||||
#include "d/d_com_inf_game.h"
|
||||
#include "discord_rpc.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
namespace dusk {
|
||||
namespace discord {
|
||||
|
||||
static int64_t g_startTime = 0;
|
||||
static bool g_initialized = false;
|
||||
static const char* APPLICATION_ID = "1495632471994405035";
|
||||
|
||||
static void OnReady(const DiscordUser* user) {
|
||||
DuskLog.info("Discord: Connected as {}", user->username);
|
||||
}
|
||||
|
||||
static void OnDisconnected(int errorCode, const char* message) {
|
||||
DuskLog.warn("Discord: Disconnected ({}: {})", errorCode, message);
|
||||
}
|
||||
|
||||
static void OnError(int errorCode, const char* message) {
|
||||
DuskLog.warn("Discord: Error ({}: {})", errorCode, message);
|
||||
}
|
||||
|
||||
static const char* LookupMapName(const char* mapFile) {
|
||||
if (!mapFile || mapFile[0] == '\0') return nullptr;
|
||||
for (const auto& region : gameRegions) {
|
||||
for (const auto& map : region.maps) {
|
||||
if (map.mapFile && strcmp(mapFile, map.mapFile) == 0) {
|
||||
return map.mapName;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Initialize() {
|
||||
g_startTime = static_cast<int64_t>(
|
||||
std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()
|
||||
).count()
|
||||
);
|
||||
|
||||
DiscordEventHandlers handlers{};
|
||||
handlers.ready = OnReady;
|
||||
handlers.disconnected = OnDisconnected;
|
||||
handlers.errored = OnError;
|
||||
Discord_Initialize(APPLICATION_ID, &handlers, 0, nullptr);
|
||||
g_initialized = true;
|
||||
|
||||
DuskLog.info("Discord Rich Presence initialized");
|
||||
}
|
||||
|
||||
void RunCallbacks() {
|
||||
if (!g_initialized) return;
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
|
||||
void UpdatePresence() {
|
||||
if (!g_initialized) return;
|
||||
|
||||
static auto lastUpdate = std::chrono::steady_clock::time_point{};
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
if (now - lastUpdate < std::chrono::seconds(15)) return;
|
||||
lastUpdate = now;
|
||||
|
||||
static std::string detailsBuf;
|
||||
static std::string stateBuf;
|
||||
|
||||
DiscordRichPresence presence{};
|
||||
presence.startTimestamp = g_startTime;
|
||||
presence.largeImageKey = "icon";
|
||||
presence.largeImageText = "Dusk";
|
||||
|
||||
if (dusk::IsGameLaunched) {
|
||||
const char* stageName = dComIfGp_getLastPlayStageName();
|
||||
|
||||
// stageName is empty until a room is actually entered
|
||||
if (stageName[0] != '\0') {
|
||||
const char* locationName = LookupMapName(stageName);
|
||||
|
||||
if (locationName) {
|
||||
detailsBuf = locationName;
|
||||
}
|
||||
else {
|
||||
detailsBuf = "Twilight Princess";
|
||||
}
|
||||
|
||||
presence.details = detailsBuf.c_str();
|
||||
|
||||
stateBuf = fmt::format(FMT_STRING("{}/{} \u2665 | {} Rupees"),
|
||||
dComIfGs_getLife() / 4, dComIfGs_getMaxLife() / 5, dComIfGs_getRupee());
|
||||
|
||||
presence.state = stateBuf.c_str();
|
||||
}
|
||||
}
|
||||
|
||||
Discord_UpdatePresence(&presence);
|
||||
DuskLog.debug("Discord Rich Presence sent");
|
||||
}
|
||||
|
||||
void Shutdown() {
|
||||
if (!g_initialized) return;
|
||||
Discord_ClearPresence();
|
||||
Discord_Shutdown();
|
||||
g_initialized = false;
|
||||
DuskLog.info("Discord Rich Presence shut down");
|
||||
}
|
||||
|
||||
} // namespace discord
|
||||
} // namespace dusk
|
||||
|
||||
#endif // DUSK_DISCORD_RPC
|
||||
@@ -71,6 +71,7 @@
|
||||
#include "dusk/config.hpp"
|
||||
#include "dusk/settings.h"
|
||||
#include "dusk/imgui/ImGuiConsole.hpp"
|
||||
#include "dusk/discord_presence.hpp"
|
||||
#include "tracy/Tracy.hpp"
|
||||
#include "f_pc/f_pc_draw.h"
|
||||
|
||||
@@ -292,6 +293,11 @@ void main01(void) {
|
||||
aurora_end_frame();
|
||||
|
||||
FrameMark;
|
||||
|
||||
#ifdef DUSK_DISCORD_RPC
|
||||
dusk::discord::RunCallbacks();
|
||||
dusk::discord::UpdatePresence();
|
||||
#endif
|
||||
} while (dusk::IsRunning);
|
||||
|
||||
exit:;
|
||||
@@ -536,6 +542,10 @@ int game_main(int argc, char* argv[]) {
|
||||
|
||||
auroraInfo = aurora_initialize(argc, argv, &config);
|
||||
|
||||
#ifdef DUSK_DISCORD_RPC
|
||||
dusk::discord::Initialize();
|
||||
#endif
|
||||
|
||||
VISetWindowTitle(
|
||||
fmt::format("Dusk {} [{}]", DUSK_WC_DESCRIBE, dusk::backend_name(auroraInfo.backend))
|
||||
.c_str());
|
||||
@@ -569,6 +579,9 @@ int game_main(int argc, char* argv[]) {
|
||||
// pre game launch ui main loop
|
||||
if (!launchUILoop()) {
|
||||
dusk::ShutdownCrashReporting();
|
||||
#ifdef DUSK_DISCORD_RPC
|
||||
dusk::discord::Shutdown();
|
||||
#endif
|
||||
aurora_shutdown();
|
||||
return 0;
|
||||
}
|
||||
@@ -615,6 +628,9 @@ int game_main(int argc, char* argv[]) {
|
||||
// Notifies all CVs and causes threads to exit
|
||||
OSResetSystem(OS_RESET_SHUTDOWN, 0, 0);
|
||||
|
||||
#ifdef DUSK_DISCORD_RPC
|
||||
dusk::discord::Shutdown();
|
||||
#endif
|
||||
aurora_shutdown();
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user