Port yuzu-emu/yuzu#11946: "Enable (Feral Interactive) Gamemode on Linux" (#7245)
This commit is contained in:
parent
2e369c03b8
commit
c7e9f8449e
14 changed files with 540 additions and 3 deletions
|
@ -38,6 +38,10 @@
|
|||
#include "network/network.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
|
||||
#ifdef __unix__
|
||||
#include "common/linux/gamemode.h"
|
||||
#endif
|
||||
|
||||
#undef _UNICODE
|
||||
#include <getopt.h>
|
||||
#ifndef _MSC_VER
|
||||
|
@ -442,6 +446,10 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef __unix__
|
||||
Common::Linux::StartGamemode();
|
||||
#endif
|
||||
|
||||
std::thread main_render_thread([&emu_window] { emu_window->Present(); });
|
||||
std::thread secondary_render_thread([&secondary_window] {
|
||||
if (secondary_window) {
|
||||
|
@ -493,6 +501,10 @@ int main(int argc, char** argv) {
|
|||
|
||||
system.Shutdown();
|
||||
|
||||
#ifdef __unix__
|
||||
Common::Linux::StopGamemode();
|
||||
#endif
|
||||
|
||||
detached_tasks.WaitForAllTasks();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -308,7 +308,7 @@ if (NOT WIN32)
|
|||
endif()
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_link_libraries(citra-qt PRIVATE Qt6::DBus)
|
||||
target_link_libraries(citra-qt PRIVATE Qt6::DBus gamemode)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(citra-qt PRIVATE
|
||||
|
|
|
@ -528,6 +528,7 @@ void Config::ReadMiscellaneousValues() {
|
|||
qt_config->beginGroup(QStringLiteral("Miscellaneous"));
|
||||
|
||||
ReadBasicSetting(Settings::values.log_filter);
|
||||
ReadBasicSetting(Settings::values.enable_gamemode);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
@ -1044,6 +1045,7 @@ void Config::SaveMiscellaneousValues() {
|
|||
qt_config->beginGroup(QStringLiteral("Miscellaneous"));
|
||||
|
||||
WriteBasicSetting(Settings::values.log_filter);
|
||||
WriteBasicSetting(Settings::values.enable_gamemode);
|
||||
|
||||
qt_config->endGroup();
|
||||
}
|
||||
|
|
|
@ -36,6 +36,9 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
|||
ui->emulation_speed_combo->setVisible(!Settings::IsConfiguringGlobal());
|
||||
ui->screenshot_combo->setVisible(!Settings::IsConfiguringGlobal());
|
||||
ui->updateBox->setVisible(UISettings::values.updater_found);
|
||||
#ifndef __unix__
|
||||
ui->toggle_gamemode->setVisible(false);
|
||||
#endif
|
||||
|
||||
SetupPerGameUI();
|
||||
SetConfiguration();
|
||||
|
@ -76,6 +79,9 @@ void ConfigureGeneral::SetConfiguration() {
|
|||
ui->toggle_update_check->setChecked(
|
||||
UISettings::values.check_for_update_on_start.GetValue());
|
||||
ui->toggle_auto_update->setChecked(UISettings::values.update_on_close.GetValue());
|
||||
#ifdef __unix__
|
||||
ui->toggle_gamemode->setChecked(Settings::values.enable_gamemode.GetValue());
|
||||
#endif
|
||||
}
|
||||
|
||||
if (Settings::values.frame_limit.GetValue() == 0) {
|
||||
|
@ -172,6 +178,9 @@ void ConfigureGeneral::ApplyConfiguration() {
|
|||
|
||||
UISettings::values.check_for_update_on_start = ui->toggle_update_check->isChecked();
|
||||
UISettings::values.update_on_close = ui->toggle_auto_update->isChecked();
|
||||
#ifdef __unix__
|
||||
Settings::values.enable_gamemode = ui->toggle_gamemode->isChecked();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,6 +210,7 @@ void ConfigureGeneral::SetupPerGameUI() {
|
|||
ui->general_group->setVisible(false);
|
||||
ui->updateBox->setVisible(false);
|
||||
ui->button_reset_defaults->setVisible(false);
|
||||
ui->toggle_gamemode->setVisible(false);
|
||||
|
||||
ConfigurationShared::SetColoredComboBox(
|
||||
ui->region_combobox, ui->widget_region,
|
||||
|
|
|
@ -43,6 +43,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="toggle_gamemode">
|
||||
<property name="text">
|
||||
<string>Enable Gamemode</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QVariant>
|
||||
#include <QtDBus/QDBusInterface>
|
||||
#include <QtDBus/QtDBus>
|
||||
#include "common/linux/gamemode.h"
|
||||
#endif
|
||||
#include "citra_qt/aboutdialog.h"
|
||||
#include "citra_qt/applets/mii_selector.h"
|
||||
|
@ -182,6 +183,10 @@ GMainWindow::GMainWindow(Core::System& system_)
|
|||
|
||||
Debugger::ToggleConsole();
|
||||
|
||||
#ifdef __unix__
|
||||
SetGamemodeEnabled(Settings::values.enable_gamemode.GetValue());
|
||||
#endif
|
||||
|
||||
// register types to use in slots and signals
|
||||
qRegisterMetaType<std::size_t>("std::size_t");
|
||||
qRegisterMetaType<Service::AM::InstallStatus>("Service::AM::InstallStatus");
|
||||
|
@ -1323,6 +1328,10 @@ void GMainWindow::ShutdownGame() {
|
|||
|
||||
discord_rpc->Update();
|
||||
|
||||
#ifdef __unix__
|
||||
Common::Linux::StopGamemode();
|
||||
#endif
|
||||
|
||||
// The emulation is stopped, so closing the window or not does not matter anymore
|
||||
disconnect(render_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
|
||||
disconnect(secondary_window, &GRenderWindow::Closed, this, &GMainWindow::OnStopGame);
|
||||
|
@ -1834,6 +1843,10 @@ void GMainWindow::OnStartGame() {
|
|||
|
||||
discord_rpc->Update();
|
||||
|
||||
#ifdef __unix__
|
||||
Common::Linux::StartGamemode();
|
||||
#endif
|
||||
|
||||
UpdateSaveStates();
|
||||
UpdateAPIIndicator();
|
||||
}
|
||||
|
@ -1852,6 +1865,10 @@ void GMainWindow::OnPauseGame() {
|
|||
|
||||
UpdateMenuState();
|
||||
AllowOSSleep();
|
||||
|
||||
#ifdef __unix__
|
||||
Common::Linux::StopGamemode();
|
||||
#endif
|
||||
}
|
||||
|
||||
void GMainWindow::OnPauseContinueGame() {
|
||||
|
@ -2076,15 +2093,25 @@ void GMainWindow::OnConfigure() {
|
|||
const auto old_input_profiles = Settings::values.input_profiles;
|
||||
const auto old_touch_from_button_maps = Settings::values.touch_from_button_maps;
|
||||
const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
|
||||
#ifdef __unix__
|
||||
const bool old_gamemode = Settings::values.enable_gamemode.GetValue();
|
||||
#endif
|
||||
auto result = configureDialog.exec();
|
||||
game_list->SetDirectoryWatcherEnabled(true);
|
||||
if (result == QDialog::Accepted) {
|
||||
configureDialog.ApplyConfiguration();
|
||||
InitializeHotkeys();
|
||||
if (UISettings::values.theme != old_theme)
|
||||
if (UISettings::values.theme != old_theme) {
|
||||
UpdateUITheme();
|
||||
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());
|
||||
}
|
||||
#ifdef __unix__
|
||||
if (Settings::values.enable_gamemode.GetValue() != old_gamemode) {
|
||||
SetGamemodeEnabled(Settings::values.enable_gamemode.GetValue());
|
||||
}
|
||||
#endif
|
||||
if (!multiplayer_state->IsHostingPublicRoom())
|
||||
multiplayer_state->UpdateCredentials();
|
||||
emit UpdateThemedIcons();
|
||||
|
@ -2931,6 +2958,14 @@ void GMainWindow::SetDiscordEnabled([[maybe_unused]] bool state) {
|
|||
discord_rpc->Update();
|
||||
}
|
||||
|
||||
#ifdef __unix__
|
||||
void GMainWindow::SetGamemodeEnabled(bool state) {
|
||||
if (emulation_running) {
|
||||
Common::Linux::SetGamemodeState(state);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef main
|
||||
#undef main
|
||||
#endif
|
||||
|
|
|
@ -276,6 +276,9 @@ private:
|
|||
void ShowMouseCursor();
|
||||
void OpenPerGameConfiguration(u64 title_id, const QString& file_name);
|
||||
void UpdateAPIIndicator(bool update = false);
|
||||
#ifdef __unix__
|
||||
void SetGamemodeEnabled(bool state);
|
||||
#endif
|
||||
|
||||
std::unique_ptr<Ui::MainWindow> ui;
|
||||
Core::System& system;
|
||||
|
|
|
@ -154,6 +154,15 @@ add_library(citra_common STATIC
|
|||
zstd_compression.h
|
||||
)
|
||||
|
||||
if (UNIX AND NOT APPLE)
|
||||
target_sources(citra_common PRIVATE
|
||||
linux/gamemode.cpp
|
||||
linux/gamemode.h
|
||||
)
|
||||
|
||||
target_link_libraries(citra_common PRIVATE gamemode)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
target_sources(citra_common PUBLIC
|
||||
apple_authorization.h
|
||||
|
|
39
src/common/linux/gamemode.cpp
Normal file
39
src/common/linux/gamemode.cpp
Normal file
|
@ -0,0 +1,39 @@
|
|||
// 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/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
Normal file
24
src/common/linux/gamemode.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
// 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
|
|
@ -421,6 +421,8 @@ struct Values {
|
|||
std::vector<InputProfile> input_profiles; ///< The list of input profiles
|
||||
std::vector<TouchFromButtonMap> touch_from_button_maps;
|
||||
|
||||
SwitchableSetting<bool> enable_gamemode{true, "enable_gamemode"};
|
||||
|
||||
// Core
|
||||
Setting<bool> use_cpu_jit{true, "use_cpu_jit"};
|
||||
SwitchableSetting<s32, true> cpu_clock_percentage{100, 5, 400, "cpu_clock_percentage"};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue