Browse Source
[gamemode] Make available on other platforms (#353)
[gamemode] Make available on other platforms (#353)
Signed-off-by: lizzie <lizzie@eden-emu.dev> Co-authored-by: crueter <crueter@eden-emu.dev> Co-authored-by: Caio Oliveira <caiooliveirafarias0@gmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/353 Reviewed-by: CamilleLaVey <camillelavey99@gmail.com> Reviewed-by: Caio Oliveira <caiooliveirafarias0@gmail.com> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>pull/3160/head
committed by
crueter
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
29 changed files with 123 additions and 775 deletions
-
5CMakeLists.txt
-
6externals/CMakeLists.txt
-
7externals/cpmfile.json
-
376externals/gamemode/gamemode_client.h
-
6src/common/CMakeLists.txt
-
40src/common/linux/gamemode.cpp
-
24src/common/linux/gamemode.h
-
2src/common/settings.cpp
-
7src/common/settings.h
-
4src/common/settings_common.h
-
26src/frontend_common/config.cpp
-
6src/frontend_common/config.h
-
4src/qt_common/CMakeLists.txt
-
6src/qt_common/config/shared_translation.cpp
-
13src/qt_common/config/uisettings.h
-
52src/qt_common/gamemode.cpp
-
14src/qt_common/gamemode.h
-
3src/yuzu/CMakeLists.txt
-
15src/yuzu/configuration/configure_general.cpp
-
27src/yuzu/configuration/configure_general.ui
-
75src/yuzu/configuration/configure_linux_tab.cpp
-
44src/yuzu/configuration/configure_linux_tab.h
-
53src/yuzu/configuration/configure_linux_tab.ui
-
9src/yuzu/configuration/configure_per_game.cpp
-
2src/yuzu/configuration/configure_per_game.h
-
4src/yuzu/main.cpp
-
52src/yuzu/main_window.cpp
-
2src/yuzu/main_window.h
-
14src/yuzu_cmd/yuzu.cpp
@ -1,376 +0,0 @@ |
|||||
/* |
|
||||
|
|
||||
Copyright (c) 2017-2019, Feral Interactive |
|
||||
All rights reserved. |
|
||||
|
|
||||
Redistribution and use in source and binary forms, with or without |
|
||||
modification, are permitted provided that the following conditions are met: |
|
||||
|
|
||||
* Redistributions of source code must retain the above copyright notice, |
|
||||
this list of conditions and the following disclaimer. |
|
||||
* Redistributions in binary form must reproduce the above copyright |
|
||||
notice, this list of conditions and the following disclaimer in the |
|
||||
documentation and/or other materials provided with the distribution. |
|
||||
* Neither the name of Feral Interactive nor the names of its contributors |
|
||||
may be used to endorse or promote products derived from this software |
|
||||
without specific prior written permission. |
|
||||
|
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
||||
POSSIBILITY OF SUCH DAMAGE. |
|
||||
|
|
||||
*/ |
|
||||
#ifndef CLIENT_GAMEMODE_H |
|
||||
#define CLIENT_GAMEMODE_H |
|
||||
/* |
|
||||
* GameMode supports the following client functions |
|
||||
* Requests are refcounted in the daemon |
|
||||
* |
|
||||
* int gamemode_request_start() - Request gamemode starts |
|
||||
* 0 if the request was sent successfully |
|
||||
* -1 if the request failed |
|
||||
* |
|
||||
* int gamemode_request_end() - Request gamemode ends |
|
||||
* 0 if the request was sent successfully |
|
||||
* -1 if the request failed |
|
||||
* |
|
||||
* GAMEMODE_AUTO can be defined to make the above two functions apply during static init and |
|
||||
* destruction, as appropriate. In this configuration, errors will be printed to stderr |
|
||||
* |
|
||||
* int gamemode_query_status() - Query the current status of gamemode |
|
||||
* 0 if gamemode is inactive |
|
||||
* 1 if gamemode is active |
|
||||
* 2 if gamemode is active and this client is registered |
|
||||
* -1 if the query failed |
|
||||
* |
|
||||
* int gamemode_request_start_for(pid_t pid) - Request gamemode starts for another process |
|
||||
* 0 if the request was sent successfully |
|
||||
* -1 if the request failed |
|
||||
* -2 if the request was rejected |
|
||||
* |
|
||||
* int gamemode_request_end_for(pid_t pid) - Request gamemode ends for another process |
|
||||
* 0 if the request was sent successfully |
|
||||
* -1 if the request failed |
|
||||
* -2 if the request was rejected |
|
||||
* |
|
||||
* int gamemode_query_status_for(pid_t pid) - Query status of gamemode for another process |
|
||||
* 0 if gamemode is inactive |
|
||||
* 1 if gamemode is active |
|
||||
* 2 if gamemode is active and this client is registered |
|
||||
* -1 if the query failed |
|
||||
* |
|
||||
* const char* gamemode_error_string() - Get an error string |
|
||||
* returns a string describing any of the above errors |
|
||||
* |
|
||||
* Note: All the above requests can be blocking - dbus requests can and will block while the daemon |
|
||||
* handles the request. It is not recommended to make these calls in performance critical code |
|
||||
*/ |
|
||||
|
|
||||
#include <stdbool.h> |
|
||||
#include <stdio.h> |
|
||||
|
|
||||
#include <dlfcn.h> |
|
||||
#include <string.h> |
|
||||
|
|
||||
#include <assert.h> |
|
||||
|
|
||||
#include <sys/types.h> |
|
||||
|
|
||||
static char internal_gamemode_client_error_string[512] = { 0 }; |
|
||||
|
|
||||
/** |
|
||||
* Load libgamemode dynamically to dislodge us from most dependencies. |
|
||||
* This allows clients to link and/or use this regardless of runtime. |
|
||||
* See SDL2 for an example of the reasoning behind this in terms of |
|
||||
* dynamic versioning as well. |
|
||||
*/ |
|
||||
static volatile int internal_libgamemode_loaded = 1; |
|
||||
|
|
||||
/* Typedefs for the functions to load */ |
|
||||
typedef int (*api_call_return_int)(void); |
|
||||
typedef const char *(*api_call_return_cstring)(void); |
|
||||
typedef int (*api_call_pid_return_int)(pid_t); |
|
||||
|
|
||||
/* Storage for functors */ |
|
||||
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_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; |
|
||||
static api_call_pid_return_int REAL_internal_gamemode_query_status_for = NULL; |
|
||||
|
|
||||
/** |
|
||||
* Internal helper to perform the symbol binding safely. |
|
||||
* |
|
||||
* Returns 0 on success and -1 on failure |
|
||||
*/ |
|
||||
__attribute__((always_inline)) static inline int internal_bind_libgamemode_symbol( |
|
||||
void *handle, const char *name, void **out_func, size_t func_size, bool required) |
|
||||
{ |
|
||||
void *symbol_lookup = NULL; |
|
||||
char *dl_error = NULL; |
|
||||
|
|
||||
/* Safely look up the symbol */ |
|
||||
symbol_lookup = dlsym(handle, name); |
|
||||
dl_error = dlerror(); |
|
||||
if (required && (dl_error || !symbol_lookup)) { |
|
||||
snprintf(internal_gamemode_client_error_string, |
|
||||
sizeof(internal_gamemode_client_error_string), |
|
||||
"dlsym failed - %s", |
|
||||
dl_error); |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
/* Have the symbol correctly, copy it to make it usable */ |
|
||||
memcpy(out_func, &symbol_lookup, func_size); |
|
||||
return 0; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Loads libgamemode and needed functions |
|
||||
* |
|
||||
* Returns 0 on success and -1 on failure |
|
||||
*/ |
|
||||
__attribute__((always_inline)) static inline int internal_load_libgamemode(void) |
|
||||
{ |
|
||||
/* We start at 1, 0 is a success and -1 is a fail */ |
|
||||
if (internal_libgamemode_loaded != 1) { |
|
||||
return internal_libgamemode_loaded; |
|
||||
} |
|
||||
|
|
||||
/* Anonymous struct type to define our bindings */ |
|
||||
struct binding { |
|
||||
const char *name; |
|
||||
void **functor; |
|
||||
size_t func_size; |
|
||||
bool required; |
|
||||
} bindings[] = { |
|
||||
{ "real_gamemode_request_start", |
|
||||
(void **)&REAL_internal_gamemode_request_start, |
|
||||
sizeof(REAL_internal_gamemode_request_start), |
|
||||
true }, |
|
||||
{ "real_gamemode_request_end", |
|
||||
(void **)&REAL_internal_gamemode_request_end, |
|
||||
sizeof(REAL_internal_gamemode_request_end), |
|
||||
true }, |
|
||||
{ "real_gamemode_query_status", |
|
||||
(void **)&REAL_internal_gamemode_query_status, |
|
||||
sizeof(REAL_internal_gamemode_query_status), |
|
||||
false }, |
|
||||
{ "real_gamemode_error_string", |
|
||||
(void **)&REAL_internal_gamemode_error_string, |
|
||||
sizeof(REAL_internal_gamemode_error_string), |
|
||||
true }, |
|
||||
{ "real_gamemode_request_start_for", |
|
||||
(void **)&REAL_internal_gamemode_request_start_for, |
|
||||
sizeof(REAL_internal_gamemode_request_start_for), |
|
||||
false }, |
|
||||
{ "real_gamemode_request_end_for", |
|
||||
(void **)&REAL_internal_gamemode_request_end_for, |
|
||||
sizeof(REAL_internal_gamemode_request_end_for), |
|
||||
false }, |
|
||||
{ "real_gamemode_query_status_for", |
|
||||
(void **)&REAL_internal_gamemode_query_status_for, |
|
||||
sizeof(REAL_internal_gamemode_query_status_for), |
|
||||
false }, |
|
||||
}; |
|
||||
|
|
||||
void *libgamemode = NULL; |
|
||||
|
|
||||
/* Try and load libgamemode */ |
|
||||
libgamemode = dlopen("libgamemode.so.0", RTLD_NOW); |
|
||||
if (!libgamemode) { |
|
||||
/* Attempt to load unversioned library for compatibility with older |
|
||||
* versions (as of writing, there are no ABI changes between the two - |
|
||||
* this may need to change if ever ABI-breaking changes are made) */ |
|
||||
libgamemode = dlopen("libgamemode.so", RTLD_NOW); |
|
||||
if (!libgamemode) { |
|
||||
snprintf(internal_gamemode_client_error_string, |
|
||||
sizeof(internal_gamemode_client_error_string), |
|
||||
"dlopen failed - %s", |
|
||||
dlerror()); |
|
||||
internal_libgamemode_loaded = -1; |
|
||||
return -1; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/* Attempt to bind all symbols */ |
|
||||
for (size_t i = 0; i < sizeof(bindings) / sizeof(bindings[0]); i++) { |
|
||||
struct binding *binder = &bindings[i]; |
|
||||
|
|
||||
if (internal_bind_libgamemode_symbol(libgamemode, |
|
||||
binder->name, |
|
||||
binder->functor, |
|
||||
binder->func_size, |
|
||||
binder->required)) { |
|
||||
internal_libgamemode_loaded = -1; |
|
||||
return -1; |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
/* Success */ |
|
||||
internal_libgamemode_loaded = 0; |
|
||||
return 0; |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Redirect to the real libgamemode |
|
||||
*/ |
|
||||
__attribute__((always_inline)) static inline const char *gamemode_error_string(void) |
|
||||
{ |
|
||||
/* If we fail to load the system gamemode, or we have an error string already, return our error |
|
||||
* string instead of diverting to the system version */ |
|
||||
if (internal_load_libgamemode() < 0 || internal_gamemode_client_error_string[0] != '\0') { |
|
||||
return internal_gamemode_client_error_string; |
|
||||
} |
|
||||
|
|
||||
/* Assert for static analyser that the function is not NULL */ |
|
||||
assert(REAL_internal_gamemode_error_string != NULL); |
|
||||
|
|
||||
return REAL_internal_gamemode_error_string(); |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* Redirect to the real libgamemode |
|
||||
* Allow automatically requesting game mode |
|
||||
* Also prints errors as they happen. |
|
||||
*/ |
|
||||
#ifdef GAMEMODE_AUTO |
|
||||
__attribute__((constructor)) |
|
||||
#else |
|
||||
__attribute__((always_inline)) static inline |
|
||||
#endif |
|
||||
int gamemode_request_start(void) |
|
||||
{ |
|
||||
/* Need to load gamemode */ |
|
||||
if (internal_load_libgamemode() < 0) { |
|
||||
#ifdef GAMEMODE_AUTO |
|
||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); |
|
||||
#endif |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
/* Assert for static analyser that the function is not NULL */ |
|
||||
assert(REAL_internal_gamemode_request_start != NULL); |
|
||||
|
|
||||
if (REAL_internal_gamemode_request_start() < 0) { |
|
||||
#ifdef GAMEMODE_AUTO |
|
||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); |
|
||||
#endif |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
return 0; |
|
||||
} |
|
||||
|
|
||||
/* Redirect to the real libgamemode */ |
|
||||
#ifdef GAMEMODE_AUTO |
|
||||
__attribute__((destructor)) |
|
||||
#else |
|
||||
__attribute__((always_inline)) static inline |
|
||||
#endif |
|
||||
int gamemode_request_end(void) |
|
||||
{ |
|
||||
/* Need to load gamemode */ |
|
||||
if (internal_load_libgamemode() < 0) { |
|
||||
#ifdef GAMEMODE_AUTO |
|
||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); |
|
||||
#endif |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
/* Assert for static analyser that the function is not NULL */ |
|
||||
assert(REAL_internal_gamemode_request_end != NULL); |
|
||||
|
|
||||
if (REAL_internal_gamemode_request_end() < 0) { |
|
||||
#ifdef GAMEMODE_AUTO |
|
||||
fprintf(stderr, "gamemodeauto: %s\n", gamemode_error_string()); |
|
||||
#endif |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
return 0; |
|
||||
} |
|
||||
|
|
||||
/* Redirect to the real libgamemode */ |
|
||||
__attribute__((always_inline)) static inline int gamemode_query_status(void) |
|
||||
{ |
|
||||
/* Need to load gamemode */ |
|
||||
if (internal_load_libgamemode() < 0) { |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
if (REAL_internal_gamemode_query_status == NULL) { |
|
||||
snprintf(internal_gamemode_client_error_string, |
|
||||
sizeof(internal_gamemode_client_error_string), |
|
||||
"gamemode_query_status missing (older host?)"); |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
return REAL_internal_gamemode_query_status(); |
|
||||
} |
|
||||
|
|
||||
/* Redirect to the real libgamemode */ |
|
||||
__attribute__((always_inline)) static inline int gamemode_request_start_for(pid_t pid) |
|
||||
{ |
|
||||
/* Need to load gamemode */ |
|
||||
if (internal_load_libgamemode() < 0) { |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
if (REAL_internal_gamemode_request_start_for == NULL) { |
|
||||
snprintf(internal_gamemode_client_error_string, |
|
||||
sizeof(internal_gamemode_client_error_string), |
|
||||
"gamemode_request_start_for missing (older host?)"); |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
return REAL_internal_gamemode_request_start_for(pid); |
|
||||
} |
|
||||
|
|
||||
/* Redirect to the real libgamemode */ |
|
||||
__attribute__((always_inline)) static inline int gamemode_request_end_for(pid_t pid) |
|
||||
{ |
|
||||
/* Need to load gamemode */ |
|
||||
if (internal_load_libgamemode() < 0) { |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
if (REAL_internal_gamemode_request_end_for == NULL) { |
|
||||
snprintf(internal_gamemode_client_error_string, |
|
||||
sizeof(internal_gamemode_client_error_string), |
|
||||
"gamemode_request_end_for missing (older host?)"); |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
return REAL_internal_gamemode_request_end_for(pid); |
|
||||
} |
|
||||
|
|
||||
/* Redirect to the real libgamemode */ |
|
||||
__attribute__((always_inline)) static inline int gamemode_query_status_for(pid_t pid) |
|
||||
{ |
|
||||
/* Need to load gamemode */ |
|
||||
if (internal_load_libgamemode() < 0) { |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
if (REAL_internal_gamemode_query_status_for == NULL) { |
|
||||
snprintf(internal_gamemode_client_error_string, |
|
||||
sizeof(internal_gamemode_client_error_string), |
|
||||
"gamemode_query_status_for missing (older host?)"); |
|
||||
return -1; |
|
||||
} |
|
||||
|
|
||||
return REAL_internal_gamemode_query_status_for(pid); |
|
||||
} |
|
||||
|
|
||||
#endif // CLIENT_GAMEMODE_H |
|
||||
@ -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
|
|
||||
@ -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 |
|
||||
@ -0,0 +1,52 @@ |
|||||
|
// 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 "qt_common/gamemode.h"
|
||||
|
#include "common/logging/log.h"
|
||||
|
#include "qt_common/config/uisettings.h"
|
||||
|
|
||||
|
namespace Common::FeralGamemode { |
||||
|
|
||||
|
/// @brief Start the gamemode client
|
||||
|
void Start() noexcept { |
||||
|
if (UISettings::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
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// @brief Stop the gmemode client
|
||||
|
void Stop() noexcept { |
||||
|
if (UISettings::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
|
||||
@ -0,0 +1,14 @@ |
|||||
|
// 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 { |
||||
|
|
||||
|
void Start() noexcept; |
||||
|
void Stop() noexcept; |
||||
|
|
||||
|
} // namespace Common::FeralGamemode |
||||
@ -1,75 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
|
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||
|
|
||||
#include "common/settings.h"
|
|
||||
#include "core/core.h"
|
|
||||
#include "ui_configure_linux_tab.h"
|
|
||||
#include "yuzu/configuration/configuration_shared.h"
|
|
||||
#include "yuzu/configuration/configure_linux_tab.h"
|
|
||||
#include "yuzu/configuration/shared_widget.h"
|
|
||||
|
|
||||
ConfigureLinuxTab::ConfigureLinuxTab(const Core::System& system_, |
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group_, |
|
||||
const ConfigurationShared::Builder& builder, QWidget* parent) |
|
||||
: Tab(group_, parent), ui(std::make_unique<Ui::ConfigureLinuxTab>()), system{system_} { |
|
||||
ui->setupUi(this); |
|
||||
|
|
||||
Setup(builder); |
|
||||
|
|
||||
SetConfiguration(); |
|
||||
} |
|
||||
|
|
||||
ConfigureLinuxTab::~ConfigureLinuxTab() = default; |
|
||||
|
|
||||
void ConfigureLinuxTab::SetConfiguration() {} |
|
||||
void ConfigureLinuxTab::Setup(const ConfigurationShared::Builder& builder) { |
|
||||
QLayout& linux_layout = *ui->linux_widget->layout(); |
|
||||
|
|
||||
std::map<u32, QWidget*> linux_hold{}; |
|
||||
|
|
||||
std::vector<Settings::BasicSetting*> settings; |
|
||||
const auto push = [&](Settings::Category category) { |
|
||||
for (const auto setting : Settings::values.linkage.by_category[category]) { |
|
||||
settings.push_back(setting); |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
push(Settings::Category::Linux); |
|
||||
|
|
||||
for (auto* setting : settings) { |
|
||||
auto* widget = builder.BuildWidget(setting, apply_funcs); |
|
||||
|
|
||||
if (widget == nullptr) { |
|
||||
continue; |
|
||||
} |
|
||||
if (!widget->Valid()) { |
|
||||
widget->deleteLater(); |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
linux_hold.insert({setting->Id(), widget}); |
|
||||
} |
|
||||
|
|
||||
for (const auto& [id, widget] : linux_hold) { |
|
||||
linux_layout.addWidget(widget); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void ConfigureLinuxTab::ApplyConfiguration() { |
|
||||
const bool is_powered_on = system.IsPoweredOn(); |
|
||||
for (const auto& apply_func : apply_funcs) { |
|
||||
apply_func(is_powered_on); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void ConfigureLinuxTab::changeEvent(QEvent* event) { |
|
||||
if (event->type() == QEvent::LanguageChange) { |
|
||||
RetranslateUI(); |
|
||||
} |
|
||||
|
|
||||
QWidget::changeEvent(event); |
|
||||
} |
|
||||
|
|
||||
void ConfigureLinuxTab::RetranslateUI() { |
|
||||
ui->retranslateUi(this); |
|
||||
} |
|
||||
@ -1,44 +0,0 @@ |
|||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project |
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later |
|
||||
|
|
||||
#pragma once |
|
||||
|
|
||||
#include <QWidget> |
|
||||
|
|
||||
namespace Core { |
|
||||
class System; |
|
||||
} |
|
||||
|
|
||||
namespace Ui { |
|
||||
class ConfigureLinuxTab; |
|
||||
} |
|
||||
|
|
||||
namespace ConfigurationShared { |
|
||||
class Builder; |
|
||||
} |
|
||||
|
|
||||
class ConfigureLinuxTab : public ConfigurationShared::Tab { |
|
||||
Q_OBJECT |
|
||||
|
|
||||
public: |
|
||||
explicit ConfigureLinuxTab(const Core::System& system_, |
|
||||
std::shared_ptr<std::vector<ConfigurationShared::Tab*>> group, |
|
||||
const ConfigurationShared::Builder& builder, |
|
||||
QWidget* parent = nullptr); |
|
||||
~ConfigureLinuxTab() override; |
|
||||
|
|
||||
void ApplyConfiguration() override; |
|
||||
void SetConfiguration() override; |
|
||||
|
|
||||
private: |
|
||||
void changeEvent(QEvent* event) override; |
|
||||
void RetranslateUI(); |
|
||||
|
|
||||
void Setup(const ConfigurationShared::Builder& builder); |
|
||||
|
|
||||
std::unique_ptr<Ui::ConfigureLinuxTab> ui; |
|
||||
|
|
||||
const Core::System& system; |
|
||||
|
|
||||
std::vector<std::function<void(bool)>> apply_funcs{}; |
|
||||
}; |
|
||||
@ -1,53 +0,0 @@ |
|||||
<?xml version="1.0" encoding="UTF-8"?> |
|
||||
<ui version="4.0"> |
|
||||
<class>ConfigureLinuxTab</class> |
|
||||
<widget class="QWidget" name="ConfigureLinuxTab"> |
|
||||
<property name="accessibleName"> |
|
||||
<string>Linux</string> |
|
||||
</property> |
|
||||
<layout class="QVBoxLayout"> |
|
||||
<item> |
|
||||
<widget class="QGroupBox" name="LinuxGroupBox"> |
|
||||
<property name="title"> |
|
||||
<string>Linux</string> |
|
||||
</property> |
|
||||
<layout class="QVBoxLayout" name="LinuxVerticalLayout_1"> |
|
||||
<item> |
|
||||
<widget class="QWidget" name="linux_widget" native="true"> |
|
||||
<layout class="QVBoxLayout" name="LinuxVerticalLayout_2"> |
|
||||
<property name="leftMargin"> |
|
||||
<number>0</number> |
|
||||
</property> |
|
||||
<property name="topMargin"> |
|
||||
<number>0</number> |
|
||||
</property> |
|
||||
<property name="rightMargin"> |
|
||||
<number>0</number> |
|
||||
</property> |
|
||||
<property name="bottomMargin"> |
|
||||
<number>0</number> |
|
||||
</property> |
|
||||
</layout> |
|
||||
</widget> |
|
||||
</item> |
|
||||
</layout> |
|
||||
</widget> |
|
||||
</item> |
|
||||
<item> |
|
||||
<spacer name="verticalSpacer"> |
|
||||
<property name="orientation"> |
|
||||
<enum>Qt::Vertical</enum> |
|
||||
</property> |
|
||||
<property name="sizeHint" stdset="0"> |
|
||||
<size> |
|
||||
<width>20</width> |
|
||||
<height>40</height> |
|
||||
</size> |
|
||||
</property> |
|
||||
</spacer> |
|
||||
</item> |
|
||||
</layout> |
|
||||
</widget> |
|
||||
<resources/> |
|
||||
<connections/> |
|
||||
</ui> |
|
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue