From efab0b162b7aead9935626d2fbd875cb15406e04 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 29 Aug 2025 23:48:25 +0000 Subject: [PATCH] [gamemode] Make available on other platforms Signed-off-by: lizzie --- CMakeLists.txt | 2 +- externals/gamemode/gamemode_client.h | 28 +++++++++++++++- src/common/CMakeLists.txt | 8 ++--- src/common/gamemode.cpp | 50 ++++++++++++++++++++++++++++ src/common/gamemode.h | 17 ++++++++++ src/common/linux/gamemode.cpp | 40 ---------------------- src/common/linux/gamemode.h | 24 ------------- src/yuzu/main.cpp | 18 +++------- src/yuzu_cmd/yuzu.cpp | 16 ++------- 9 files changed, 105 insertions(+), 98 deletions(-) create mode 100644 src/common/gamemode.cpp create mode 100644 src/common/gamemode.h delete mode 100644 src/common/linux/gamemode.cpp delete mode 100644 src/common/linux/gamemode.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a9e15cfbd..9b5fae07f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -473,7 +473,7 @@ else() find_package(Catch2 3.0.1 REQUIRED) endif() - if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID) + if (PLATFORM_LINUX OR ANDROID) find_package(gamemode 1.7 MODULE) endif() diff --git a/externals/gamemode/gamemode_client.h b/externals/gamemode/gamemode_client.h index b9f64fe460..bfbf61c0c2 100644 --- a/externals/gamemode/gamemode_client.h +++ b/externals/gamemode/gamemode_client.h @@ -1,6 +1,9 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + /* -Copyright (c) 2017-2019, Feral Interactive +Copyright (c) 2017-2025, Feral Interactive and the GameMode contributors All rights reserved. Redistribution and use in source and binary forms, with or without @@ -103,6 +106,7 @@ typedef int (*api_call_pid_return_int)(pid_t); static api_call_return_int REAL_internal_gamemode_request_start = NULL; static api_call_return_int REAL_internal_gamemode_request_end = NULL; static api_call_return_int REAL_internal_gamemode_query_status = NULL; +static api_call_return_int REAL_internal_gamemode_request_restart = NULL; static api_call_return_cstring REAL_internal_gamemode_error_string = NULL; static api_call_pid_return_int REAL_internal_gamemode_request_start_for = NULL; static api_call_pid_return_int REAL_internal_gamemode_request_end_for = NULL; @@ -166,6 +170,10 @@ __attribute__((always_inline)) static inline int internal_load_libgamemode(void) (void **)&REAL_internal_gamemode_query_status, sizeof(REAL_internal_gamemode_query_status), false }, + { "real_gamemode_request_restart", + (void **)&REAL_internal_gamemode_request_restart, + sizeof(REAL_internal_gamemode_request_restart), + false }, { "real_gamemode_error_string", (void **)&REAL_internal_gamemode_error_string, sizeof(REAL_internal_gamemode_error_string), @@ -319,6 +327,24 @@ __attribute__((always_inline)) static inline int gamemode_query_status(void) return REAL_internal_gamemode_query_status(); } +/* Redirect to the real libgamemode */ +__attribute__((always_inline)) static inline int gamemode_request_restart(void) +{ + /* Need to load gamemode */ + if (internal_load_libgamemode() < 0) { + return -1; + } + + if (REAL_internal_gamemode_request_restart == NULL) { + snprintf(internal_gamemode_client_error_string, + sizeof(internal_gamemode_client_error_string), + "gamemode_request_restart missing (older host?)"); + return -1; + } + + return REAL_internal_gamemode_request_restart(); +} + /* Redirect to the real libgamemode */ __attribute__((always_inline)) static inline int gamemode_request_start_for(pid_t pid) { diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 665143900a..3683052c30 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -69,6 +69,8 @@ add_library( fs/fs_util.h fs/path_util.cpp fs/path_util.h + gamemode.cpp + gamemode.h hash.h heap_tracker.cpp heap_tracker.h @@ -187,11 +189,7 @@ if(ANDROID) android/applets/software_keyboard.h) endif() -if(LINUX AND NOT APPLE) - target_sources(common PRIVATE linux/gamemode.cpp linux/gamemode.h) - - target_link_libraries(common PRIVATE gamemode::headers) -endif() +target_link_libraries(common PRIVATE gamemode::headers) if(ARCHITECTURE_x86_64) target_sources( diff --git a/src/common/gamemode.cpp b/src/common/gamemode.cpp new file mode 100644 index 0000000000..a3f0ba37ab --- /dev/null +++ b/src/common/gamemode.cpp @@ -0,0 +1,50 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +// While technically available on al *NIX platforms, Linux is only available +// as the primary target of libgamemode.so - so warnings are suppressed +#ifdef __unix__ +#include +#endif +#include "common/gamemode.h" +#include "common/logging/log.h" +#include "common/settings.h" + +namespace Common::FeralGamemode { + +void Start() noexcept { + if (Settings::values.enable_gamemode) { +#ifdef __unix__ + if (gamemode_request_start() < 0) { +#ifdef __linux__ + LOG_WARNING(Frontend, "{}", gamemode_error_string()); +#else + LOG_INFO(Frontend, "{}", gamemode_error_string()); +#endif + } else { + LOG_INFO(Frontend, "Done"); + } +#endif + } +} + +void Stop() noexcept { + if (Settings::values.enable_gamemode) { +#ifdef __unix__ + if (gamemode_request_end() < 0) { +#ifdef __linux__ + LOG_WARNING(Frontend, "{}", gamemode_error_string()); +#else + LOG_INFO(Frontend, "{}", gamemode_error_string()); +#endif + } else { + LOG_INFO(Frontend, "Done"); + } +#endif + } +} + +} // namespace Common::Linux diff --git a/src/common/gamemode.h b/src/common/gamemode.h new file mode 100644 index 0000000000..05b1936bb5 --- /dev/null +++ b/src/common/gamemode.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +namespace Common::FeralGamemode { + +/// @brief Start the gamemode client +void Start() noexcept; + +/// @brief Stop the gmemode client +void Stop() noexcept; + +} // namespace Common::FeralGamemode diff --git a/src/common/linux/gamemode.cpp b/src/common/linux/gamemode.cpp deleted file mode 100644 index 8d3e2934a6..0000000000 --- a/src/common/linux/gamemode.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include - -#include "common/linux/gamemode.h" -#include "common/logging/log.h" -#include "common/settings.h" - -namespace Common::Linux { - -void StartGamemode() { - if (Settings::values.enable_gamemode) { - if (gamemode_request_start() < 0) { - LOG_WARNING(Frontend, "Failed to start gamemode: {}", gamemode_error_string()); - } else { - LOG_INFO(Frontend, "Started gamemode"); - } - } -} - -void StopGamemode() { - if (Settings::values.enable_gamemode) { - if (gamemode_request_end() < 0) { - LOG_WARNING(Frontend, "Failed to stop gamemode: {}", gamemode_error_string()); - } else { - LOG_INFO(Frontend, "Stopped gamemode"); - } - } -} - -void SetGamemodeState(bool state) { - if (state) { - StartGamemode(); - } else { - StopGamemode(); - } -} - -} // namespace Common::Linux diff --git a/src/common/linux/gamemode.h b/src/common/linux/gamemode.h deleted file mode 100644 index b80646ae27..0000000000 --- a/src/common/linux/gamemode.h +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -namespace Common::Linux { - -/** - * Start the (Feral Interactive) Linux gamemode if it is installed and it is activated - */ -void StartGamemode(); - -/** - * Stop the (Feral Interactive) Linux gamemode if it is installed and it is activated - */ -void StopGamemode(); - -/** - * Start or stop the (Feral Interactive) Linux gamemode if it is installed and it is activated - * @param state The new state the gamemode should have - */ -void SetGamemodeState(bool state); - -} // namespace Common::Linux diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index e23e9a6a48..ab646eb622 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -21,9 +21,7 @@ #include #include #endif -#ifdef __linux__ -#include "common/linux/gamemode.h" -#endif +#include "common/gamemode.h" #include @@ -2393,9 +2391,7 @@ void GMainWindow::OnEmulationStopped() { discord_rpc->Update(); -#ifdef __linux__ - Common::Linux::StopGamemode(); -#endif + Common::FeralGamemode::Stop(); // The emulation is stopped, so closing the window or not does not matter anymore disconnect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame); @@ -3578,10 +3574,7 @@ void GMainWindow::OnStartGame() { play_time_manager->Start(); discord_rpc->Update(); - -#ifdef __linux__ - Common::Linux::StartGamemode(); -#endif + Common::FeralGamemode::StartGamemode(); } void GMainWindow::OnRestartGame() { @@ -3602,10 +3595,7 @@ void GMainWindow::OnPauseGame() { play_time_manager->Stop(); UpdateMenuState(); AllowOSSleep(); - -#ifdef __linux__ - Common::Linux::StopGamemode(); -#endif + Common::FeralGamemode::Stop(); } void GMainWindow::OnPauseContinueGame() { diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 599582aba9..7400b48e47 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -63,10 +63,7 @@ __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001; __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; } #endif - -#ifdef __linux__ -#include "common/linux/gamemode.h" -#endif +#include "common/gamemode.h" static void PrintHelp(const char* argv0) { std::cout << "Usage: " << argv0 @@ -435,10 +432,7 @@ int main(int argc, char** argv) { // Just exit right away. exit(0); }); - -#ifdef __linux__ - Common::Linux::StartGamemode(); -#endif + Common::FeralGamemode::StartGamemode(); void(system.Run()); if (system.DebuggerEnabled()) { @@ -450,11 +444,7 @@ int main(int argc, char** argv) { system.DetachDebugger(); void(system.Pause()); system.ShutdownMainProcess(); - -#ifdef __linux__ - Common::Linux::StopGamemode(); -#endif - + Common::FeralGamemode::Stop(); detached_tasks.WaitForAllTasks(); return 0; }