Browse Source

[gamemode] Make available on other platforms

Signed-off-by: lizzie <lizzie@eden-emu.dev>
pull/353/head
lizzie 4 months ago
committed by Caio Oliveira
parent
commit
cd4ea20ce0
No known key found for this signature in database GPG Key ID: 362DA3DC1901E080
  1. 2
      CMakeLists.txt
  2. 28
      externals/gamemode/gamemode_client.h
  3. 8
      src/common/CMakeLists.txt
  4. 50
      src/common/gamemode.cpp
  5. 17
      src/common/gamemode.h
  6. 40
      src/common/linux/gamemode.cpp
  7. 24
      src/common/linux/gamemode.h
  8. 14
      src/yuzu/main_window.cpp
  9. 16
      src/yuzu_cmd/yuzu.cpp

2
CMakeLists.txt

@ -487,7 +487,7 @@ else()
# wow # wow
find_package(Boost 1.57.0 CONFIG REQUIRED OPTIONAL_COMPONENTS headers context system fiber filesystem) find_package(Boost 1.57.0 CONFIG REQUIRED OPTIONAL_COMPONENTS headers context system fiber filesystem)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux" OR ANDROID)
if (PLATFORM_LINUX OR ANDROID)
find_package(gamemode 1.7 MODULE) find_package(gamemode 1.7 MODULE)
endif() endif()

28
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. All rights reserved.
Redistribution and use in source and binary forms, with or without 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_start = NULL;
static api_call_return_int REAL_internal_gamemode_request_end = 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_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_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_start_for = NULL;
static api_call_pid_return_int REAL_internal_gamemode_request_end_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, (void **)&REAL_internal_gamemode_query_status,
sizeof(REAL_internal_gamemode_query_status), sizeof(REAL_internal_gamemode_query_status),
false }, false },
{ "real_gamemode_request_restart",
(void **)&REAL_internal_gamemode_request_restart,
sizeof(REAL_internal_gamemode_request_restart),
false },
{ "real_gamemode_error_string", { "real_gamemode_error_string",
(void **)&REAL_internal_gamemode_error_string, (void **)&REAL_internal_gamemode_error_string,
sizeof(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(); 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 */ /* Redirect to the real libgamemode */
__attribute__((always_inline)) static inline int gamemode_request_start_for(pid_t pid) __attribute__((always_inline)) static inline int gamemode_request_start_for(pid_t pid)
{ {

8
src/common/CMakeLists.txt

@ -65,6 +65,8 @@ add_library(
fs/fs_util.h fs/fs_util.h
fs/path_util.cpp fs/path_util.cpp
fs/path_util.h fs/path_util.h
gamemode.cpp
gamemode.h
hash.h hash.h
heap_tracker.cpp heap_tracker.cpp
heap_tracker.h heap_tracker.h
@ -181,11 +183,7 @@ if(ANDROID)
android/applets/software_keyboard.h) android/applets/software_keyboard.h)
endif() 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) if(ARCHITECTURE_x86_64)
target_sources( target_sources(

50
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 <gamemode_client.h>
#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

17
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

40
src/common/linux/gamemode.cpp

@ -1,40 +0,0 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <gamemode_client.h>
#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

24
src/common/linux/gamemode.h

@ -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

14
src/yuzu/main_window.cpp

@ -164,9 +164,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#endif #endif
#ifdef __linux__
#include "common/linux/gamemode.h" #include "common/linux/gamemode.h"
#endif
#ifdef _WIN32 #ifdef _WIN32
#include "core/core_timing.h" #include "core/core_timing.h"
@ -423,9 +421,7 @@ MainWindow::MainWindow(bool has_broken_vulkan)
SetupSigInterrupts(); SetupSigInterrupts();
#endif #endif
#ifdef __linux__
SetGamemodeEnabled(Settings::values.enable_gamemode.GetValue()); SetGamemodeEnabled(Settings::values.enable_gamemode.GetValue());
#endif
UISettings::RestoreWindowState(config); UISettings::RestoreWindowState(config);
@ -2198,10 +2194,7 @@ void MainWindow::OnEmulationStopped() {
emulation_running = false; emulation_running = false;
discord_rpc->Update(); discord_rpc->Update();
#ifdef __linux__
Common::Linux::StopGamemode(); Common::Linux::StopGamemode();
#endif
// The emulation is stopped, so closing the window or not does not matter anymore // The emulation is stopped, so closing the window or not does not matter anymore
disconnect(render_window, &GRenderWindow::Closed, this, &MainWindow::OnStopGame); disconnect(render_window, &GRenderWindow::Closed, this, &MainWindow::OnStopGame);
@ -3072,10 +3065,7 @@ void MainWindow::OnStartGame() {
play_time_manager->Start(); play_time_manager->Start();
discord_rpc->Update(); discord_rpc->Update();
#ifdef __linux__
Common::Linux::StartGamemode(); Common::Linux::StartGamemode();
#endif
} }
void MainWindow::OnRestartGame() { void MainWindow::OnRestartGame() {
@ -3449,11 +3439,9 @@ void MainWindow::OnConfigure() {
if (UISettings::values.enable_discord_presence.GetValue() != old_discord_presence) { if (UISettings::values.enable_discord_presence.GetValue() != old_discord_presence) {
SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue()); SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue());
} }
#ifdef __linux__
if (Settings::values.enable_gamemode.GetValue() != old_gamemode) { if (Settings::values.enable_gamemode.GetValue() != old_gamemode) {
SetGamemodeEnabled(Settings::values.enable_gamemode.GetValue()); SetGamemodeEnabled(Settings::values.enable_gamemode.GetValue());
} }
#endif
#ifdef __unix__ #ifdef __unix__
if (Settings::values.gui_force_x11.GetValue() != old_force_x11) { if (Settings::values.gui_force_x11.GetValue() != old_force_x11) {
GraphicsBackend::SetForceX11(Settings::values.gui_force_x11.GetValue()); GraphicsBackend::SetForceX11(Settings::values.gui_force_x11.GetValue());
@ -4760,13 +4748,11 @@ void MainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
discord_rpc->Update(); discord_rpc->Update();
} }
#ifdef __linux__
void MainWindow::SetGamemodeEnabled(bool state) { void MainWindow::SetGamemodeEnabled(bool state) {
if (emulation_running) { if (emulation_running) {
Common::Linux::SetGamemodeState(state); Common::Linux::SetGamemodeState(state);
} }
} }
#endif
void MainWindow::changeEvent(QEvent* event) { void MainWindow::changeEvent(QEvent* event) {
#ifdef __unix__ #ifdef __unix__

16
src/yuzu_cmd/yuzu.cpp

@ -59,10 +59,7 @@ __declspec(dllexport) unsigned long NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
} }
#endif #endif
#ifdef __linux__
#include "common/linux/gamemode.h"
#endif
#include "common/gamemode.h"
static void PrintHelp(const char* argv0) { static void PrintHelp(const char* argv0) {
std::cout << "Usage: " << argv0 std::cout << "Usage: " << argv0
@ -427,10 +424,7 @@ int main(int argc, char** argv) {
// Just exit right away. // Just exit right away.
exit(0); exit(0);
}); });
#ifdef __linux__
Common::Linux::StartGamemode();
#endif
Common::FeralGamemode::StartGamemode();
void(system.Run()); void(system.Run());
if (system.DebuggerEnabled()) { if (system.DebuggerEnabled()) {
@ -442,11 +436,7 @@ int main(int argc, char** argv) {
system.DetachDebugger(); system.DetachDebugger();
void(system.Pause()); void(system.Pause());
system.ShutdownMainProcess(); system.ShutdownMainProcess();
#ifdef __linux__
Common::Linux::StopGamemode();
#endif
Common::FeralGamemode::Stop();
detached_tasks.WaitForAllTasks(); detached_tasks.WaitForAllTasks();
return 0; return 0;
} }

Loading…
Cancel
Save