early-access version 3832

This commit is contained in:
pineappleEA 2023-08-24 22:11:26 +02:00
parent e0a13c3ca8
commit 979f3570e9
28 changed files with 212 additions and 42 deletions

View File

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 3831. This is the source code for early-access 3832.
## Legal Notice ## Legal Notice

View File

@ -11,6 +11,7 @@
#include "common/fs/path_util.h" #include "common/fs/path_util.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h"
#include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/acc/profile_manager.h"
#include "input_common/main.h" #include "input_common/main.h"
#include "jni/config.h" #include "jni/config.h"
@ -144,7 +145,9 @@ void Config::ReadValues() {
Service::Account::MAX_USERS - 1); Service::Account::MAX_USERS - 1);
// Disable docked mode by default on Android // Disable docked mode by default on Android
Settings::values.use_docked_mode = config->GetBoolean("System", "use_docked_mode", false); Settings::values.use_docked_mode.SetValue(config->GetBoolean("System", "use_docked_mode", false)
? Settings::ConsoleMode::Docked
: Settings::ConsoleMode::Handheld);
const auto rng_seed_enabled = config->GetBoolean("System", "rng_seed_enabled", false); const auto rng_seed_enabled = config->GetBoolean("System", "rng_seed_enabled", false);
if (rng_seed_enabled) { if (rng_seed_enabled) {

View File

@ -377,7 +377,7 @@ public:
return false; return false;
} }
return !Settings::values.use_docked_mode.GetValue(); return !Settings::IsDockedMode();
} }
void SetDeviceType([[maybe_unused]] int index, int type) { void SetDeviceType([[maybe_unused]] int index, int type) {

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include <version> #include <version>
#include "common/settings_enums.h"
#if __cpp_lib_chrono >= 201907L #if __cpp_lib_chrono >= 201907L
#include <chrono> #include <chrono>
#include <exception> #include <exception>
@ -149,6 +150,10 @@ bool IsFastmemEnabled() {
return true; return true;
} }
bool IsDockedMode() {
return values.use_docked_mode.GetValue() == Settings::ConsoleMode::Docked;
}
float Volume() { float Volume() {
if (values.audio_muted) { if (values.audio_muted) {
return 0.0f; return 0.0f;

View File

@ -380,7 +380,13 @@ struct Values {
Setting<s32> current_user{linkage, 0, "current_user", Category::System}; Setting<s32> current_user{linkage, 0, "current_user", Category::System};
SwitchableSetting<bool> use_docked_mode{linkage, true, "use_docked_mode", Category::System}; SwitchableSetting<ConsoleMode> use_docked_mode{linkage,
ConsoleMode::Docked,
"use_docked_mode",
Category::System,
Specialization::Radio,
true,
true};
// Controls // Controls
InputSetting<std::array<PlayerInput, 10>> players; InputSetting<std::array<PlayerInput, 10>> players;
@ -521,6 +527,8 @@ bool IsGPULevelHigh();
bool IsFastmemEnabled(); bool IsFastmemEnabled();
bool IsDockedMode();
float Volume(); float Volume();
std::string GetTimeZoneString(TimeZone time_zone); std::string GetTimeZoneString(TimeZone time_zone);

View File

@ -56,6 +56,7 @@ enum Specialization : u8 {
Scalar = 5, // Values are continuous Scalar = 5, // Values are continuous
Countable = 6, // Can be stepped through Countable = 6, // Can be stepped through
Paired = 7, // Another setting is associated with this setting Paired = 7, // Another setting is associated with this setting
Radio = 8, // Setting should be presented in a radio group
Percentage = (1 << SpecializationAttributeOffset), // Should be represented as a percentage Percentage = (1 << SpecializationAttributeOffset), // Should be represented as a percentage
}; };

View File

@ -146,6 +146,8 @@ ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum);
ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch);
ENUM(ConsoleMode, Handheld, Docked);
template <typename Type> template <typename Type>
inline std::string CanonicalizeEnum(Type id) { inline std::string CanonicalizeEnum(Type id) {
const auto group = EnumMetadata<Type>::Canonicalizations(); const auto group = EnumMetadata<Type>::Canonicalizations();

View File

@ -3,6 +3,8 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/frontend/applets/controller.h" #include "core/frontend/applets/controller.h"
#include "core/hid/emulated_controller.h" #include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h" #include "core/hid/hid_core.h"
@ -62,7 +64,7 @@ void DefaultControllerApplet::ReconfigureControllers(ReconfigureCallback callbac
controller->Connect(true); controller->Connect(true);
} }
} else if (index == 0 && parameters.enable_single_mode && parameters.allow_handheld && } else if (index == 0 && parameters.enable_single_mode && parameters.allow_handheld &&
!Settings::values.use_docked_mode.GetValue()) { !Settings::IsDockedMode()) {
// We should *never* reach here under any normal circumstances. // We should *never* reach here under any normal circumstances.
controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld); controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
controller->Connect(true); controller->Connect(true);

View File

@ -5,6 +5,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h"
#include "core/frontend/framebuffer_layout.h" #include "core/frontend/framebuffer_layout.h"
namespace Layout { namespace Layout {
@ -49,7 +50,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) {
} }
FramebufferLayout FrameLayoutFromResolutionScale(f32 res_scale) { FramebufferLayout FrameLayoutFromResolutionScale(f32 res_scale) {
const bool is_docked = Settings::values.use_docked_mode.GetValue(); const bool is_docked = Settings::IsDockedMode();
const u32 screen_width = is_docked ? ScreenDocked::Width : ScreenUndocked::Width; const u32 screen_width = is_docked ? ScreenDocked::Width : ScreenUndocked::Width;
const u32 screen_height = is_docked ? ScreenDocked::Height : ScreenUndocked::Height; const u32 screen_height = is_docked ? ScreenDocked::Height : ScreenUndocked::Height;

View File

@ -6,6 +6,7 @@
#include <cinttypes> #include <cinttypes>
#include <cstring> #include <cstring>
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h"
#include "core/core.h" #include "core/core.h"
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
@ -833,7 +834,7 @@ void ICommonStateGetter::GetDefaultDisplayResolution(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4}; IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
if (Settings::values.use_docked_mode.GetValue()) { if (Settings::IsDockedMode()) {
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth)); rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth));
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight)); rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight));
} else { } else {
@ -921,7 +922,7 @@ void IStorage::Open(HLERequestContext& ctx) {
} }
void ICommonStateGetter::GetOperationMode(HLERequestContext& ctx) { void ICommonStateGetter::GetOperationMode(HLERequestContext& ctx) {
const bool use_docked_mode{Settings::values.use_docked_mode.GetValue()}; const bool use_docked_mode{Settings::IsDockedMode()};
LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode); LOG_DEBUG(Service_AM, "called, use_docked_mode={}", use_docked_mode);
IPC::ResponseBuilder rb{ctx, 3}; IPC::ResponseBuilder rb{ctx, 3};

View File

@ -7,6 +7,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/hle/service/apm/apm_controller.h" #include "core/hle/service/apm/apm_controller.h"
@ -67,8 +68,7 @@ void Controller::SetFromCpuBoostMode(CpuBoostMode mode) {
} }
PerformanceMode Controller::GetCurrentPerformanceMode() const { PerformanceMode Controller::GetCurrentPerformanceMode() const {
return Settings::values.use_docked_mode.GetValue() ? PerformanceMode::Boost return Settings::IsDockedMode() ? PerformanceMode::Boost : PerformanceMode::Normal;
: PerformanceMode::Normal;
} }
PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) { PerformanceConfiguration Controller::GetCurrentPerformanceConfiguration(PerformanceMode mode) {

View File

@ -4,6 +4,7 @@
#include <utility> #include <utility>
#include "common/assert.h" #include "common/assert.h"
#include "common/fs/fs.h"
#include "common/fs/path_util.h" #include "common/fs/path_util.h"
#include "common/settings.h" #include "common/settings.h"
#include "core/core.h" #include "core/core.h"
@ -154,10 +155,18 @@ Result VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
std::string src_path(Common::FS::SanitizePath(src_path_)); std::string src_path(Common::FS::SanitizePath(src_path_));
std::string dest_path(Common::FS::SanitizePath(dest_path_)); std::string dest_path(Common::FS::SanitizePath(dest_path_));
auto src = backing->GetFileRelative(src_path); auto src = backing->GetFileRelative(src_path);
auto dst = backing->GetFileRelative(dest_path);
if (Common::FS::GetParentPath(src_path) == Common::FS::GetParentPath(dest_path)) { if (Common::FS::GetParentPath(src_path) == Common::FS::GetParentPath(dest_path)) {
// Use more-optimized vfs implementation rename. // Use more-optimized vfs implementation rename.
if (src == nullptr) if (src == nullptr) {
return FileSys::ERROR_PATH_NOT_FOUND; return FileSys::ERROR_PATH_NOT_FOUND;
}
if (dst && Common::FS::Exists(dst->GetFullPath())) {
LOG_ERROR(Service_FS, "File at new_path={} already exists", dst->GetFullPath());
return FileSys::ERROR_PATH_ALREADY_EXISTS;
}
if (!src->Rename(Common::FS::GetFilename(dest_path))) { if (!src->Rename(Common::FS::GetFilename(dest_path))) {
// TODO(DarkLordZach): Find a better error code for this // TODO(DarkLordZach): Find a better error code for this
return ResultUnknown; return ResultUnknown;

View File

@ -331,7 +331,7 @@ Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties()
}; };
// Hack: There is no touch in docked but games still allow it // Hack: There is no touch in docked but games still allow it
if (Settings::values.use_docked_mode.GetValue()) { if (Settings::IsDockedMode()) {
gesture.points[id] = { gesture.points[id] = {
.x = static_cast<s32>(active_x * Layout::ScreenDocked::Width), .x = static_cast<s32>(active_x * Layout::ScreenDocked::Width),
.y = static_cast<s32>(active_y * Layout::ScreenDocked::Height), .y = static_cast<s32>(active_y * Layout::ScreenDocked::Height),

View File

@ -1518,7 +1518,7 @@ bool Controller_NPad::IsControllerSupported(Core::HID::NpadStyleIndex controller
return false; return false;
} }
// Handheld shouldn't be supported in docked mode // Handheld shouldn't be supported in docked mode
if (Settings::values.use_docked_mode.GetValue()) { if (Settings::IsDockedMode()) {
return false; return false;
} }

View File

@ -217,7 +217,7 @@ private:
IPC::ResponseBuilder rb{ctx, 6}; IPC::ResponseBuilder rb{ctx, 6};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
if (Settings::values.use_docked_mode.GetValue()) { if (Settings::IsDockedMode()) {
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth)); rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth));
rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight)); rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight));
} else { } else {

View File

@ -14,6 +14,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h"
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
@ -275,7 +276,7 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader,
static_cast<u32>(Settings::values.shader_backend.GetValue())); static_cast<u32>(Settings::values.shader_backend.GetValue()));
AddField(field_type, "Renderer_UseAsynchronousShaders", AddField(field_type, "Renderer_UseAsynchronousShaders",
Settings::values.use_asynchronous_shaders.GetValue()); Settings::values.use_asynchronous_shaders.GetValue());
AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode.GetValue()); AddField(field_type, "System_UseDockedMode", Settings::IsDockedMode());
} }
bool TelemetrySession::SubmitTestcase() { bool TelemetrySession::SubmitTestcase() {

View File

@ -5,6 +5,8 @@
#include <thread> #include <thread>
#include "common/assert.h" #include "common/assert.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "common/string_util.h" #include "common/string_util.h"
#include "core/core.h" #include "core/core.h"
#include "core/hid/emulated_controller.h" #include "core/hid/emulated_controller.h"
@ -226,9 +228,11 @@ int QtControllerSelectorDialog::exec() {
} }
void QtControllerSelectorDialog::ApplyConfiguration() { void QtControllerSelectorDialog::ApplyConfiguration() {
const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue(); const bool pre_docked_mode = Settings::IsDockedMode();
Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked()); const bool docked_mode_selected = ui->radioDocked->isChecked();
OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue(), system); Settings::values.use_docked_mode.SetValue(
docked_mode_selected ? Settings::ConsoleMode::Docked : Settings::ConsoleMode::Handheld);
OnDockedModeChanged(pre_docked_mode, docked_mode_selected, system);
Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked()); Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked()); Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
@ -616,8 +620,8 @@ void QtControllerSelectorDialog::UpdateDockedState(bool is_handheld) {
ui->radioDocked->setEnabled(!is_handheld); ui->radioDocked->setEnabled(!is_handheld);
ui->radioUndocked->setEnabled(!is_handheld); ui->radioUndocked->setEnabled(!is_handheld);
ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue()); ui->radioDocked->setChecked(Settings::IsDockedMode());
ui->radioUndocked->setChecked(!Settings::values.use_docked_mode.GetValue()); ui->radioUndocked->setChecked(!Settings::IsDockedMode());
// Also force into undocked mode if the controller type is handheld. // Also force into undocked mode if the controller type is handheld.
if (is_handheld) { if (is_handheld) {

View File

@ -928,8 +928,8 @@ void GRenderWindow::CaptureScreenshot(const QString& screenshot_path) {
const Layout::FramebufferLayout layout{[]() { const Layout::FramebufferLayout layout{[]() {
u32 height = UISettings::values.screenshot_height.GetValue(); u32 height = UISettings::values.screenshot_height.GetValue();
if (height == 0) { if (height == 0) {
height = Settings::values.use_docked_mode.GetValue() ? Layout::ScreenDocked::Height height = Settings::IsDockedMode() ? Layout::ScreenDocked::Height
: Layout::ScreenUndocked::Height; : Layout::ScreenUndocked::Height;
height *= Settings::values.resolution_info.up_factor; height *= Settings::values.resolution_info.up_factor;
} }
const u32 width = const u32 width =

View File

@ -9,6 +9,7 @@
#include "common/fs/path_util.h" #include "common/fs/path_util.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_common.h" #include "common/settings_common.h"
#include "common/settings_enums.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/acc/profile_manager.h"
#include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/controllers/npad.h"
@ -85,9 +86,9 @@ const std::map<Settings::ScalingFilter, QString> Config::scaling_filter_texts_ma
{Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))}, {Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
}; };
const std::map<bool, QString> Config::use_docked_mode_texts_map = { const std::map<Settings::ConsoleMode, QString> Config::use_docked_mode_texts_map = {
{true, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))}, {Settings::ConsoleMode::Docked, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))},
{false, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))}, {Settings::ConsoleMode::Handheld, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))},
}; };
const std::map<Settings::GpuAccuracy, QString> Config::gpu_accuracy_texts_map = { const std::map<Settings::GpuAccuracy, QString> Config::gpu_accuracy_texts_map = {
@ -376,7 +377,7 @@ void Config::ReadControlValues() {
const auto controller_type = Settings::values.players.GetValue()[0].controller_type; const auto controller_type = Settings::values.players.GetValue()[0].controller_type;
if (controller_type == Settings::ControllerType::Handheld) { if (controller_type == Settings::ControllerType::Handheld) {
Settings::values.use_docked_mode.SetGlobal(!IsCustomConfig()); Settings::values.use_docked_mode.SetGlobal(!IsCustomConfig());
Settings::values.use_docked_mode.SetValue(false); Settings::values.use_docked_mode.SetValue(Settings::ConsoleMode::Handheld);
} }
if (IsCustomConfig()) { if (IsCustomConfig()) {

View File

@ -9,6 +9,7 @@
#include <QMetaType> #include <QMetaType>
#include <QVariant> #include <QVariant>
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h"
#include "yuzu/uisettings.h" #include "yuzu/uisettings.h"
class QSettings; class QSettings;
@ -51,7 +52,7 @@ public:
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map; static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map;
static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map; static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map;
static const std::map<bool, QString> use_docked_mode_texts_map; static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map;
static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map; static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map;
static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map; static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map;
static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map; static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map;

View File

@ -4,6 +4,8 @@
#include <memory> #include <memory>
#include <thread> #include <thread>
#include "common/settings.h"
#include "common/settings_enums.h"
#include "core/core.h" #include "core/core.h"
#include "core/hid/emulated_controller.h" #include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h" #include "core/hid/hid_core.h"
@ -197,9 +199,11 @@ void ConfigureInput::ApplyConfiguration() {
advanced->ApplyConfiguration(); advanced->ApplyConfiguration();
const bool pre_docked_mode = Settings::values.use_docked_mode.GetValue(); const bool pre_docked_mode = Settings::IsDockedMode();
Settings::values.use_docked_mode.SetValue(ui->radioDocked->isChecked()); const bool docked_mode_selected = ui->radioDocked->isChecked();
OnDockedModeChanged(pre_docked_mode, Settings::values.use_docked_mode.GetValue(), system); Settings::values.use_docked_mode.SetValue(
docked_mode_selected ? Settings::ConsoleMode::Docked : Settings::ConsoleMode::Handheld);
OnDockedModeChanged(pre_docked_mode, docked_mode_selected, system);
Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked()); Settings::values.vibration_enabled.SetValue(ui->vibrationGroup->isChecked());
Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked()); Settings::values.motion_enabled.SetValue(ui->motionGroup->isChecked());
@ -267,8 +271,8 @@ void ConfigureInput::UpdateDockedState(bool is_handheld) {
ui->radioDocked->setEnabled(!is_handheld); ui->radioDocked->setEnabled(!is_handheld);
ui->radioUndocked->setEnabled(!is_handheld); ui->radioUndocked->setEnabled(!is_handheld);
ui->radioDocked->setChecked(Settings::values.use_docked_mode.GetValue()); ui->radioDocked->setChecked(Settings::IsDockedMode());
ui->radioUndocked->setChecked(!Settings::values.use_docked_mode.GetValue()); ui->radioUndocked->setChecked(!Settings::IsDockedMode());
// Also force into undocked mode if the controller type is handheld. // Also force into undocked mode if the controller type is handheld.
if (is_handheld) { if (is_handheld) {

View File

@ -18,6 +18,7 @@
#include "common/fs/fs_util.h" #include "common/fs/fs_util.h"
#include "common/settings_enums.h" #include "common/settings_enums.h"
#include "common/settings_input.h"
#include "configuration/shared_widget.h" #include "configuration/shared_widget.h"
#include "core/core.h" #include "core/core.h"
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
@ -98,6 +99,12 @@ void ConfigurePerGame::ApplyConfiguration() {
addons_tab->ApplyConfiguration(); addons_tab->ApplyConfiguration();
input_tab->ApplyConfiguration(); input_tab->ApplyConfiguration();
if (Settings::IsDockedMode() && Settings::values.players.GetValue()[0].controller_type ==
Settings::ControllerType::Handheld) {
Settings::values.use_docked_mode.SetValue(Settings::ConsoleMode::Handheld);
Settings::values.use_docked_mode.SetGlobal(true);
}
system.ApplySettings(); system.ApplySettings();
Settings::LogSettings(); Settings::LogSettings();

View File

@ -106,6 +106,11 @@ void ConfigureSystem::Setup(const ConfigurationShared::Builder& builder) {
push(Settings::values.linkage.by_category[Settings::Category::System]); push(Settings::values.linkage.by_category[Settings::Category::System]);
for (auto setting : settings) { for (auto setting : settings) {
if (setting->Id() == Settings::values.use_docked_mode.Id() &&
Settings::IsConfiguringGlobal()) {
continue;
}
ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs); ConfigurationShared::Widget* widget = builder.BuildWidget(setting, apply_funcs);
if (widget == nullptr) { if (widget == nullptr) {

View File

@ -135,7 +135,7 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent) {
INSERT(Settings, region_index, "Region:", ""); INSERT(Settings, region_index, "Region:", "");
INSERT(Settings, time_zone_index, "Time Zone:", ""); INSERT(Settings, time_zone_index, "Time Zone:", "");
INSERT(Settings, sound_index, "Sound Output Mode:", ""); INSERT(Settings, sound_index, "Sound Output Mode:", "");
INSERT(Settings, use_docked_mode, "", ""); INSERT(Settings, use_docked_mode, "Console Mode:", "");
INSERT(Settings, current_user, "", ""); INSERT(Settings, current_user, "", "");
// Controls // Controls
@ -379,6 +379,9 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent) {
PAIR(MemoryLayout, Memory_6Gb, "6GB DRAM (Unsafe)"), PAIR(MemoryLayout, Memory_6Gb, "6GB DRAM (Unsafe)"),
PAIR(MemoryLayout, Memory_8Gb, "8GB DRAM (Unsafe)"), PAIR(MemoryLayout, Memory_8Gb, "8GB DRAM (Unsafe)"),
}}); }});
translations->insert(
{Settings::EnumMetadata<Settings::ConsoleMode>::Index(),
{PAIR(ConsoleMode, Docked, "Docked"), PAIR(ConsoleMode, Handheld, "Handheld")}});
#undef PAIR #undef PAIR
#undef CTX_PAIR #undef CTX_PAIR

View File

@ -23,6 +23,7 @@
#include <QLineEdit> #include <QLineEdit>
#include <QObject> #include <QObject>
#include <QPushButton> #include <QPushButton>
#include <QRadioButton>
#include <QRegularExpression> #include <QRegularExpression>
#include <QSizePolicy> #include <QSizePolicy>
#include <QSlider> #include <QSlider>
@ -171,6 +172,65 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer,
return combobox; return combobox;
} }
QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer,
std::function<void()>& restore_func,
const std::function<void()>& touch) {
const auto type = setting.EnumIndex();
QWidget* group = new QWidget(this);
QHBoxLayout* layout = new QHBoxLayout(group);
layout->setContentsMargins(0, 0, 0, 0);
group->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
const ComboboxTranslations* enumeration{nullptr};
if (combobox_enumerations.contains(type)) {
enumeration = &combobox_enumerations.at(type);
for (const auto& [id, name] : *enumeration) {
QRadioButton* radio_button = new QRadioButton(name, group);
layout->addWidget(radio_button);
radio_buttons.push_back({id, radio_button});
}
} else {
return group;
}
const auto get_selected = [=]() -> u32 {
for (const auto& [id, button] : radio_buttons) {
if (button->isChecked()) {
return id;
}
}
return -1;
};
const auto set_index = [=](u32 value) {
for (const auto& [id, button] : radio_buttons) {
button->setChecked(id == value);
}
};
const u32 setting_value = std::stoi(setting.ToString());
set_index(setting_value);
serializer = [get_selected]() {
int current = get_selected();
return std::to_string(current);
};
restore_func = [this, set_index]() {
const u32 global_value = std::stoi(RelevantDefault(setting));
set_index(global_value);
};
if (!Settings::IsConfiguringGlobal()) {
for (const auto& [id, button] : radio_buttons) {
QObject::connect(button, &QAbstractButton::clicked, [touch]() { touch(); });
}
}
return group;
}
QWidget* Widget::CreateLineEdit(std::function<std::string()>& serializer, QWidget* Widget::CreateLineEdit(std::function<std::string()>& serializer,
std::function<void()>& restore_func, std::function<void()>& restore_func,
const std::function<void()>& touch, bool managed) { const std::function<void()>& touch, bool managed) {
@ -410,6 +470,8 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu
return RequestType::Slider; return RequestType::Slider;
case Settings::Specialization::Countable: case Settings::Specialization::Countable:
return RequestType::SpinBox; return RequestType::SpinBox;
case Settings::Specialization::Radio:
return RequestType::RadioGroup;
default: default:
break; break;
} }
@ -438,7 +500,11 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu
if (setting.TypeId() == typeid(bool)) { if (setting.TypeId() == typeid(bool)) {
data_component = CreateCheckBox(&setting, label, serializer, restore_func, touch); data_component = CreateCheckBox(&setting, label, serializer, restore_func, touch);
} else if (setting.IsEnum()) { } else if (setting.IsEnum()) {
data_component = CreateCombobox(serializer, restore_func, touch); if (request == RequestType::RadioGroup) {
data_component = CreateRadioGroup(serializer, restore_func, touch);
} else {
data_component = CreateCombobox(serializer, restore_func, touch);
}
} else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) || } else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) ||
type == typeid(s64) || type == typeid(u8)) { type == typeid(s64) || type == typeid(u8)) {
switch (request) { switch (request) {

View File

@ -22,6 +22,7 @@ class QObject;
class QPushButton; class QPushButton;
class QSlider; class QSlider;
class QSpinBox; class QSpinBox;
class QRadioButton;
namespace Settings { namespace Settings {
class BasicSetting; class BasicSetting;
@ -38,6 +39,7 @@ enum class RequestType {
LineEdit, LineEdit,
HexEdit, HexEdit,
DateTimeEdit, DateTimeEdit,
RadioGroup,
MaxEnum, MaxEnum,
}; };
@ -91,6 +93,7 @@ public:
QSlider* slider{}; QSlider* slider{};
QComboBox* combobox{}; QComboBox* combobox{};
QDateTimeEdit* date_time_edit{}; QDateTimeEdit* date_time_edit{};
std::vector<std::pair<u32, QRadioButton*>> radio_buttons{};
private: private:
void SetupComponent(const QString& label, std::function<void()>& load_func, bool managed, void SetupComponent(const QString& label, std::function<void()>& load_func, bool managed,
@ -106,6 +109,9 @@ private:
QWidget* CreateCombobox(std::function<std::string()>& serializer, QWidget* CreateCombobox(std::function<std::string()>& serializer,
std::function<void()>& restore_func, std::function<void()>& restore_func,
const std::function<void()>& touch); const std::function<void()>& touch);
QWidget* CreateRadioGroup(std::function<std::string()>& serializer,
std::function<void()>& restore_func,
const std::function<void()>& touch);
QWidget* CreateLineEdit(std::function<std::string()>& serializer, QWidget* CreateLineEdit(std::function<std::string()>& serializer,
std::function<void()>& restore_func, const std::function<void()>& touch, std::function<void()>& restore_func, const std::function<void()>& touch,
bool managed = true); bool managed = true);

View File

@ -1158,9 +1158,9 @@ void GMainWindow::InitializeWidgets() {
[this](const QPoint& menu_location) { [this](const QPoint& menu_location) {
QMenu context_menu; QMenu context_menu;
for (auto const& docked_mode_pair : Config::use_docked_mode_texts_map) { for (auto const& pair : Config::use_docked_mode_texts_map) {
context_menu.addAction(docked_mode_pair.second, [this, docked_mode_pair] { context_menu.addAction(pair.second, [this, &pair] {
if (docked_mode_pair.first != Settings::values.use_docked_mode.GetValue()) { if (pair.first != Settings::values.use_docked_mode.GetValue()) {
OnToggleDockedMode(); OnToggleDockedMode();
} }
}); });
@ -1811,6 +1811,43 @@ bool GMainWindow::SelectAndSetCurrentUser(
return true; return true;
} }
void GMainWindow::ConfigureFilesystemProvider(const std::string& filepath) {
// Ensure all NCAs are registered before launching the game
const auto file = vfs->OpenFile(filepath, FileSys::Mode::Read);
if (!file) {
return;
}
auto loader = Loader::GetLoader(*system, file);
if (!loader) {
return;
}
const auto file_type = loader->GetFileType();
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
return;
}
u64 program_id = 0;
const auto res2 = loader->ReadProgramId(program_id);
if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
provider->AddEntry(FileSys::TitleType::Application,
FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()), program_id,
file);
} else if (res2 == Loader::ResultStatus::Success &&
(file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
const auto nsp = file_type == Loader::FileType::NSP
? std::make_shared<FileSys::NSP>(file)
: FileSys::XCI{file}.GetSecurePartitionNSP();
for (const auto& title : nsp->GetNCAs()) {
for (const auto& entry : title.second) {
provider->AddEntry(entry.first.first, entry.first.second, title.first,
entry.second->GetBaseFile());
}
}
}
}
void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index, void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
StartGameType type) { StartGameType type) {
LOG_INFO(Frontend, "yuzu starting..."); LOG_INFO(Frontend, "yuzu starting...");
@ -1825,6 +1862,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
last_filename_booted = filename; last_filename_booted = filename;
ConfigureFilesystemProvider(filename.toStdString());
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
const auto loader = Loader::GetLoader(*system, v_file, program_id, program_index); const auto loader = Loader::GetLoader(*system, v_file, program_id, program_index);
@ -3636,7 +3674,7 @@ void GMainWindow::OnTasReset() {
} }
void GMainWindow::OnToggleDockedMode() { void GMainWindow::OnToggleDockedMode() {
const bool is_docked = Settings::values.use_docked_mode.GetValue(); const bool is_docked = Settings::IsDockedMode();
auto* player_1 = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); auto* player_1 = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
auto* handheld = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld); auto* handheld = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
@ -3650,7 +3688,8 @@ void GMainWindow::OnToggleDockedMode() {
controller_dialog->refreshConfiguration(); controller_dialog->refreshConfiguration();
} }
Settings::values.use_docked_mode.SetValue(!is_docked); Settings::values.use_docked_mode.SetValue(is_docked ? Settings::ConsoleMode::Handheld
: Settings::ConsoleMode::Docked);
UpdateDockedButton(); UpdateDockedButton();
OnDockedModeChanged(is_docked, !is_docked, *system); OnDockedModeChanged(is_docked, !is_docked, *system);
} }
@ -4080,10 +4119,10 @@ void GMainWindow::UpdateGPUAccuracyButton() {
} }
void GMainWindow::UpdateDockedButton() { void GMainWindow::UpdateDockedButton() {
const bool is_docked = Settings::values.use_docked_mode.GetValue(); const auto console_mode = Settings::values.use_docked_mode.GetValue();
dock_status_button->setChecked(is_docked); dock_status_button->setChecked(Settings::IsDockedMode());
dock_status_button->setText( dock_status_button->setText(
Config::use_docked_mode_texts_map.find(is_docked)->second.toUpper()); Config::use_docked_mode_texts_map.find(console_mode)->second.toUpper());
} }
void GMainWindow::UpdateAPIText() { void GMainWindow::UpdateAPIText() {

View File

@ -399,6 +399,7 @@ private:
void OpenPerGameConfiguration(u64 title_id, const std::string& file_name); void OpenPerGameConfiguration(u64 title_id, const std::string& file_name);
bool CheckDarkMode(); bool CheckDarkMode();
bool CheckSystemArchiveDecryption(); bool CheckSystemArchiveDecryption();
void ConfigureFilesystemProvider(const std::string& filepath);
QString GetTasStateDescription() const; QString GetTasStateDescription() const;
bool CreateShortcut(const std::string& shortcut_path, const std::string& title, bool CreateShortcut(const std::string& shortcut_path, const std::string& title,