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
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)
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.
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)
{

8
src/common/CMakeLists.txt

@ -65,6 +65,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
@ -181,11 +183,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(

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

16
src/yuzu_cmd/yuzu.cpp

@ -59,10 +59,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
@ -427,10 +424,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()) {
@ -442,11 +436,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;
}

Loading…
Cancel
Save