[Linux] Add cvars to enable mangohud and gamemode

This commit is contained in:
Herman S.
2025-10-28 15:24:00 +09:00
parent 12ebb1e46d
commit 2e2dd8073f
2 changed files with 80 additions and 4 deletions
+37 -4
View File
@@ -200,6 +200,18 @@ DEFINE_int32(recent_titles_entry_amount, 10,
"Allows user to define how many titles is saved in list of "
"recently played titles.",
"General");
#if XE_PLATFORM_LINUX
DEFINE_bool(
use_mangohud, false,
"Enable MangoHUD overlay when launching games in separate processes.\n"
"MangoHUD must be installed on your system for this to work.",
"Linux");
DEFINE_bool(use_gamemode, false,
"Use Feral GameMode when launching games in separate processes.\n"
"GameMode must be installed on your system for this to work.",
"Linux");
#endif
namespace xe {
namespace app {
@@ -2238,8 +2250,23 @@ void EmulatorWindow::LaunchTitleInNewProcess(
if (pid == 0) {
// Child process
// Set MangoHUD environment variable if enabled
if (cvars::use_mangohud) {
setenv("MANGOHUD", "1", 1);
}
std::vector<const char*> argv;
argv.push_back(executable_path.c_str());
std::string gamemode_cmd;
// If GameMode is enabled, use gamemoderun as the executable
if (cvars::use_gamemode) {
gamemode_cmd = "gamemoderun";
argv.push_back(gamemode_cmd.c_str());
argv.push_back(executable_path.c_str());
} else {
argv.push_back(executable_path.c_str());
}
// Pass the config file if one is being used
std::string config_arg;
@@ -2270,10 +2297,16 @@ void EmulatorWindow::LaunchTitleInNewProcess(
argv.push_back(nullptr);
// Execute the new process
execv(executable_path.c_str(), const_cast<char**>(argv.data()));
if (cvars::use_gamemode) {
// Use execvp to search PATH for gamemoderun
execvp(gamemode_cmd.c_str(), const_cast<char**>(argv.data()));
} else {
execv(executable_path.c_str(), const_cast<char**>(argv.data()));
}
// If execv returns, it failed
XELOGE("Failed to execute: {}", executable_path.string());
// If exec returns, it failed
XELOGE("Failed to execute: {}",
cvars::use_gamemode ? gamemode_cmd : executable_path.string());
std::exit(1);
} else if (pid < 0) {
// Fork failed
+43
View File
@@ -29,6 +29,10 @@
#include "xenia/config.h"
#include "xenia/ui/config_helpers.h"
#if XE_PLATFORM_LINUX
#include <unistd.h>
#endif
namespace xe {
namespace app {
@@ -37,6 +41,28 @@ namespace {
// Use the shared enum options from config_helpers.h
using xe::ui::GetKnownEnumOptions;
#if XE_PLATFORM_LINUX
// Check if a command exists in PATH by searching each directory
bool IsCommandAvailable(const std::string& command) {
std::string path_env = std::getenv("PATH") ? std::getenv("PATH") : "";
if (path_env.empty()) {
return false;
}
// Split PATH by ':'
std::istringstream path_stream(path_env);
std::string path_dir;
while (std::getline(path_stream, path_dir, ':')) {
std::filesystem::path full_path = std::filesystem::path(path_dir) / command;
if (std::filesystem::exists(full_path) &&
access(full_path.c_str(), X_OK) == 0) {
return true;
}
}
return false;
}
#endif
} // namespace
ConfigDialogQt::ConfigDialogQt(QWidget* parent, EmulatorWindow* emulator_window)
@@ -246,6 +272,23 @@ QWidget* ConfigDialogQt::CreateEditorWidget(ConfigVarInfo* var_info) {
checkbox->setChecked(var_info->pending_value == "true");
connect(checkbox, &QCheckBox::checkStateChanged, this,
&ConfigDialogQt::OnValueChanged);
#if XE_PLATFORM_LINUX
// Disable Linux-specific options if the required tools aren't installed
if (var_info->name == "use_mangohud" && !IsCommandAvailable("mangohud")) {
checkbox->setEnabled(false);
checkbox->setToolTip(
"MangoHUD is not installed or not found in PATH. Install MangoHUD "
"to use this feature.");
} else if (var_info->name == "use_gamemode" &&
!IsCommandAvailable("gamemoderun")) {
checkbox->setEnabled(false);
checkbox->setToolTip(
"GameMode is not installed or not found in PATH. Install GameMode "
"to use this feature.");
}
#endif
return checkbox;
} else if (enum_it != enum_options.end()) {
// Dropdown for enum-like cvars