mirror of
https://github.com/Lime3DS/Lime3DS
synced 2024-12-26 09:02:44 -06:00
Add per game configuration options (#6187)
* common: Move settings to common from core. - Removes a dependency on core and input_common from common. * code: Wrap settings values * Port from yuzu to allow per game settings * citra_qt: Initial per-game settings dialog * citra_qt: Use new API for read/save of config values * citra_qt: Per game audio settings * citra_qt: Per game graphics settings * citra_qt: Per game system settings * citra_qt: Per game general settings * citra_qt: Document and run clang format * citra_qt: Make icon smaller and centered * citra_qt: Remove version number * Not sure how to extract that, can always add it back later * citra_qt: Wrap UISettings * citra_qt: Fix unthottled fps setting * citra_qt: Remove margin in emulation tab * citra_qt: Implement some suggestions * Bring back speed switch hotkey * Allow configuration when game is running * Rename/adjust UI stuff * citra_qt: Fix build with separate windows * citra_qt: Address feedback * citra_qt: Log per-game settings before launching games * citra_qt: Add shader cache options * Also fix android build * citra_qt: Add DLC menu option * citra_qt: Run clang-format * citra_qt: Adjust for time offset * citra_qt: Implement suggestions * Run clang-format Co-authored-by: bunnei <bunneidev@gmail.com>
This commit is contained in:
parent
f261daf2fa
commit
48ee112ceb
92 changed files with 3171 additions and 1546 deletions
|
@ -8,7 +8,7 @@ import org.citra.citra_emu.CitraApplication;
|
||||||
public class EmulationMenuSettings {
|
public class EmulationMenuSettings {
|
||||||
private static SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(CitraApplication.getAppContext());
|
private static SharedPreferences mPreferences = PreferenceManager.getDefaultSharedPreferences(CitraApplication.getAppContext());
|
||||||
|
|
||||||
// These must match what is defined in src/core/settings.h
|
// These must match what is defined in src/common/settings.h
|
||||||
public static final int LayoutOption_Default = 0;
|
public static final int LayoutOption_Default = 0;
|
||||||
public static final int LayoutOption_SingleScreen = 1;
|
public static final int LayoutOption_SingleScreen = 1;
|
||||||
public static final int LayoutOption_LargeScreen = 2;
|
public static final int LayoutOption_LargeScreen = 2;
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/udp/client.h"
|
#include "input_common/udp/client.h"
|
||||||
#include "jni/camera/ndk_camera.h"
|
#include "jni/camera/ndk_camera.h"
|
||||||
|
@ -139,9 +139,9 @@ void Config::ReadValues() {
|
||||||
Settings::values.factor_3d =
|
Settings::values.factor_3d =
|
||||||
static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0));
|
static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0));
|
||||||
std::string default_shader = "none (builtin)";
|
std::string default_shader = "none (builtin)";
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::Anaglyph)
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph)
|
||||||
default_shader = "dubois (builtin)";
|
default_shader = "dubois (builtin)";
|
||||||
else if (Settings::values.render_3d == Settings::StereoRenderOption::Interlaced)
|
else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced)
|
||||||
default_shader = "horizontal (builtin)";
|
default_shader = "horizontal (builtin)";
|
||||||
Settings::values.pp_shader_name =
|
Settings::values.pp_shader_name =
|
||||||
sdl2_config->GetString("Renderer", "pp_shader_name", default_shader);
|
sdl2_config->GetString("Renderer", "pp_shader_name", default_shader);
|
||||||
|
@ -186,9 +186,9 @@ void Config::ReadValues() {
|
||||||
sdl2_config->GetBoolean("Utility", "preload_textures", false);
|
sdl2_config->GetBoolean("Utility", "preload_textures", false);
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
Settings::values.enable_dsp_lle = sdl2_config->GetBoolean("Audio", "enable_dsp_lle", false);
|
Settings::values.audio_emulation =
|
||||||
Settings::values.enable_dsp_lle_multithread =
|
static_cast<Settings::AudioEmulation>(sdl2_config->GetInteger(
|
||||||
sdl2_config->GetBoolean("Audio", "enable_dsp_lle_multithread", false);
|
"Audio", "audio_emulation", static_cast<int>(Settings::AudioEmulation::HLE)));
|
||||||
Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto");
|
Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto");
|
||||||
Settings::values.enable_audio_stretching =
|
Settings::values.enable_audio_stretching =
|
||||||
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
|
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "jni/emu_window/emu_window.h"
|
#include "jni/emu_window/emu_window.h"
|
||||||
#include "jni/id_cache.h"
|
#include "jni/id_cache.h"
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
namespace GameSettings {
|
namespace GameSettings {
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "common/logging/backend.h"
|
#include "common/logging/backend.h"
|
||||||
#include "common/logging/filter.h"
|
#include "common/logging/filter.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
#include "jni/applets/mii_selector.h"
|
#include "jni/applets/mii_selector.h"
|
||||||
#include "jni/applets/swkbd.h"
|
#include "jni/applets/swkbd.h"
|
||||||
#include "jni/camera/still_image_camera.h"
|
#include "jni/camera/still_image_camera.h"
|
||||||
|
@ -156,7 +156,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
|
|
||||||
// Initialize Logger
|
// Initialize Logger
|
||||||
Log::Filter log_filter;
|
Log::Filter log_filter;
|
||||||
log_filter.ParseFilterString(Settings::values.log_filter);
|
log_filter.ParseFilterString(Settings::values.log_filter.GetValue());
|
||||||
Log::SetGlobalFilter(log_filter);
|
Log::SetGlobalFilter(log_filter);
|
||||||
Log::AddBackend(std::make_unique<Log::LogcatBackend>());
|
Log::AddBackend(std::make_unique<Log::LogcatBackend>());
|
||||||
FileUtil::CreateFullPath(FileUtil::GetUserPath(FileUtil::UserPath::LogDir));
|
FileUtil::CreateFullPath(FileUtil::GetUserPath(FileUtil::UserPath::LogDir));
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/applets/default_applets.h"
|
#include "core/frontend/applets/default_applets.h"
|
||||||
|
@ -26,7 +27,6 @@
|
||||||
#include "core/hle/service/am/am.h"
|
#include "core/hle/service/am/am.h"
|
||||||
#include "core/hle/service/nfc/nfc.h"
|
#include "core/hle/service/nfc/nfc.h"
|
||||||
#include "core/savestate.h"
|
#include "core/savestate.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "jni/android_common/android_common.h"
|
#include "jni/android_common/android_common.h"
|
||||||
#include "jni/applets/mii_selector.h"
|
#include "jni/applets/mii_selector.h"
|
||||||
#include "jni/applets/swkbd.h"
|
#include "jni/applets/swkbd.h"
|
||||||
|
@ -238,7 +238,7 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Ensure no audio bleeds out while game is paused
|
// Ensure no audio bleeds out while game is paused
|
||||||
const float volume = Settings::values.volume;
|
const float volume = Settings::values.volume.GetValue();
|
||||||
SCOPE_EXIT({ Settings::values.volume = volume; });
|
SCOPE_EXIT({ Settings::values.volume = volume; });
|
||||||
Settings::values.volume = 0;
|
Settings::values.volume = 0;
|
||||||
|
|
||||||
|
|
|
@ -7,17 +7,18 @@
|
||||||
#include "audio_core/sink.h"
|
#include "audio_core/sink.h"
|
||||||
#include "audio_core/sink_details.h"
|
#include "audio_core/sink_details.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/dumping/backend.h"
|
#include "core/dumping/backend.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
namespace AudioCore {
|
namespace AudioCore {
|
||||||
|
|
||||||
DspInterface::DspInterface() = default;
|
DspInterface::DspInterface() = default;
|
||||||
DspInterface::~DspInterface() = default;
|
DspInterface::~DspInterface() = default;
|
||||||
|
|
||||||
void DspInterface::SetSink(const std::string& sink_id, const std::string& audio_device) {
|
void DspInterface::SetSink(std::string_view sink_id, std::string_view audio_device) {
|
||||||
sink = CreateSinkFromID(Settings::values.sink_id, Settings::values.audio_device_id);
|
sink = CreateSinkFromID(Settings::values.sink_id.GetValue(),
|
||||||
|
Settings::values.audio_device_id.GetValue());
|
||||||
sink->SetCallback(
|
sink->SetCallback(
|
||||||
[this](s16* buffer, std::size_t num_frames) { OutputCallback(buffer, num_frames); });
|
[this](s16* buffer, std::size_t num_frames) { OutputCallback(buffer, num_frames); });
|
||||||
time_stretcher.SetOutputSampleRate(sink->GetNativeSampleRate());
|
time_stretcher.SetOutputSampleRate(sink->GetNativeSampleRate());
|
||||||
|
|
|
@ -94,7 +94,7 @@ public:
|
||||||
virtual void UnloadComponent() = 0;
|
virtual void UnloadComponent() = 0;
|
||||||
|
|
||||||
/// Select the sink to use based on sink id.
|
/// Select the sink to use based on sink id.
|
||||||
void SetSink(const std::string& sink_id, const std::string& audio_device);
|
void SetSink(std::string_view sink_id, std::string_view audio_device);
|
||||||
/// Get the current sink
|
/// Get the current sink
|
||||||
Sink& GetSink();
|
Sink& GetSink();
|
||||||
/// Enable/Disable audio stretching.
|
/// Enable/Disable audio stretching.
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/dumping/backend.h"
|
#include "core/dumping/backend.h"
|
||||||
|
@ -34,7 +35,6 @@
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
|
@ -174,7 +174,7 @@ static void OnStatusMessageReceived(const Network::StatusMessageEntry& msg) {
|
||||||
|
|
||||||
static void InitializeLogging() {
|
static void InitializeLogging() {
|
||||||
Log::Filter log_filter(Log::Level::Debug);
|
Log::Filter log_filter(Log::Level::Debug);
|
||||||
log_filter.ParseFilterString(Settings::values.log_filter);
|
log_filter.ParseFilterString(Settings::values.log_filter.GetValue());
|
||||||
Log::SetGlobalFilter(log_filter);
|
Log::SetGlobalFilter(log_filter);
|
||||||
|
|
||||||
Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
|
Log::AddBackend(std::make_unique<Log::ColorConsoleBackend>());
|
||||||
|
@ -192,8 +192,8 @@ int main(int argc, char** argv) {
|
||||||
Common::DetachedTasks detached_tasks;
|
Common::DetachedTasks detached_tasks;
|
||||||
Config config;
|
Config config;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
bool use_gdbstub = Settings::values.use_gdbstub;
|
bool use_gdbstub = Settings::values.use_gdbstub.GetValue();
|
||||||
u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port);
|
u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port.GetValue());
|
||||||
std::string movie_record;
|
std::string movie_record;
|
||||||
std::string movie_record_author;
|
std::string movie_record_author;
|
||||||
std::string movie_play;
|
std::string movie_play;
|
||||||
|
@ -363,7 +363,7 @@ int main(int argc, char** argv) {
|
||||||
EmuWindow_SDL2::InitializeSDL2();
|
EmuWindow_SDL2::InitializeSDL2();
|
||||||
|
|
||||||
const auto emu_window{std::make_unique<EmuWindow_SDL2>(fullscreen, false)};
|
const auto emu_window{std::make_unique<EmuWindow_SDL2>(fullscreen, false)};
|
||||||
const bool use_secondary_window{Settings::values.layout_option ==
|
const bool use_secondary_window{Settings::values.layout_option.GetValue() ==
|
||||||
Settings::LayoutOption::SeparateWindows};
|
Settings::LayoutOption::SeparateWindows};
|
||||||
const auto secondary_window =
|
const auto secondary_window =
|
||||||
use_secondary_window ? std::make_unique<EmuWindow_SDL2>(false, true) : nullptr;
|
use_secondary_window ? std::make_unique<EmuWindow_SDL2>(false, true) : nullptr;
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/frontend/mic.h"
|
#include "core/frontend/mic.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/udp/client.h"
|
#include "input_common/udp/client.h"
|
||||||
#include "network/network_settings.h"
|
#include "network/network_settings.h"
|
||||||
|
@ -128,10 +128,6 @@ void Config::ReadValues() {
|
||||||
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", true);
|
sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", true);
|
||||||
Settings::values.frame_limit =
|
Settings::values.frame_limit =
|
||||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100));
|
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100));
|
||||||
Settings::values.use_frame_limit_alternate =
|
|
||||||
sdl2_config->GetBoolean("Renderer", "use_frame_limit_alternate", false);
|
|
||||||
Settings::values.frame_limit_alternate =
|
|
||||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit_alternate", 200));
|
|
||||||
Settings::values.use_vsync_new =
|
Settings::values.use_vsync_new =
|
||||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync_new", 1));
|
static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync_new", 1));
|
||||||
Settings::values.texture_filter_name =
|
Settings::values.texture_filter_name =
|
||||||
|
@ -144,10 +140,11 @@ void Config::ReadValues() {
|
||||||
Settings::values.factor_3d =
|
Settings::values.factor_3d =
|
||||||
static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0));
|
static_cast<u8>(sdl2_config->GetInteger("Renderer", "factor_3d", 0));
|
||||||
std::string default_shader = "none (builtin)";
|
std::string default_shader = "none (builtin)";
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::Anaglyph)
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph)
|
||||||
default_shader = "dubois (builtin)";
|
default_shader = "dubois (builtin)";
|
||||||
else if (Settings::values.render_3d == Settings::StereoRenderOption::Interlaced ||
|
else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced ||
|
||||||
Settings::values.render_3d == Settings::StereoRenderOption::ReverseInterlaced)
|
Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::ReverseInterlaced)
|
||||||
default_shader = "horizontal (builtin)";
|
default_shader = "horizontal (builtin)";
|
||||||
Settings::values.pp_shader_name =
|
Settings::values.pp_shader_name =
|
||||||
sdl2_config->GetString("Renderer", "pp_shader_name", default_shader);
|
sdl2_config->GetString("Renderer", "pp_shader_name", default_shader);
|
||||||
|
@ -188,9 +185,8 @@ void Config::ReadValues() {
|
||||||
sdl2_config->GetBoolean("Utility", "preload_textures", false);
|
sdl2_config->GetBoolean("Utility", "preload_textures", false);
|
||||||
|
|
||||||
// Audio
|
// Audio
|
||||||
Settings::values.enable_dsp_lle = sdl2_config->GetBoolean("Audio", "enable_dsp_lle", false);
|
Settings::values.audio_emulation = static_cast<Settings::AudioEmulation>(
|
||||||
Settings::values.enable_dsp_lle_multithread =
|
sdl2_config->GetInteger("Audio", "audio_emulation", 0));
|
||||||
sdl2_config->GetBoolean("Audio", "enable_dsp_lle_multithread", false);
|
|
||||||
Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto");
|
Settings::values.sink_id = sdl2_config->GetString("Audio", "output_engine", "auto");
|
||||||
Settings::values.enable_audio_stretching =
|
Settings::values.enable_audio_stretching =
|
||||||
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
|
sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true);
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
#include "citra/emu_window/emu_window_sdl2.h"
|
#include "citra/emu_window/emu_window_sdl2.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/3ds.h"
|
#include "core/3ds.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "input_common/keyboard.h"
|
#include "input_common/keyboard.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/motion_emu.h"
|
#include "input_common/motion_emu.h"
|
||||||
|
|
|
@ -38,6 +38,8 @@ add_executable(citra-qt
|
||||||
configuration/config.cpp
|
configuration/config.cpp
|
||||||
configuration/config.h
|
configuration/config.h
|
||||||
configuration/configure.ui
|
configuration/configure.ui
|
||||||
|
configuration/configuration_shared.cpp
|
||||||
|
configuration/configuration_shared.h
|
||||||
configuration/configure_audio.cpp
|
configuration/configure_audio.cpp
|
||||||
configuration/configure_audio.h
|
configuration/configure_audio.h
|
||||||
configuration/configure_audio.ui
|
configuration/configure_audio.ui
|
||||||
|
@ -67,6 +69,9 @@ add_executable(citra-qt
|
||||||
configuration/configure_motion_touch.cpp
|
configuration/configure_motion_touch.cpp
|
||||||
configuration/configure_motion_touch.h
|
configuration/configure_motion_touch.h
|
||||||
configuration/configure_motion_touch.ui
|
configuration/configure_motion_touch.ui
|
||||||
|
configuration/configure_per_game.cpp
|
||||||
|
configuration/configure_per_game.h
|
||||||
|
configuration/configure_per_game.ui
|
||||||
configuration/configure_storage.cpp
|
configuration/configure_storage.cpp
|
||||||
configuration/configure_storage.h
|
configuration/configure_storage.h
|
||||||
configuration/configure_storage.ui
|
configuration/configure_storage.ui
|
||||||
|
|
|
@ -15,11 +15,11 @@
|
||||||
#include "citra_qt/main.h"
|
#include "citra_qt/main.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/3ds.h"
|
#include "core/3ds.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/scope_acquire_context.h"
|
#include "core/frontend/scope_acquire_context.h"
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "input_common/keyboard.h"
|
#include "input_common/keyboard.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/motion_emu.h"
|
#include "input_common/motion_emu.h"
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -8,13 +8,16 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
class QSettings;
|
class QSettings;
|
||||||
|
|
||||||
class Config {
|
class Config {
|
||||||
public:
|
public:
|
||||||
Config();
|
enum class ConfigType : u32 { GlobalConfig, PerGameConfig };
|
||||||
|
|
||||||
|
explicit Config(const std::string& config_name = "qt-config",
|
||||||
|
ConfigType config_type = ConfigType::GlobalConfig);
|
||||||
~Config();
|
~Config();
|
||||||
|
|
||||||
void Reload();
|
void Reload();
|
||||||
|
@ -24,6 +27,8 @@ public:
|
||||||
static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Initialize(const std::string& config_name);
|
||||||
|
|
||||||
void ReadValues();
|
void ReadValues();
|
||||||
void ReadAudioValues();
|
void ReadAudioValues();
|
||||||
void ReadCameraValues();
|
void ReadCameraValues();
|
||||||
|
@ -68,11 +73,78 @@ private:
|
||||||
void SaveWebServiceValues();
|
void SaveWebServiceValues();
|
||||||
void SaveVideoDumpingValues();
|
void SaveVideoDumpingValues();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a setting from the qt_config.
|
||||||
|
*
|
||||||
|
* @param name The setting's identifier
|
||||||
|
* @param default_value The value to use when the setting is not already present in the config
|
||||||
|
*/
|
||||||
QVariant ReadSetting(const QString& name) const;
|
QVariant ReadSetting(const QString& name) const;
|
||||||
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
|
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only reads a setting from the qt_config if the current config is a global config, or if the
|
||||||
|
* current config is a custom config and the setting is overriding the global setting. Otherwise
|
||||||
|
* it does nothing.
|
||||||
|
*
|
||||||
|
* @param setting The variable to be modified
|
||||||
|
* @param name The setting's identifier
|
||||||
|
* @param default_value The value to use when the setting is not already present in the config
|
||||||
|
*/
|
||||||
|
template <typename Type>
|
||||||
|
void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a setting to the qt_config.
|
||||||
|
*
|
||||||
|
* @param name The setting's idetentifier
|
||||||
|
* @param value Value of the setting
|
||||||
|
* @param default_value Default of the setting if not present in qt_config
|
||||||
|
* @param use_global Specifies if the custom or global config should be in use, for custom
|
||||||
|
* configs
|
||||||
|
*/
|
||||||
void WriteSetting(const QString& name, const QVariant& value);
|
void WriteSetting(const QString& name, const QVariant& value);
|
||||||
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
|
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
|
||||||
|
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
|
||||||
|
bool use_global);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a value from the qt_config and applies it to the setting, using its label and default
|
||||||
|
* value. If the config is a custom config, this will also read the global state of the setting
|
||||||
|
* and apply that information to it.
|
||||||
|
*
|
||||||
|
* @param The setting
|
||||||
|
*/
|
||||||
|
template <typename Type, bool ranged>
|
||||||
|
void ReadGlobalSetting(Settings::SwitchableSetting<Type, ranged>& setting);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a value to the qt_config using the setting's label and default value. If the config is a
|
||||||
|
* custom config, it will apply the global state, and the custom value if needed.
|
||||||
|
*
|
||||||
|
* @param The setting
|
||||||
|
*/
|
||||||
|
template <typename Type, bool ranged>
|
||||||
|
void WriteGlobalSetting(const Settings::SwitchableSetting<Type, ranged>& setting);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads a value from the qt_config using the setting's label and default value and applies the
|
||||||
|
* value to the setting.
|
||||||
|
*
|
||||||
|
* @param The setting
|
||||||
|
*/
|
||||||
|
template <typename Type, bool ranged>
|
||||||
|
void ReadBasicSetting(Settings::Setting<Type, ranged>& setting);
|
||||||
|
|
||||||
|
/** Sets a value from the setting in the qt_config using the setting's label and default value.
|
||||||
|
*
|
||||||
|
* @param The setting
|
||||||
|
*/
|
||||||
|
template <typename Type, bool ranged>
|
||||||
|
void WriteBasicSetting(const Settings::Setting<Type, ranged>& setting);
|
||||||
|
|
||||||
|
ConfigType type;
|
||||||
std::unique_ptr<QSettings> qt_config;
|
std::unique_ptr<QSettings> qt_config;
|
||||||
std::string qt_config_loc;
|
std::string qt_config_loc;
|
||||||
|
bool global;
|
||||||
};
|
};
|
||||||
|
|
95
src/citra_qt/configuration/configuration_shared.cpp
Normal file
95
src/citra_qt/configuration/configuration_shared.cpp
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include "citra_qt/configuration/configuration_shared.h"
|
||||||
|
#include "citra_qt/configuration/configure_per_game.h"
|
||||||
|
#include "common/settings.h"
|
||||||
|
|
||||||
|
void ConfigurationShared::ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting,
|
||||||
|
const QCheckBox* checkbox,
|
||||||
|
const CheckState& tracker) {
|
||||||
|
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
|
||||||
|
setting->SetValue(checkbox->checkState());
|
||||||
|
} else if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
if (tracker == CheckState::Global) {
|
||||||
|
setting->SetGlobal(true);
|
||||||
|
} else {
|
||||||
|
setting->SetGlobal(false);
|
||||||
|
setting->SetValue(checkbox->checkState());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox,
|
||||||
|
const Settings::SwitchableSetting<bool>* setting) {
|
||||||
|
if (setting->UsingGlobal()) {
|
||||||
|
checkbox->setCheckState(Qt::PartiallyChecked);
|
||||||
|
} else {
|
||||||
|
checkbox->setCheckState(setting->GetValue() ? Qt::Checked : Qt::Unchecked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationShared::SetHighlight(QWidget* widget, bool highlighted) {
|
||||||
|
if (highlighted) {
|
||||||
|
widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,203,255,0.5) }")
|
||||||
|
.arg(widget->objectName()));
|
||||||
|
} else {
|
||||||
|
widget->setStyleSheet(QStringLiteral("QWidget#%1 { background-color:rgba(0,0,0,0) }")
|
||||||
|
.arg(widget->objectName()));
|
||||||
|
}
|
||||||
|
widget->show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox,
|
||||||
|
const Settings::SwitchableSetting<bool>& setting,
|
||||||
|
CheckState& tracker) {
|
||||||
|
if (setting.UsingGlobal()) {
|
||||||
|
tracker = CheckState::Global;
|
||||||
|
} else {
|
||||||
|
tracker = (setting.GetValue() == setting.GetValue(true)) ? CheckState::On : CheckState::Off;
|
||||||
|
}
|
||||||
|
SetHighlight(checkbox, tracker != CheckState::Global);
|
||||||
|
QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, setting, &tracker] {
|
||||||
|
tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
|
||||||
|
static_cast<int>(CheckState::Count));
|
||||||
|
if (tracker == CheckState::Global) {
|
||||||
|
checkbox->setChecked(setting.GetValue(true));
|
||||||
|
}
|
||||||
|
SetHighlight(checkbox, tracker != CheckState::Global);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationShared::SetColoredTristate(QCheckBox* checkbox, bool global, bool state,
|
||||||
|
bool global_state, CheckState& tracker) {
|
||||||
|
if (global) {
|
||||||
|
tracker = CheckState::Global;
|
||||||
|
} else {
|
||||||
|
tracker = (state == global_state) ? CheckState::On : CheckState::Off;
|
||||||
|
}
|
||||||
|
SetHighlight(checkbox, tracker != CheckState::Global);
|
||||||
|
QObject::connect(checkbox, &QCheckBox::clicked, checkbox, [checkbox, global_state, &tracker] {
|
||||||
|
tracker = static_cast<CheckState>((static_cast<int>(tracker) + 1) %
|
||||||
|
static_cast<int>(CheckState::Count));
|
||||||
|
if (tracker == CheckState::Global) {
|
||||||
|
checkbox->setChecked(global_state);
|
||||||
|
}
|
||||||
|
SetHighlight(checkbox, tracker != CheckState::Global);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationShared::SetColoredComboBox(QComboBox* combobox, QWidget* target, int global) {
|
||||||
|
InsertGlobalItem(combobox, global);
|
||||||
|
QObject::connect(combobox, qOverload<int>(&QComboBox::activated), target,
|
||||||
|
[target](int index) { SetHighlight(target, index != 0); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationShared::InsertGlobalItem(QComboBox* combobox, int global_index) {
|
||||||
|
const QString use_global_text =
|
||||||
|
ConfigurePerGame::tr("Use global configuration (%1)").arg(combobox->itemText(global_index));
|
||||||
|
combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text);
|
||||||
|
combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX);
|
||||||
|
}
|
98
src/citra_qt/configuration/configuration_shared.h
Normal file
98
src/citra_qt/configuration/configuration_shared.h
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
#include "common/settings.h"
|
||||||
|
|
||||||
|
namespace ConfigurationShared {
|
||||||
|
|
||||||
|
constexpr int USE_GLOBAL_INDEX =
|
||||||
|
0; ///< The index of the "Use global configuration" option in checkboxes
|
||||||
|
constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1;
|
||||||
|
constexpr int USE_GLOBAL_OFFSET = 2;
|
||||||
|
|
||||||
|
/// CheckBoxes require a tracker for their state since we emulate a tristate CheckBox
|
||||||
|
enum class CheckState {
|
||||||
|
Off, ///< Checkbox overrides to off/false
|
||||||
|
On, ///< Checkbox overrides to on/true
|
||||||
|
Global, ///< Checkbox defers to the global state
|
||||||
|
Count, ///< Simply the number of states, not a valid checkbox state
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ApplyPerGameSetting given a setting and a Qt UI element, properly applies a Setting
|
||||||
|
* taking into account the global/per-game check state. This is used for configuring checkboxes
|
||||||
|
* @param setting
|
||||||
|
* @param checkbox
|
||||||
|
* @param tracker
|
||||||
|
*/
|
||||||
|
void ApplyPerGameSetting(Settings::SwitchableSetting<bool>* setting, const QCheckBox* checkbox,
|
||||||
|
const CheckState& tracker);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ApplyPerGameSetting given a setting and a Qt UI element, properly applies a Setting
|
||||||
|
* taking into account the global/per-game check state. This is used for both combo boxes
|
||||||
|
* as well as any other widget that is accompanied by a combo box in per-game settings.
|
||||||
|
* @param setting The setting class that stores the desired option
|
||||||
|
* @param combobox The Qt combo box that stores the value/per-game status
|
||||||
|
* @param transform A function that accepts the combo box index and transforms it to the
|
||||||
|
* desired settings value. When used with sliders/edit the user can ignore the input value
|
||||||
|
* and set a custom value this making this function useful for these widgets as well
|
||||||
|
*/
|
||||||
|
template <typename Type, bool ranged>
|
||||||
|
void ApplyPerGameSetting(Settings::SwitchableSetting<Type, ranged>* setting,
|
||||||
|
const QComboBox* combobox, auto transform) {
|
||||||
|
if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
|
||||||
|
setting->SetValue(static_cast<Type>(transform(combobox->currentIndex())));
|
||||||
|
} else if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
|
||||||
|
setting->SetGlobal(true);
|
||||||
|
} else {
|
||||||
|
setting->SetGlobal(false);
|
||||||
|
setting->SetValue(static_cast<Type>(
|
||||||
|
transform(combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simpler version of ApplyPerGameSetting without a transform parameter
|
||||||
|
template <typename Type, bool ranged>
|
||||||
|
void ApplyPerGameSetting(Settings::SwitchableSetting<Type, ranged>* setting,
|
||||||
|
const QComboBox* combobox) {
|
||||||
|
const auto transform = [](s32 index) { return index; };
|
||||||
|
return ApplyPerGameSetting(setting, combobox, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets a Qt UI element given a Settings::Setting
|
||||||
|
void SetPerGameSetting(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>* setting);
|
||||||
|
|
||||||
|
template <typename Type, bool ranged>
|
||||||
|
void SetPerGameSetting(QComboBox* combobox,
|
||||||
|
const Settings::SwitchableSetting<Type, ranged>* setting) {
|
||||||
|
combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX
|
||||||
|
: static_cast<int>(setting->GetValue()) +
|
||||||
|
ConfigurationShared::USE_GLOBAL_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a Qt widget sets the background color to indicate whether the setting
|
||||||
|
/// is per-game overriden (highlighted) or global (non-highlighted)
|
||||||
|
void SetHighlight(QWidget* widget, bool highlighted);
|
||||||
|
|
||||||
|
/// Sets up a QCheckBox like a tristate one, given a Setting
|
||||||
|
void SetColoredTristate(QCheckBox* checkbox, const Settings::SwitchableSetting<bool>& setting,
|
||||||
|
CheckState& tracker);
|
||||||
|
void SetColoredTristate(QCheckBox* checkbox, bool global, bool state, bool global_state,
|
||||||
|
CheckState& tracker);
|
||||||
|
|
||||||
|
/// Sets up coloring of a QWidget `target` based on the state of a QComboBox, and calls
|
||||||
|
/// InsertGlobalItem
|
||||||
|
void SetColoredComboBox(QComboBox* combobox, QWidget* target, int global);
|
||||||
|
|
||||||
|
/// Adds the "Use Global Configuration" selection and separator to the beginning of a QComboBox
|
||||||
|
void InsertGlobalItem(QComboBox* combobox, int global_index);
|
||||||
|
|
||||||
|
} // namespace ConfigurationShared
|
|
@ -9,10 +9,11 @@
|
||||||
#endif
|
#endif
|
||||||
#include "audio_core/sink.h"
|
#include "audio_core/sink.h"
|
||||||
#include "audio_core/sink_details.h"
|
#include "audio_core/sink_details.h"
|
||||||
|
#include "citra_qt/configuration/configuration_shared.h"
|
||||||
#include "citra_qt/configuration/configure_audio.h"
|
#include "citra_qt/configuration/configure_audio.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/mic.h"
|
#include "core/frontend/mic.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "ui_configure_audio.h"
|
#include "ui_configure_audio.h"
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
@ -31,25 +32,30 @@ ConfigureAudio::ConfigureAudio(QWidget* parent)
|
||||||
ui->output_sink_combo_box->addItem(QString::fromUtf8(id));
|
ui->output_sink_combo_box->addItem(QString::fromUtf8(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->emulation_combo_box->addItem(tr("HLE (fast)"));
|
const bool is_running = Core::System::GetInstance().IsPoweredOn();
|
||||||
ui->emulation_combo_box->addItem(tr("LLE (accurate)"));
|
ui->emulation_combo_box->setEnabled(!is_running);
|
||||||
ui->emulation_combo_box->addItem(tr("LLE multi-core"));
|
|
||||||
ui->emulation_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
|
||||||
|
|
||||||
connect(ui->volume_slider, &QSlider::valueChanged, this,
|
connect(ui->volume_slider, &QSlider::valueChanged, this,
|
||||||
&ConfigureAudio::SetVolumeIndicatorText);
|
&ConfigureAudio::SetVolumeIndicatorText);
|
||||||
|
|
||||||
ui->input_device_combo_box->clear();
|
ui->input_device_combo_box->clear();
|
||||||
ui->input_device_combo_box->addItem(tr("Default"));
|
ui->input_device_combo_box->addItem(tr("Default"));
|
||||||
|
|
||||||
#ifdef HAVE_CUBEB
|
#ifdef HAVE_CUBEB
|
||||||
for (const auto& device : AudioCore::ListCubebInputDevices()) {
|
for (const auto& device : AudioCore::ListCubebInputDevices()) {
|
||||||
ui->input_device_combo_box->addItem(QString::fromStdString(device));
|
ui->input_device_combo_box->addItem(QString::fromStdString(device));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
connect(ui->input_type_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(ui->input_type_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
&ConfigureAudio::UpdateAudioInputDevices);
|
&ConfigureAudio::UpdateAudioInputDevices);
|
||||||
|
|
||||||
|
ui->volume_label->setVisible(Settings::IsConfiguringGlobal());
|
||||||
|
ui->volume_combo_box->setVisible(!Settings::IsConfiguringGlobal());
|
||||||
|
|
||||||
|
SetupPerGameUI();
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
&ConfigureAudio::UpdateAudioOutputDevices);
|
&ConfigureAudio::UpdateAudioOutputDevices);
|
||||||
}
|
}
|
||||||
|
@ -61,27 +67,35 @@ void ConfigureAudio::SetConfiguration() {
|
||||||
|
|
||||||
// The device list cannot be pre-populated (nor listed) until the output sink is known.
|
// The device list cannot be pre-populated (nor listed) until the output sink is known.
|
||||||
UpdateAudioOutputDevices(ui->output_sink_combo_box->currentIndex());
|
UpdateAudioOutputDevices(ui->output_sink_combo_box->currentIndex());
|
||||||
|
|
||||||
SetAudioDeviceFromDeviceID();
|
SetAudioDeviceFromDeviceID();
|
||||||
|
|
||||||
ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching);
|
ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching.GetValue());
|
||||||
ui->volume_slider->setValue(
|
|
||||||
static_cast<int>(Settings::values.volume * ui->volume_slider->maximum()));
|
const s32 volume =
|
||||||
|
static_cast<s32>(Settings::values.volume.GetValue() * ui->volume_slider->maximum());
|
||||||
|
ui->volume_slider->setValue(volume);
|
||||||
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
SetVolumeIndicatorText(ui->volume_slider->sliderPosition());
|
||||||
|
|
||||||
int selection;
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
if (Settings::values.enable_dsp_lle) {
|
if (Settings::values.volume.UsingGlobal()) {
|
||||||
if (Settings::values.enable_dsp_lle_multithread) {
|
ui->volume_combo_box->setCurrentIndex(0);
|
||||||
selection = 2;
|
ui->volume_slider->setEnabled(false);
|
||||||
} else {
|
} else {
|
||||||
selection = 1;
|
ui->volume_combo_box->setCurrentIndex(1);
|
||||||
|
ui->volume_slider->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
ConfigurationShared::SetHighlight(ui->volume_layout,
|
||||||
|
!Settings::values.volume.UsingGlobal());
|
||||||
|
ConfigurationShared::SetHighlight(ui->widget_emulation,
|
||||||
|
!Settings::values.audio_emulation.UsingGlobal());
|
||||||
|
ConfigurationShared::SetPerGameSetting(ui->emulation_combo_box,
|
||||||
|
&Settings::values.audio_emulation);
|
||||||
} else {
|
} else {
|
||||||
selection = 0;
|
s32 selection = static_cast<s32>(Settings::values.audio_emulation.GetValue());
|
||||||
|
ui->emulation_combo_box->setCurrentIndex(selection);
|
||||||
}
|
}
|
||||||
ui->emulation_combo_box->setCurrentIndex(selection);
|
|
||||||
|
|
||||||
int index = static_cast<int>(Settings::values.mic_input_type);
|
s32 index = static_cast<s32>(Settings::values.mic_input_type.GetValue());
|
||||||
ui->input_type_combo_box->setCurrentIndex(index);
|
ui->input_type_combo_box->setCurrentIndex(index);
|
||||||
|
|
||||||
UpdateAudioInputDevices(index);
|
UpdateAudioInputDevices(index);
|
||||||
|
@ -90,7 +104,7 @@ void ConfigureAudio::SetConfiguration() {
|
||||||
void ConfigureAudio::SetOutputSinkFromSinkID() {
|
void ConfigureAudio::SetOutputSinkFromSinkID() {
|
||||||
int new_sink_index = 0;
|
int new_sink_index = 0;
|
||||||
|
|
||||||
const QString sink_id = QString::fromStdString(Settings::values.sink_id);
|
const QString sink_id = QString::fromStdString(Settings::values.sink_id.GetValue());
|
||||||
for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
|
for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
|
||||||
if (ui->output_sink_combo_box->itemText(index) == sink_id) {
|
if (ui->output_sink_combo_box->itemText(index) == sink_id) {
|
||||||
new_sink_index = index;
|
new_sink_index = index;
|
||||||
|
@ -104,7 +118,7 @@ void ConfigureAudio::SetOutputSinkFromSinkID() {
|
||||||
void ConfigureAudio::SetAudioDeviceFromDeviceID() {
|
void ConfigureAudio::SetAudioDeviceFromDeviceID() {
|
||||||
int new_device_index = -1;
|
int new_device_index = -1;
|
||||||
|
|
||||||
const QString device_id = QString::fromStdString(Settings::values.audio_device_id);
|
const QString device_id = QString::fromStdString(Settings::values.audio_device_id.GetValue());
|
||||||
for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
|
for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
|
||||||
if (ui->audio_device_combo_box->itemText(index) == device_id) {
|
if (ui->audio_device_combo_box->itemText(index) == device_id) {
|
||||||
new_device_index = index;
|
new_device_index = index;
|
||||||
|
@ -120,24 +134,31 @@ void ConfigureAudio::SetVolumeIndicatorText(int percentage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::ApplyConfiguration() {
|
void ConfigureAudio::ApplyConfiguration() {
|
||||||
Settings::values.sink_id =
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching,
|
||||||
ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
|
ui->toggle_audio_stretching, audio_stretching);
|
||||||
.toStdString();
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.audio_emulation,
|
||||||
Settings::values.enable_audio_stretching = ui->toggle_audio_stretching->isChecked();
|
ui->emulation_combo_box);
|
||||||
Settings::values.audio_device_id =
|
ConfigurationShared::ApplyPerGameSetting(
|
||||||
ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
|
&Settings::values.volume, ui->volume_combo_box, [this](s32) {
|
||||||
.toStdString();
|
return static_cast<float>(ui->volume_slider->value()) / ui->volume_slider->maximum();
|
||||||
Settings::values.volume =
|
});
|
||||||
static_cast<float>(ui->volume_slider->sliderPosition()) / ui->volume_slider->maximum();
|
|
||||||
Settings::values.enable_dsp_lle = ui->emulation_combo_box->currentIndex() != 0;
|
|
||||||
Settings::values.enable_dsp_lle_multithread = ui->emulation_combo_box->currentIndex() == 2;
|
|
||||||
Settings::values.mic_input_type =
|
|
||||||
static_cast<Settings::MicInputType>(ui->input_type_combo_box->currentIndex());
|
|
||||||
|
|
||||||
if (ui->input_device_combo_box->currentIndex() == DEFAULT_INPUT_DEVICE_INDEX) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
Settings::values.mic_input_device = Frontend::Mic::default_device_name;
|
Settings::values.sink_id =
|
||||||
} else {
|
ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
|
||||||
Settings::values.mic_input_device = ui->input_device_combo_box->currentText().toStdString();
|
.toStdString();
|
||||||
|
Settings::values.audio_device_id =
|
||||||
|
ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
|
||||||
|
.toStdString();
|
||||||
|
Settings::values.mic_input_type =
|
||||||
|
static_cast<Settings::MicInputType>(ui->input_type_combo_box->currentIndex());
|
||||||
|
|
||||||
|
if (ui->input_device_combo_box->currentIndex() == DEFAULT_INPUT_DEVICE_INDEX) {
|
||||||
|
Settings::values.mic_input_device = Frontend::Mic::default_device_name;
|
||||||
|
} else {
|
||||||
|
Settings::values.mic_input_device =
|
||||||
|
ui->input_device_combo_box->currentText().toStdString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,12 +178,41 @@ void ConfigureAudio::UpdateAudioInputDevices(int index) {
|
||||||
AppleAuthorization::CheckAuthorizationForMicrophone();
|
AppleAuthorization::CheckAuthorizationForMicrophone();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (Settings::values.mic_input_device != Frontend::Mic::default_device_name) {
|
if (Settings::values.mic_input_device.GetValue() != Frontend::Mic::default_device_name) {
|
||||||
ui->input_device_combo_box->setCurrentText(
|
ui->input_device_combo_box->setCurrentText(
|
||||||
QString::fromStdString(Settings::values.mic_input_device));
|
QString::fromStdString(Settings::values.mic_input_device.GetValue()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureAudio::RetranslateUI() {
|
void ConfigureAudio::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigureAudio::SetupPerGameUI() {
|
||||||
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
ui->volume_slider->setEnabled(Settings::values.volume.UsingGlobal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->output_sink_combo_box->setVisible(false);
|
||||||
|
ui->output_sink_label->setVisible(false);
|
||||||
|
ui->audio_device_combo_box->setVisible(false);
|
||||||
|
ui->audio_device_label->setVisible(false);
|
||||||
|
ui->input_type_label->setVisible(false);
|
||||||
|
ui->input_type_combo_box->setVisible(false);
|
||||||
|
ui->input_device_label->setVisible(false);
|
||||||
|
ui->input_device_combo_box->setVisible(false);
|
||||||
|
ui->microphone_layout->setVisible(false);
|
||||||
|
|
||||||
|
connect(ui->volume_combo_box, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
||||||
|
ui->volume_slider->setEnabled(index == 1);
|
||||||
|
ConfigurationShared::SetHighlight(ui->volume_layout, index == 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
ConfigurationShared::SetColoredComboBox(
|
||||||
|
ui->emulation_combo_box, ui->widget_emulation,
|
||||||
|
static_cast<u32>(Settings::values.audio_emulation.GetValue(true)));
|
||||||
|
|
||||||
|
ConfigurationShared::SetColoredTristate(
|
||||||
|
ui->toggle_audio_stretching, Settings::values.enable_audio_stretching, audio_stretching);
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,10 @@ namespace Ui {
|
||||||
class ConfigureAudio;
|
class ConfigureAudio;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ConfigurationShared {
|
||||||
|
enum class CheckState;
|
||||||
|
}
|
||||||
|
|
||||||
class ConfigureAudio : public QWidget {
|
class ConfigureAudio : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -30,5 +34,8 @@ private:
|
||||||
void SetAudioDeviceFromDeviceID();
|
void SetAudioDeviceFromDeviceID();
|
||||||
void SetVolumeIndicatorText(int percentage);
|
void SetVolumeIndicatorText(int percentage);
|
||||||
|
|
||||||
|
void SetupPerGameUI();
|
||||||
|
|
||||||
|
ConfigurationShared::CheckState audio_stretching;
|
||||||
std::unique_ptr<Ui::ConfigureAudio> ui;
|
std::unique_ptr<Ui::ConfigureAudio> ui;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>329</width>
|
<width>696</width>
|
||||||
<height>344</height>
|
<height>527</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout">
|
||||||
|
@ -18,26 +18,53 @@
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout">
|
<layout class="QVBoxLayout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_emulation">
|
<widget class="QWidget" name="widget_emulation" native="true">
|
||||||
<property name="bottomMargin">
|
<layout class="QHBoxLayout" name="horizontalLayout_emulation">
|
||||||
<number>0</number>
|
<property name="leftMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QLabel" name="label_emulation">
|
<property name="topMargin">
|
||||||
<property name="text">
|
<number>0</number>
|
||||||
<string>Emulation:</string>
|
</property>
|
||||||
</property>
|
<property name="rightMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="bottomMargin">
|
||||||
<widget class="QComboBox" name="emulation_combo_box"/>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
</layout>
|
<item>
|
||||||
|
<widget class="QLabel" name="label_emulation">
|
||||||
|
<property name="text">
|
||||||
|
<string>Emulation:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="emulation_combo_box">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>HLE (fast)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>LLE (accurate)</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>LLE multi-core</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout">
|
<layout class="QHBoxLayout" name="output_engine_layout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label1">
|
<widget class="QLabel" name="output_sink_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Output Engine</string>
|
<string>Output Engine</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -59,9 +86,9 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout">
|
<layout class="QHBoxLayout" name="audio_device_layout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label2">
|
<widget class="QLabel" name="audio_device_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Audio Device</string>
|
<string>Audio Device</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -73,72 +100,97 @@
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<widget class="QWidget" name="volume_layout" native="true">
|
||||||
<property name="topMargin">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<number>0</number>
|
<property name="leftMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QLabel" name="label">
|
<property name="topMargin">
|
||||||
<property name="text">
|
<number>0</number>
|
||||||
<string>Volume:</string>
|
</property>
|
||||||
</property>
|
<property name="rightMargin">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item>
|
<property name="bottomMargin">
|
||||||
<spacer name="horizontalSpacer">
|
<number>0</number>
|
||||||
<property name="orientation">
|
</property>
|
||||||
<enum>Qt::Horizontal</enum>
|
<item>
|
||||||
</property>
|
<widget class="QComboBox" name="volume_combo_box">
|
||||||
<property name="sizeHint" stdset="0">
|
<item>
|
||||||
<size>
|
<property name="text">
|
||||||
<width>40</width>
|
<string>Use global volume</string>
|
||||||
<height>20</height>
|
</property>
|
||||||
</size>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
</spacer>
|
<property name="text">
|
||||||
</item>
|
<string>Set volume:</string>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QSlider" name="volume_slider">
|
</item>
|
||||||
<property name="sizePolicy">
|
</widget>
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
</item>
|
||||||
<horstretch>0</horstretch>
|
<item>
|
||||||
<verstretch>0</verstretch>
|
<widget class="QLabel" name="volume_label">
|
||||||
</sizepolicy>
|
<property name="text">
|
||||||
</property>
|
<string>Volume:</string>
|
||||||
<property name="maximum">
|
</property>
|
||||||
<number>100</number>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="pageStep">
|
<item>
|
||||||
<number>10</number>
|
<spacer name="horizontalSpacer">
|
||||||
</property>
|
<property name="orientation">
|
||||||
<property name="orientation">
|
<enum>Qt::Horizontal</enum>
|
||||||
<enum>Qt::Horizontal</enum>
|
</property>
|
||||||
</property>
|
<property name="sizeHint" stdset="0">
|
||||||
</widget>
|
<size>
|
||||||
</item>
|
<width>30</width>
|
||||||
<item>
|
<height>20</height>
|
||||||
<widget class="QLabel" name="volume_indicator">
|
</size>
|
||||||
<property name="minimumSize">
|
</property>
|
||||||
<size>
|
</spacer>
|
||||||
<width>32</width>
|
</item>
|
||||||
<height>0</height>
|
<item>
|
||||||
</size>
|
<widget class="QSlider" name="volume_slider">
|
||||||
</property>
|
<property name="sizePolicy">
|
||||||
<property name="text">
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
<string>0 %</string>
|
<horstretch>0</horstretch>
|
||||||
</property>
|
<verstretch>0</verstretch>
|
||||||
<property name="alignment">
|
</sizepolicy>
|
||||||
<set>Qt::AlignCenter</set>
|
</property>
|
||||||
</property>
|
<property name="maximum">
|
||||||
</widget>
|
<number>100</number>
|
||||||
</item>
|
</property>
|
||||||
</layout>
|
<property name="pageStep">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="volume_indicator">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>32</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>0 %</string>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="microphone_layout">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Microphone</string>
|
<string>Microphone</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -146,7 +198,7 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_2">
|
<widget class="QLabel" name="input_type_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Input Type</string>
|
<string>Input Type</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -176,7 +228,7 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QLabel" name="input_device_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Input Device</string>
|
<string>Input Device</string>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include "citra_qt/configuration/configure_camera.h"
|
#include "citra_qt/configuration/configure_camera.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/frontend/camera/factory.h"
|
#include "core/frontend/camera/factory.h"
|
||||||
#include "core/frontend/camera/interface.h"
|
#include "core/frontend/camera/interface.h"
|
||||||
#include "core/hle/service/cam/cam.h"
|
#include "core/hle/service/cam/cam.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "ui_configure_camera.h"
|
#include "ui_configure_camera.h"
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
|
|
@ -8,11 +8,9 @@
|
||||||
#include "citra_qt/debugger/console.h"
|
#include "citra_qt/debugger/console.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/backend.h"
|
|
||||||
#include "common/logging/filter.h"
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "ui_configure_debug.h"
|
#include "ui_configure_debug.h"
|
||||||
|
|
||||||
ConfigureDebug::ConfigureDebug(QWidget* parent)
|
ConfigureDebug::ConfigureDebug(QWidget* parent)
|
||||||
|
@ -32,13 +30,13 @@ ConfigureDebug::ConfigureDebug(QWidget* parent)
|
||||||
ConfigureDebug::~ConfigureDebug() = default;
|
ConfigureDebug::~ConfigureDebug() = default;
|
||||||
|
|
||||||
void ConfigureDebug::SetConfiguration() {
|
void ConfigureDebug::SetConfiguration() {
|
||||||
ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub);
|
ui->toggle_gdbstub->setChecked(Settings::values.use_gdbstub.GetValue());
|
||||||
ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub);
|
ui->gdbport_spinbox->setEnabled(Settings::values.use_gdbstub.GetValue());
|
||||||
ui->gdbport_spinbox->setValue(Settings::values.gdbstub_port);
|
ui->gdbport_spinbox->setValue(Settings::values.gdbstub_port.GetValue());
|
||||||
ui->toggle_console->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
ui->toggle_console->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||||
ui->toggle_console->setChecked(UISettings::values.show_console);
|
ui->toggle_console->setChecked(UISettings::values.show_console.GetValue());
|
||||||
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter));
|
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
|
||||||
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit);
|
ui->toggle_cpu_jit->setChecked(Settings::values.use_cpu_jit.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureDebug::ApplyConfiguration() {
|
void ConfigureDebug::ApplyConfiguration() {
|
||||||
|
@ -48,7 +46,7 @@ void ConfigureDebug::ApplyConfiguration() {
|
||||||
Settings::values.log_filter = ui->log_filter_edit->text().toStdString();
|
Settings::values.log_filter = ui->log_filter_edit->text().toStdString();
|
||||||
Debugger::ToggleConsole();
|
Debugger::ToggleConsole();
|
||||||
Log::Filter filter;
|
Log::Filter filter;
|
||||||
filter.ParseFilterString(Settings::values.log_filter);
|
filter.ParseFilterString(Settings::values.log_filter.GetValue());
|
||||||
Log::SetGlobalFilter(filter);
|
Log::SetGlobalFilter(filter);
|
||||||
Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked();
|
Settings::values.use_cpu_jit = ui->toggle_cpu_jit->isChecked();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
#include "citra_qt/configuration/config.h"
|
#include "citra_qt/configuration/config.h"
|
||||||
#include "citra_qt/configuration/configure_dialog.h"
|
#include "citra_qt/configuration/configure_dialog.h"
|
||||||
#include "citra_qt/hotkeys.h"
|
#include "citra_qt/hotkeys.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
#include "ui_configure.h"
|
#include "ui_configure.h"
|
||||||
|
|
||||||
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, bool enable_web_config)
|
ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, bool enable_web_config)
|
||||||
: QDialog(parent), ui(std::make_unique<Ui::ConfigureDialog>()), registry(registry) {
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigureDialog>()), registry(registry) {
|
||||||
|
Settings::SetConfiguringGlobal(true);
|
||||||
|
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
ui->hotkeysTab->Populate(registry);
|
ui->hotkeysTab->Populate(registry);
|
||||||
ui->webTab->SetWebServiceConfigEnabled(enable_web_config);
|
ui->webTab->SetWebServiceConfigEnabled(enable_web_config);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
#include <QColorDialog>
|
#include <QColorDialog>
|
||||||
#include "citra_qt/configuration/configure_enhancements.h"
|
#include "citra_qt/configuration/configure_enhancements.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "ui_configure_enhancements.h"
|
#include "ui_configure_enhancements.h"
|
||||||
#include "video_core/renderer_opengl/post_processing_opengl.h"
|
#include "video_core/renderer_opengl/post_processing_opengl.h"
|
||||||
#include "video_core/renderer_opengl/texture_filters/texture_filterer.h"
|
#include "video_core/renderer_opengl/texture_filters/texture_filterer.h"
|
||||||
|
@ -21,7 +21,7 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent)
|
||||||
|
|
||||||
ui->layoutBox->setEnabled(!Settings::values.custom_layout);
|
ui->layoutBox->setEnabled(!Settings::values.custom_layout);
|
||||||
|
|
||||||
ui->resolution_factor_combobox->setEnabled(Settings::values.use_hw_renderer);
|
ui->resolution_factor_combobox->setEnabled(Settings::values.use_hw_renderer.GetValue());
|
||||||
|
|
||||||
connect(ui->render_3d_combobox,
|
connect(ui->render_3d_combobox,
|
||||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
|
||||||
|
@ -50,27 +50,30 @@ ConfigureEnhancements::ConfigureEnhancements(QWidget* parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureEnhancements::SetConfiguration() {
|
void ConfigureEnhancements::SetConfiguration() {
|
||||||
ui->resolution_factor_combobox->setCurrentIndex(Settings::values.resolution_factor);
|
ui->resolution_factor_combobox->setCurrentIndex(Settings::values.resolution_factor.GetValue());
|
||||||
ui->render_3d_combobox->setCurrentIndex(static_cast<int>(Settings::values.render_3d));
|
ui->render_3d_combobox->setCurrentIndex(
|
||||||
ui->factor_3d->setValue(Settings::values.factor_3d);
|
static_cast<int>(Settings::values.render_3d.GetValue()));
|
||||||
ui->mono_render_left_eye->setChecked(Settings::values.mono_render_left_eye);
|
ui->factor_3d->setValue(Settings::values.factor_3d.GetValue());
|
||||||
updateShaders(Settings::values.render_3d);
|
ui->mono_render_left_eye->setChecked(Settings::values.mono_render_left_eye.GetValue());
|
||||||
ui->toggle_linear_filter->setChecked(Settings::values.filter_mode);
|
updateShaders(Settings::values.render_3d.GetValue());
|
||||||
|
ui->toggle_linear_filter->setChecked(Settings::values.filter_mode.GetValue());
|
||||||
int tex_filter_idx = ui->texture_filter_combobox->findText(
|
int tex_filter_idx = ui->texture_filter_combobox->findText(
|
||||||
QString::fromStdString(Settings::values.texture_filter_name));
|
QString::fromStdString(Settings::values.texture_filter_name.GetValue()));
|
||||||
if (tex_filter_idx == -1) {
|
if (tex_filter_idx == -1) {
|
||||||
ui->texture_filter_combobox->setCurrentIndex(0);
|
ui->texture_filter_combobox->setCurrentIndex(0);
|
||||||
} else {
|
} else {
|
||||||
ui->texture_filter_combobox->setCurrentIndex(tex_filter_idx);
|
ui->texture_filter_combobox->setCurrentIndex(tex_filter_idx);
|
||||||
}
|
}
|
||||||
ui->layout_combobox->setCurrentIndex(static_cast<int>(Settings::values.layout_option));
|
ui->layout_combobox->setCurrentIndex(
|
||||||
ui->swap_screen->setChecked(Settings::values.swap_screen);
|
static_cast<int>(Settings::values.layout_option.GetValue()));
|
||||||
ui->upright_screen->setChecked(Settings::values.upright_screen);
|
ui->swap_screen->setChecked(Settings::values.swap_screen.GetValue());
|
||||||
ui->toggle_dump_textures->setChecked(Settings::values.dump_textures);
|
ui->upright_screen->setChecked(Settings::values.upright_screen.GetValue());
|
||||||
ui->toggle_custom_textures->setChecked(Settings::values.custom_textures);
|
ui->toggle_dump_textures->setChecked(Settings::values.dump_textures.GetValue());
|
||||||
ui->toggle_preload_textures->setChecked(Settings::values.preload_textures);
|
ui->toggle_custom_textures->setChecked(Settings::values.custom_textures.GetValue());
|
||||||
bg_color = QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green,
|
ui->toggle_preload_textures->setChecked(Settings::values.preload_textures.GetValue());
|
||||||
Settings::values.bg_blue);
|
bg_color =
|
||||||
|
QColor::fromRgbF(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(),
|
||||||
|
Settings::values.bg_blue.GetValue());
|
||||||
QPixmap pixmap(ui->bg_button->size());
|
QPixmap pixmap(ui->bg_button->size());
|
||||||
pixmap.fill(bg_color);
|
pixmap.fill(bg_color);
|
||||||
const QIcon color_icon(pixmap);
|
const QIcon color_icon(pixmap);
|
||||||
|
@ -93,7 +96,7 @@ void ConfigureEnhancements::updateShaders(Settings::StereoRenderOption stereo_op
|
||||||
for (const auto& shader : OpenGL::GetPostProcessingShaderList(
|
for (const auto& shader : OpenGL::GetPostProcessingShaderList(
|
||||||
stereo_option == Settings::StereoRenderOption::Anaglyph)) {
|
stereo_option == Settings::StereoRenderOption::Anaglyph)) {
|
||||||
ui->shader_combobox->addItem(QString::fromStdString(shader));
|
ui->shader_combobox->addItem(QString::fromStdString(shader));
|
||||||
if (Settings::values.pp_shader_name == shader)
|
if (Settings::values.pp_shader_name.GetValue() == shader)
|
||||||
ui->shader_combobox->setCurrentIndex(ui->shader_combobox->count() - 1);
|
ui->shader_combobox->setCurrentIndex(ui->shader_combobox->count() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,10 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
enum class StereoRenderOption;
|
enum class StereoRenderOption : u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include "citra_qt/configuration/configuration_shared.h"
|
||||||
#include "citra_qt/configuration/configure_general.h"
|
#include "citra_qt/configuration/configure_general.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "core/core.h"
|
#include "common/file_util.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
#include "ui_configure_general.h"
|
#include "ui_configure_general.h"
|
||||||
|
|
||||||
// The QSlider doesn't have an easy way to set a custom step amount,
|
// The QSlider doesn't have an easy way to set a custom step amount,
|
||||||
|
@ -31,14 +32,17 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||||
// Set a minimum width for the label to prevent the slider from changing size.
|
// Set a minimum width for the label to prevent the slider from changing size.
|
||||||
// This scales across DPIs, and is acceptable for uncapitalized strings.
|
// This scales across DPIs, and is acceptable for uncapitalized strings.
|
||||||
ui->emulation_speed_display_label->setMinimumWidth(tr("unthrottled").size() * 6);
|
ui->emulation_speed_display_label->setMinimumWidth(tr("unthrottled").size() * 6);
|
||||||
|
ui->emulation_speed_combo->setVisible(!Settings::IsConfiguringGlobal());
|
||||||
|
ui->screenshot_combo->setVisible(!Settings::IsConfiguringGlobal());
|
||||||
|
|
||||||
|
SetupPerGameUI();
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
ui->updateBox->setVisible(UISettings::values.updater_found);
|
ui->updateBox->setVisible(UISettings::values.updater_found);
|
||||||
connect(ui->button_reset_defaults, &QPushButton::clicked, this,
|
connect(ui->button_reset_defaults, &QPushButton::clicked, this,
|
||||||
&ConfigureGeneral::ResetDefaults);
|
&ConfigureGeneral::ResetDefaults);
|
||||||
|
|
||||||
connect(ui->frame_limit, &QSlider::valueChanged, [&](int value) {
|
connect(ui->frame_limit, &QSlider::valueChanged, this, [&](int value) {
|
||||||
if (value == ui->frame_limit->maximum()) {
|
if (value == ui->frame_limit->maximum()) {
|
||||||
ui->emulation_speed_display_label->setText(tr("unthrottled"));
|
ui->emulation_speed_display_label->setText(tr("unthrottled"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -49,17 +53,6 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ui->frame_limit_alternate, &QSlider::valueChanged, [&](int value) {
|
|
||||||
if (value == ui->frame_limit_alternate->maximum()) {
|
|
||||||
ui->emulation_speed_alternate_display_label->setText(tr("unthrottled"));
|
|
||||||
} else {
|
|
||||||
ui->emulation_speed_alternate_display_label->setText(
|
|
||||||
QStringLiteral("%1%")
|
|
||||||
.arg(SliderToSettings(value))
|
|
||||||
.rightJustified(tr("unthrottled").size()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(ui->change_screenshot_dir, &QToolButton::clicked, this, [this] {
|
connect(ui->change_screenshot_dir, &QToolButton::clicked, this, [this] {
|
||||||
const QString dir_path = QFileDialog::getExistingDirectory(
|
const QString dir_path = QFileDialog::getExistingDirectory(
|
||||||
this, tr("Select Screenshot Directory"), ui->screenshot_dir_path->text(),
|
this, tr("Select Screenshot Directory"), ui->screenshot_dir_path->text(),
|
||||||
|
@ -73,20 +66,21 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
|
||||||
ConfigureGeneral::~ConfigureGeneral() = default;
|
ConfigureGeneral::~ConfigureGeneral() = default;
|
||||||
|
|
||||||
void ConfigureGeneral::SetConfiguration() {
|
void ConfigureGeneral::SetConfiguration() {
|
||||||
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing);
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background);
|
ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing.GetValue());
|
||||||
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse);
|
ui->toggle_background_pause->setChecked(
|
||||||
|
UISettings::values.pause_when_in_background.GetValue());
|
||||||
|
ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse.GetValue());
|
||||||
|
|
||||||
ui->toggle_update_check->setChecked(UISettings::values.check_for_update_on_start);
|
ui->toggle_update_check->setChecked(
|
||||||
ui->toggle_auto_update->setChecked(UISettings::values.update_on_close);
|
UISettings::values.check_for_update_on_start.GetValue());
|
||||||
|
ui->toggle_auto_update->setChecked(UISettings::values.update_on_close.GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
// The first item is "auto-select" with actual value -1, so plus one here will do the trick
|
if (Settings::values.frame_limit.GetValue() == 0) {
|
||||||
ui->region_combobox->setCurrentIndex(Settings::values.region_value + 1);
|
|
||||||
|
|
||||||
if (Settings::values.frame_limit == 0) {
|
|
||||||
ui->frame_limit->setValue(ui->frame_limit->maximum());
|
ui->frame_limit->setValue(ui->frame_limit->maximum());
|
||||||
} else {
|
} else {
|
||||||
ui->frame_limit->setValue(SettingsToSlider(Settings::values.frame_limit));
|
ui->frame_limit->setValue(SettingsToSlider(Settings::values.frame_limit.GetValue()));
|
||||||
}
|
}
|
||||||
if (ui->frame_limit->value() == ui->frame_limit->maximum()) {
|
if (ui->frame_limit->value() == ui->frame_limit->maximum()) {
|
||||||
ui->emulation_speed_display_label->setText(tr("unthrottled"));
|
ui->emulation_speed_display_label->setText(tr("unthrottled"));
|
||||||
|
@ -97,32 +91,48 @@ void ConfigureGeneral::SetConfiguration() {
|
||||||
.rightJustified(tr("unthrottled").size()));
|
.rightJustified(tr("unthrottled").size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->toggle_alternate_speed->setChecked(Settings::values.use_frame_limit_alternate);
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
if (Settings::values.frame_limit.UsingGlobal()) {
|
||||||
if (Settings::values.frame_limit_alternate == 0) {
|
ui->emulation_speed_combo->setCurrentIndex(0);
|
||||||
ui->frame_limit_alternate->setValue(ui->frame_limit_alternate->maximum());
|
ui->frame_limit->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
ui->emulation_speed_combo->setCurrentIndex(1);
|
||||||
|
ui->frame_limit->setEnabled(true);
|
||||||
|
}
|
||||||
|
if (UISettings::values.screenshot_path.UsingGlobal()) {
|
||||||
|
ui->screenshot_combo->setCurrentIndex(0);
|
||||||
|
ui->screenshot_dir_path->setEnabled(false);
|
||||||
|
ui->change_screenshot_dir->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
ui->screenshot_combo->setCurrentIndex(1);
|
||||||
|
ui->screenshot_dir_path->setEnabled(true);
|
||||||
|
ui->change_screenshot_dir->setEnabled(true);
|
||||||
|
}
|
||||||
|
ConfigurationShared::SetHighlight(ui->widget_screenshot,
|
||||||
|
!UISettings::values.screenshot_path.UsingGlobal());
|
||||||
|
ConfigurationShared::SetHighlight(ui->emulation_speed_layout,
|
||||||
|
!Settings::values.frame_limit.UsingGlobal());
|
||||||
|
ConfigurationShared::SetHighlight(ui->widget_region,
|
||||||
|
!Settings::values.region_value.UsingGlobal());
|
||||||
|
const bool is_region_global = Settings::values.region_value.UsingGlobal();
|
||||||
|
ui->region_combobox->setCurrentIndex(
|
||||||
|
is_region_global ? ConfigurationShared::USE_GLOBAL_INDEX
|
||||||
|
: static_cast<int>(Settings::values.region_value.GetValue()) +
|
||||||
|
ConfigurationShared::USE_GLOBAL_OFFSET + 1);
|
||||||
} else {
|
} else {
|
||||||
ui->frame_limit_alternate->setValue(
|
// The first item is "auto-select" with actual value -1, so plus one here will do the trick
|
||||||
SettingsToSlider(Settings::values.frame_limit_alternate));
|
ui->region_combobox->setCurrentIndex(Settings::values.region_value.GetValue() + 1);
|
||||||
}
|
|
||||||
if (ui->frame_limit_alternate->value() == ui->frame_limit_alternate->maximum()) {
|
|
||||||
ui->emulation_speed_alternate_display_label->setText(tr("unthrottled"));
|
|
||||||
} else {
|
|
||||||
ui->emulation_speed_alternate_display_label->setText(
|
|
||||||
QStringLiteral("%1%")
|
|
||||||
.arg(SliderToSettings(ui->frame_limit_alternate->value()))
|
|
||||||
.rightJustified(tr("unthrottled").size()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString screenshot_path = UISettings::values.screenshot_path;
|
UISettings::values.screenshot_path.SetGlobal(ui->screenshot_combo->currentIndex() ==
|
||||||
if (screenshot_path.isEmpty()) {
|
ConfigurationShared::USE_GLOBAL_INDEX);
|
||||||
screenshot_path =
|
std::string screenshot_path = UISettings::values.screenshot_path.GetValue();
|
||||||
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::UserDir));
|
if (screenshot_path.empty()) {
|
||||||
screenshot_path.append(QStringLiteral("screenshots/"));
|
screenshot_path = FileUtil::GetUserPath(FileUtil::UserPath::UserDir) + "screenshots/";
|
||||||
FileUtil::CreateFullPath(screenshot_path.toStdString());
|
FileUtil::CreateFullPath(screenshot_path);
|
||||||
UISettings::values.screenshot_path = screenshot_path;
|
UISettings::values.screenshot_path = screenshot_path;
|
||||||
}
|
}
|
||||||
ui->screenshot_dir_path->setText(screenshot_path);
|
ui->screenshot_dir_path->setText(QString::fromStdString(screenshot_path));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::ResetDefaults() {
|
void ConfigureGeneral::ResetDefaults() {
|
||||||
|
@ -139,31 +149,57 @@ void ConfigureGeneral::ResetDefaults() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::ApplyConfiguration() {
|
void ConfigureGeneral::ApplyConfiguration() {
|
||||||
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.region_value, ui->region_combobox,
|
||||||
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
|
[](s32 index) { return index - 1; });
|
||||||
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
|
|
||||||
|
|
||||||
UISettings::values.check_for_update_on_start = ui->toggle_update_check->isChecked();
|
ConfigurationShared::ApplyPerGameSetting(
|
||||||
UISettings::values.update_on_close = ui->toggle_auto_update->isChecked();
|
&Settings::values.frame_limit, ui->emulation_speed_combo, [this](s32) {
|
||||||
|
const bool is_maximum = ui->frame_limit->value() == ui->frame_limit->maximum();
|
||||||
|
return is_maximum ? 0 : SliderToSettings(ui->frame_limit->value());
|
||||||
|
});
|
||||||
|
|
||||||
UISettings::values.screenshot_path = ui->screenshot_dir_path->text();
|
ConfigurationShared::ApplyPerGameSetting(
|
||||||
|
&UISettings::values.screenshot_path, ui->screenshot_combo,
|
||||||
|
[this](s32) { return ui->screenshot_dir_path->text().toStdString(); });
|
||||||
|
|
||||||
Settings::values.region_value = ui->region_combobox->currentIndex() - 1;
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked();
|
||||||
|
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
|
||||||
|
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
|
||||||
|
|
||||||
if (ui->frame_limit->value() == ui->frame_limit->maximum()) {
|
UISettings::values.check_for_update_on_start = ui->toggle_update_check->isChecked();
|
||||||
Settings::values.frame_limit = 0;
|
UISettings::values.update_on_close = ui->toggle_auto_update->isChecked();
|
||||||
} else {
|
|
||||||
Settings::values.frame_limit = SliderToSettings(ui->frame_limit->value());
|
|
||||||
}
|
|
||||||
Settings::values.use_frame_limit_alternate = ui->toggle_alternate_speed->isChecked();
|
|
||||||
if (ui->frame_limit_alternate->value() == ui->frame_limit_alternate->maximum()) {
|
|
||||||
Settings::values.frame_limit_alternate = 0;
|
|
||||||
} else {
|
|
||||||
Settings::values.frame_limit_alternate =
|
|
||||||
SliderToSettings(ui->frame_limit_alternate->value());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::RetranslateUI() {
|
void ConfigureGeneral::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigureGeneral::SetupPerGameUI() {
|
||||||
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
ui->region_combobox->setEnabled(Settings::values.region_value.UsingGlobal());
|
||||||
|
ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(ui->emulation_speed_combo, qOverload<int>(&QComboBox::activated), this,
|
||||||
|
[this](int index) {
|
||||||
|
ui->frame_limit->setEnabled(index == 1);
|
||||||
|
ConfigurationShared::SetHighlight(ui->emulation_speed_layout, index == 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
connect(ui->screenshot_combo, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
||||||
|
ui->screenshot_dir_path->setEnabled(index == 1);
|
||||||
|
ui->change_screenshot_dir->setEnabled(index == 1);
|
||||||
|
ConfigurationShared::SetHighlight(ui->widget_screenshot, index == 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
ui->general_group->setVisible(false);
|
||||||
|
ui->updateBox->setVisible(false);
|
||||||
|
ui->button_reset_defaults->setVisible(false);
|
||||||
|
|
||||||
|
ConfigurationShared::SetColoredComboBox(
|
||||||
|
ui->region_combobox, ui->widget_region,
|
||||||
|
static_cast<u32>(Settings::values.region_value.GetValue(true) + 1));
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,8 @@ public:
|
||||||
void RetranslateUI();
|
void RetranslateUI();
|
||||||
void SetConfiguration();
|
void SetConfiguration();
|
||||||
|
|
||||||
|
void SetupPerGameUI();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Ui::ConfigureGeneral> ui;
|
std::unique_ptr<Ui::ConfigureGeneral> ui;
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>408</width>
|
<width>524</width>
|
||||||
<height>436</height>
|
<height>578</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -17,7 +17,7 @@
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="general_group">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>General</string>
|
<string>General</string>
|
||||||
</property>
|
</property>
|
||||||
|
@ -70,144 +70,152 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox_4">
|
<widget class="QGroupBox" name="emulation_group">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Emulation</string>
|
<string>Emulation</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item row="0" column="2">
|
<item>
|
||||||
<widget class="QComboBox" name="region_combobox">
|
<widget class="QWidget" name="widget_region" native="true">
|
||||||
<item>
|
<layout class="QHBoxLayout" name="region_layout">
|
||||||
<property name="text">
|
<property name="leftMargin">
|
||||||
<string>Auto-select</string>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<property name="topMargin">
|
||||||
<item>
|
<number>0</number>
|
||||||
<property name="text">
|
|
||||||
<string notr="true">JPN</string>
|
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<property name="rightMargin">
|
||||||
<item>
|
<number>0</number>
|
||||||
<property name="text">
|
|
||||||
<string notr="true">USA</string>
|
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<property name="bottomMargin">
|
||||||
<item>
|
<number>0</number>
|
||||||
<property name="text">
|
|
||||||
<string notr="true">EUR</string>
|
|
||||||
</property>
|
</property>
|
||||||
</item>
|
<item>
|
||||||
<item>
|
<widget class="QLabel" name="region_label">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string notr="true">AUS</string>
|
<string>Region:</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</widget>
|
||||||
<item>
|
</item>
|
||||||
<property name="text">
|
<item>
|
||||||
<string notr="true">CHN</string>
|
<widget class="QComboBox" name="region_combobox">
|
||||||
</property>
|
<item>
|
||||||
</item>
|
<property name="text">
|
||||||
<item>
|
<string>Auto-select</string>
|
||||||
<property name="text">
|
</property>
|
||||||
<string notr="true">KOR</string>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
</item>
|
<property name="text">
|
||||||
<item>
|
<string notr="true">JPN</string>
|
||||||
<property name="text">
|
</property>
|
||||||
<string notr="true">TWN</string>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
</item>
|
<property name="text">
|
||||||
|
<string notr="true">USA</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">EUR</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">AUS</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">CHN</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">KOR</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">TWN</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item>
|
||||||
<widget class="QLabel" name="label_emulation_speed">
|
<widget class="QWidget" name="emulation_speed_layout" native="true">
|
||||||
<property name="text">
|
<layout class="QHBoxLayout" name="emulation_speed_layout_inner">
|
||||||
<string>Emulation Speed:</string>
|
<property name="leftMargin">
|
||||||
</property>
|
<number>0</number>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="topMargin">
|
||||||
<item row="2" column="0">
|
<number>0</number>
|
||||||
<widget class="QCheckBox" name="toggle_alternate_speed">
|
</property>
|
||||||
<property name="text">
|
<property name="rightMargin">
|
||||||
<string>Use Alternate Speed:</string>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="bottomMargin">
|
||||||
</item>
|
<number>0</number>
|
||||||
<item row="1" column="2">
|
</property>
|
||||||
<widget class="QSlider" name="frame_limit">
|
<item>
|
||||||
<property name="minimum">
|
<widget class="QComboBox" name="emulation_speed_combo">
|
||||||
<number>0</number>
|
<item>
|
||||||
</property>
|
<property name="text">
|
||||||
<property name="maximum">
|
<string>Use global emulation speed</string>
|
||||||
<number>199</number>
|
</property>
|
||||||
</property>
|
</item>
|
||||||
<property name="singleStep">
|
<item>
|
||||||
<number>5</number>
|
<property name="text">
|
||||||
</property>
|
<string>Set emulation speed:</string>
|
||||||
<property name="pageStep">
|
</property>
|
||||||
<number>15</number>
|
</item>
|
||||||
</property>
|
</widget>
|
||||||
<property name="value">
|
</item>
|
||||||
<number>19</number>
|
<item>
|
||||||
</property>
|
<widget class="QLabel" name="label_emulation_speed">
|
||||||
<property name="orientation">
|
<property name="text">
|
||||||
<enum>Qt::Horizontal</enum>
|
<string>Emulation Speed:</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="tickPosition">
|
</widget>
|
||||||
<enum>QSlider::TicksBelow</enum>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
</widget>
|
<widget class="QSlider" name="frame_limit">
|
||||||
</item>
|
<property name="minimum">
|
||||||
<item row="1" column="1">
|
<number>0</number>
|
||||||
<widget class="QLabel" name="emulation_speed_display_label">
|
</property>
|
||||||
<property name="text">
|
<property name="maximum">
|
||||||
<string/>
|
<number>199</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="alignment">
|
<property name="singleStep">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<number>5</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="pageStep">
|
||||||
</item>
|
<number>15</number>
|
||||||
<item row="0" column="0">
|
</property>
|
||||||
<widget class="QLabel" name="label">
|
<property name="value">
|
||||||
<property name="text">
|
<number>19</number>
|
||||||
<string>Region:</string>
|
</property>
|
||||||
</property>
|
<property name="orientation">
|
||||||
</widget>
|
<enum>Qt::Horizontal</enum>
|
||||||
</item>
|
</property>
|
||||||
<item row="2" column="2">
|
<property name="tickPosition">
|
||||||
<widget class="QSlider" name="frame_limit_alternate">
|
<enum>QSlider::TicksBelow</enum>
|
||||||
<property name="minimum">
|
</property>
|
||||||
<number>0</number>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="maximum">
|
<item>
|
||||||
<number>199</number>
|
<widget class="QLabel" name="emulation_speed_display_label">
|
||||||
</property>
|
<property name="text">
|
||||||
<property name="singleStep">
|
<string/>
|
||||||
<number>5</number>
|
</property>
|
||||||
</property>
|
<property name="alignment">
|
||||||
<property name="pageStep">
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
<number>15</number>
|
</property>
|
||||||
</property>
|
</widget>
|
||||||
<property name="value">
|
</item>
|
||||||
<number>39</number>
|
</layout>
|
||||||
</property>
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="tickPosition">
|
|
||||||
<enum>QSlider::TicksBelow</enum>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QLabel" name="emulation_speed_alternate_display_label">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -218,23 +226,57 @@
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Screenshots</string>
|
<string>Screenshots</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item>
|
<property name="verticalSpacing">
|
||||||
<widget class="QLabel" name="label_2">
|
<number>0</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string>Save Screenshots To</string>
|
<item row="0" column="1">
|
||||||
</property>
|
<widget class="QWidget" name="widget_screenshot" native="true">
|
||||||
</widget>
|
<layout class="QHBoxLayout" name="screenshot_layout">
|
||||||
</item>
|
<property name="leftMargin">
|
||||||
<item>
|
<number>0</number>
|
||||||
<widget class="QLineEdit" name="screenshot_dir_path">
|
</property>
|
||||||
</widget>
|
<property name="topMargin">
|
||||||
</item>
|
<number>0</number>
|
||||||
<item>
|
</property>
|
||||||
<widget class="QToolButton" name="change_screenshot_dir">
|
<property name="rightMargin">
|
||||||
<property name="text">
|
<number>0</number>
|
||||||
<string>...</string>
|
</property>
|
||||||
</property>
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="screenshot_combo">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Use global screenshot path</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Set screenshot path:</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="screenshot_dir_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Save Screenshots To</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="screenshot_dir_path"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QToolButton" name="change_screenshot_dir">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -270,12 +312,6 @@
|
||||||
<tabstop>toggle_hide_mouse</tabstop>
|
<tabstop>toggle_hide_mouse</tabstop>
|
||||||
<tabstop>toggle_update_check</tabstop>
|
<tabstop>toggle_update_check</tabstop>
|
||||||
<tabstop>toggle_auto_update</tabstop>
|
<tabstop>toggle_auto_update</tabstop>
|
||||||
<tabstop>region_combobox</tabstop>
|
|
||||||
<tabstop>frame_limit</tabstop>
|
|
||||||
<tabstop>toggle_alternate_speed</tabstop>
|
|
||||||
<tabstop>frame_limit_alternate</tabstop>
|
|
||||||
<tabstop>screenshot_dir_path</tabstop>
|
|
||||||
<tabstop>change_screenshot_dir</tabstop>
|
|
||||||
<tabstop>button_reset_defaults</tabstop>
|
<tabstop>button_reset_defaults</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|
|
@ -6,22 +6,25 @@
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#endif
|
#endif
|
||||||
|
#include "citra_qt/configuration/configuration_shared.h"
|
||||||
#include "citra_qt/configuration/configure_graphics.h"
|
#include "citra_qt/configuration/configure_graphics.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "ui_configure_graphics.h"
|
#include "ui_configure_graphics.h"
|
||||||
#include "video_core/renderer_opengl/post_processing_opengl.h"
|
|
||||||
|
|
||||||
ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureGraphics>()) {
|
: QWidget(parent), ui(std::make_unique<Ui::ConfigureGraphics>()) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
SetupPerGameUI();
|
||||||
SetConfiguration();
|
SetConfiguration();
|
||||||
|
|
||||||
ui->hw_renderer_group->setEnabled(ui->toggle_hw_renderer->isChecked());
|
ui->hw_renderer_group->setEnabled(ui->hw_renderer_group->isEnabled() &&
|
||||||
|
ui->toggle_hw_renderer->isChecked());
|
||||||
ui->toggle_vsync_new->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
ui->toggle_vsync_new->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||||
|
|
||||||
connect(ui->toggle_hw_renderer, &QCheckBox::toggled, this, [this] {
|
connect(ui->toggle_hw_renderer, &QCheckBox::toggled, this, [this] {
|
||||||
auto checked = ui->toggle_hw_renderer->isChecked();
|
const bool checked = ui->toggle_hw_renderer->isChecked();
|
||||||
ui->hw_renderer_group->setEnabled(checked);
|
ui->hw_renderer_group->setEnabled(checked);
|
||||||
ui->toggle_disk_shader_cache->setEnabled(checked && ui->toggle_hw_shader->isChecked());
|
ui->toggle_disk_shader_cache->setEnabled(checked && ui->toggle_hw_shader->isChecked());
|
||||||
});
|
});
|
||||||
|
@ -31,7 +34,7 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
||||||
ui->toggle_hw_shader->isChecked());
|
ui->toggle_hw_shader->isChecked());
|
||||||
|
|
||||||
connect(ui->toggle_hw_shader, &QCheckBox::toggled, this, [this] {
|
connect(ui->toggle_hw_shader, &QCheckBox::toggled, this, [this] {
|
||||||
auto checked = ui->toggle_hw_shader->isChecked();
|
const bool checked = ui->toggle_hw_shader->isChecked();
|
||||||
ui->hw_shader_group->setEnabled(checked);
|
ui->hw_shader_group->setEnabled(checked);
|
||||||
ui->toggle_disk_shader_cache->setEnabled(checked);
|
ui->toggle_disk_shader_cache->setEnabled(checked);
|
||||||
});
|
});
|
||||||
|
@ -62,25 +65,67 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
|
||||||
ConfigureGraphics::~ConfigureGraphics() = default;
|
ConfigureGraphics::~ConfigureGraphics() = default;
|
||||||
|
|
||||||
void ConfigureGraphics::SetConfiguration() {
|
void ConfigureGraphics::SetConfiguration() {
|
||||||
ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer);
|
ui->toggle_hw_renderer->setChecked(Settings::values.use_hw_renderer.GetValue());
|
||||||
ui->toggle_hw_shader->setChecked(Settings::values.use_hw_shader);
|
ui->toggle_hw_shader->setChecked(Settings::values.use_hw_shader.GetValue());
|
||||||
ui->toggle_separable_shader->setChecked(Settings::values.separable_shader);
|
ui->toggle_separable_shader->setChecked(Settings::values.separable_shader.GetValue());
|
||||||
ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul);
|
ui->toggle_accurate_mul->setChecked(Settings::values.shaders_accurate_mul.GetValue());
|
||||||
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit);
|
ui->toggle_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
|
||||||
ui->toggle_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache);
|
ui->toggle_vsync_new->setChecked(Settings::values.use_vsync_new.GetValue());
|
||||||
ui->toggle_vsync_new->setChecked(Settings::values.use_vsync_new);
|
|
||||||
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
ui->toggle_shader_jit->setChecked(Settings::values.use_shader_jit.GetValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphics::ApplyConfiguration() {
|
void ConfigureGraphics::ApplyConfiguration() {
|
||||||
Settings::values.use_hw_renderer = ui->toggle_hw_renderer->isChecked();
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_hw_renderer,
|
||||||
Settings::values.use_hw_shader = ui->toggle_hw_shader->isChecked();
|
ui->toggle_hw_renderer, use_hw_renderer);
|
||||||
Settings::values.separable_shader = ui->toggle_separable_shader->isChecked();
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_hw_shader, ui->toggle_hw_shader,
|
||||||
Settings::values.shaders_accurate_mul = ui->toggle_accurate_mul->isChecked();
|
use_hw_shader);
|
||||||
Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked();
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.separable_shader,
|
||||||
Settings::values.use_disk_shader_cache = ui->toggle_disk_shader_cache->isChecked();
|
ui->toggle_separable_shader, separable_shader);
|
||||||
Settings::values.use_vsync_new = ui->toggle_vsync_new->isChecked();
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.shaders_accurate_mul,
|
||||||
|
ui->toggle_accurate_mul, shaders_accurate_mul);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache,
|
||||||
|
ui->toggle_disk_shader_cache, use_disk_shader_cache);
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync_new, ui->toggle_vsync_new,
|
||||||
|
use_vsync_new);
|
||||||
|
|
||||||
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
Settings::values.use_shader_jit = ui->toggle_shader_jit->isChecked();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGraphics::RetranslateUI() {
|
void ConfigureGraphics::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigureGraphics::SetupPerGameUI() {
|
||||||
|
// Block the global settings if a game is currently running that overrides them
|
||||||
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
ui->toggle_hw_renderer->setEnabled(Settings::values.use_hw_renderer.UsingGlobal());
|
||||||
|
ui->toggle_hw_shader->setEnabled(Settings::values.use_hw_shader.UsingGlobal());
|
||||||
|
ui->toggle_separable_shader->setEnabled(Settings::values.separable_shader.UsingGlobal());
|
||||||
|
ui->toggle_accurate_mul->setEnabled(Settings::values.shaders_accurate_mul.UsingGlobal());
|
||||||
|
ui->toggle_disk_shader_cache->setEnabled(
|
||||||
|
Settings::values.use_disk_shader_cache.UsingGlobal());
|
||||||
|
ui->toggle_vsync_new->setEnabled(Settings::values.use_vsync_new.UsingGlobal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->toggle_shader_jit->setVisible(false);
|
||||||
|
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->toggle_hw_renderer,
|
||||||
|
Settings::values.use_hw_renderer, use_hw_renderer);
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->toggle_hw_shader, Settings::values.use_hw_shader,
|
||||||
|
use_hw_shader);
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->toggle_separable_shader,
|
||||||
|
Settings::values.separable_shader, separable_shader);
|
||||||
|
ConfigurationShared::SetColoredTristate(
|
||||||
|
ui->toggle_accurate_mul, Settings::values.shaders_accurate_mul, shaders_accurate_mul);
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->toggle_disk_shader_cache,
|
||||||
|
Settings::values.use_disk_shader_cache,
|
||||||
|
use_disk_shader_cache);
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->toggle_vsync_new, Settings::values.use_vsync_new,
|
||||||
|
use_vsync_new);
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,10 @@ namespace Ui {
|
||||||
class ConfigureGraphics;
|
class ConfigureGraphics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ConfigurationShared {
|
||||||
|
enum class CheckState;
|
||||||
|
}
|
||||||
|
|
||||||
class ConfigureGraphics : public QWidget {
|
class ConfigureGraphics : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -24,6 +28,14 @@ public:
|
||||||
|
|
||||||
void UpdateBackgroundColorButton(const QColor& color);
|
void UpdateBackgroundColorButton(const QColor& color);
|
||||||
|
|
||||||
|
void SetupPerGameUI();
|
||||||
|
|
||||||
|
ConfigurationShared::CheckState use_hw_renderer;
|
||||||
|
ConfigurationShared::CheckState use_hw_shader;
|
||||||
|
ConfigurationShared::CheckState separable_shader;
|
||||||
|
ConfigurationShared::CheckState shaders_accurate_mul;
|
||||||
|
ConfigurationShared::CheckState use_disk_shader_cache;
|
||||||
|
ConfigurationShared::CheckState use_vsync_new;
|
||||||
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
std::unique_ptr<Ui::ConfigureGraphics> ui;
|
||||||
QColor bg_color;
|
QColor bg_color;
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "citra_qt/configuration/configure_hotkeys.h"
|
#include "citra_qt/configuration/configure_hotkeys.h"
|
||||||
#include "citra_qt/hotkeys.h"
|
#include "citra_qt/hotkeys.h"
|
||||||
#include "citra_qt/util/sequence_dialog/sequence_dialog.h"
|
#include "citra_qt/util/sequence_dialog/sequence_dialog.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
#include "ui_configure_hotkeys.h"
|
#include "ui_configure_hotkeys.h"
|
||||||
|
|
||||||
ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
|
ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <QKeySequence>
|
#include <QKeySequence>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
|
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/udp/udp.h"
|
#include "input_common/udp/udp.h"
|
||||||
|
|
||||||
|
|
128
src/citra_qt/configuration/configure_per_game.cpp
Normal file
128
src/citra_qt/configuration/configure_per_game.cpp
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QString>
|
||||||
|
#include <fmt/format.h>
|
||||||
|
#include "citra_qt/configuration/config.h"
|
||||||
|
#include "citra_qt/configuration/configure_audio.h"
|
||||||
|
#include "citra_qt/configuration/configure_general.h"
|
||||||
|
#include "citra_qt/configuration/configure_graphics.h"
|
||||||
|
#include "citra_qt/configuration/configure_per_game.h"
|
||||||
|
#include "citra_qt/configuration/configure_system.h"
|
||||||
|
#include "citra_qt/util/util.h"
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/loader/loader.h"
|
||||||
|
#include "core/loader/smdh.h"
|
||||||
|
#include "ui_configure_per_game.h"
|
||||||
|
|
||||||
|
ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name,
|
||||||
|
Core::System& system_)
|
||||||
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()),
|
||||||
|
filename{file_name.toStdString()}, title_id{title_id_}, system{system_} {
|
||||||
|
const auto config_file_name = title_id == 0 ? filename : fmt::format("{:016X}", title_id);
|
||||||
|
game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig);
|
||||||
|
|
||||||
|
audio_tab = std::make_unique<ConfigureAudio>(this);
|
||||||
|
general_tab = std::make_unique<ConfigureGeneral>(this);
|
||||||
|
graphics_tab = std::make_unique<ConfigureGraphics>(this);
|
||||||
|
system_tab = std::make_unique<ConfigureSystem>(this);
|
||||||
|
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
ui->tabWidget->addTab(general_tab.get(), tr("General"));
|
||||||
|
ui->tabWidget->addTab(system_tab.get(), tr("System"));
|
||||||
|
ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
|
||||||
|
ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
|
||||||
|
|
||||||
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
|
setWindowTitle(tr("Properties"));
|
||||||
|
// remove Help question mark button from the title bar
|
||||||
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||||
|
|
||||||
|
scene = new QGraphicsScene;
|
||||||
|
ui->icon_view->setScene(scene);
|
||||||
|
|
||||||
|
if (system.IsPoweredOn()) {
|
||||||
|
QPushButton* apply_button = ui->buttonBox->addButton(QDialogButtonBox::Apply);
|
||||||
|
connect(apply_button, &QAbstractButton::clicked, this,
|
||||||
|
&ConfigurePerGame::HandleApplyButtonClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
LoadConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigurePerGame::~ConfigurePerGame() = default;
|
||||||
|
|
||||||
|
void ConfigurePerGame::ApplyConfiguration() {
|
||||||
|
general_tab->ApplyConfiguration();
|
||||||
|
system_tab->ApplyConfiguration();
|
||||||
|
graphics_tab->ApplyConfiguration();
|
||||||
|
audio_tab->ApplyConfiguration();
|
||||||
|
|
||||||
|
Settings::LogSettings();
|
||||||
|
|
||||||
|
game_config->Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurePerGame::changeEvent(QEvent* event) {
|
||||||
|
if (event->type() == QEvent::LanguageChange) {
|
||||||
|
RetranslateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog::changeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurePerGame::RetranslateUI() {
|
||||||
|
ui->retranslateUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurePerGame::HandleApplyButtonClicked() {
|
||||||
|
ApplyConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QPixmap GetQPixmapFromSMDH(std::vector<u8>& smdh_data) {
|
||||||
|
Loader::SMDH smdh;
|
||||||
|
memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH));
|
||||||
|
|
||||||
|
bool large = true;
|
||||||
|
std::vector<u16> icon_data = smdh.GetIcon(large);
|
||||||
|
const uchar* data = reinterpret_cast<const uchar*>(icon_data.data());
|
||||||
|
int size = large ? 48 : 24;
|
||||||
|
QImage icon(data, size, size, QImage::Format::Format_RGB16);
|
||||||
|
return QPixmap::fromImage(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurePerGame::LoadConfiguration() {
|
||||||
|
if (filename.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->display_title_id->setText(
|
||||||
|
QStringLiteral("%1").arg(title_id, 16, 16, QLatin1Char{'0'}).toUpper());
|
||||||
|
|
||||||
|
const auto loader = Loader::GetLoader(filename);
|
||||||
|
|
||||||
|
std::string title;
|
||||||
|
if (loader->ReadTitle(title) == Loader::ResultStatus::Success)
|
||||||
|
ui->display_name->setText(QString::fromStdString(title));
|
||||||
|
|
||||||
|
std::vector<u8> bytes;
|
||||||
|
if (loader->ReadIcon(bytes) == Loader::ResultStatus::Success) {
|
||||||
|
scene->clear();
|
||||||
|
|
||||||
|
QPixmap map = GetQPixmapFromSMDH(bytes);
|
||||||
|
scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(),
|
||||||
|
Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->display_filepath->setText(QString::fromStdString(filename));
|
||||||
|
|
||||||
|
ui->display_format->setText(
|
||||||
|
QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType())));
|
||||||
|
|
||||||
|
const auto valueText = ReadableByteSize(FileUtil::GetSize(filename));
|
||||||
|
ui->display_size->setText(valueText);
|
||||||
|
}
|
66
src/citra_qt/configuration/configure_per_game.h
Normal file
66
src/citra_qt/configuration/configure_per_game.h
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QList>
|
||||||
|
#include "citra_qt/configuration/config.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureAudio;
|
||||||
|
class ConfigureGeneral;
|
||||||
|
class ConfigureGraphics;
|
||||||
|
class ConfigureSystem;
|
||||||
|
|
||||||
|
class QGraphicsScene;
|
||||||
|
class QStandardItem;
|
||||||
|
class QStandardItemModel;
|
||||||
|
class QTreeView;
|
||||||
|
class QVBoxLayout;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ConfigurePerGame;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigurePerGame : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263
|
||||||
|
explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const QString& file_name,
|
||||||
|
Core::System& system_);
|
||||||
|
~ConfigurePerGame() override;
|
||||||
|
|
||||||
|
/// Loads all button configurations to settings file
|
||||||
|
void LoadConfiguration();
|
||||||
|
|
||||||
|
/// Save all button configurations to settings file
|
||||||
|
void ApplyConfiguration();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void changeEvent(QEvent* event) override;
|
||||||
|
void RetranslateUI();
|
||||||
|
|
||||||
|
void HandleApplyButtonClicked();
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::ConfigurePerGame> ui;
|
||||||
|
std::string filename;
|
||||||
|
u64 title_id;
|
||||||
|
|
||||||
|
QGraphicsScene* scene;
|
||||||
|
|
||||||
|
std::unique_ptr<Config> game_config;
|
||||||
|
|
||||||
|
Core::System& system;
|
||||||
|
|
||||||
|
std::unique_ptr<ConfigureAudio> audio_tab;
|
||||||
|
std::unique_ptr<ConfigureGeneral> general_tab;
|
||||||
|
std::unique_ptr<ConfigureGraphics> graphics_tab;
|
||||||
|
std::unique_ptr<ConfigureSystem> system_tab;
|
||||||
|
};
|
264
src/citra_qt/configuration/configure_per_game.ui
Normal file
264
src/citra_qt/configuration/configure_per_game.ui
Normal file
|
@ -0,0 +1,264 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ConfigurePerGame</class>
|
||||||
|
<widget class="QDialog" name="ConfigurePerGame">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>900</width>
|
||||||
|
<height>661</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>900</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Dialog</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="groupBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="title">
|
||||||
|
<string>Info</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QGraphicsView" name="icon_view">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>128</width>
|
||||||
|
<height>128</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>128</width>
|
||||||
|
<height>128</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="verticalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="interactive">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="label_6">
|
||||||
|
<property name="text">
|
||||||
|
<string>Size</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1">
|
||||||
|
<widget class="QLineEdit" name="display_filepath">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>160</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_5">
|
||||||
|
<property name="text">
|
||||||
|
<string>Format</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Name</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QLineEdit" name="display_size">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QLabel" name="label_7">
|
||||||
|
<property name="text">
|
||||||
|
<string>Filepath</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_4">
|
||||||
|
<property name="text">
|
||||||
|
<string>Title ID</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="display_title_id">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="display_name">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLineEdit" name="display_format">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="readOnly">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</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>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="VerticalLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>-1</number>
|
||||||
|
</property>
|
||||||
|
<property name="usesScrollButtons">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="documentMode">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="tabsClosable">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ConfigurePerGame</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>20</x>
|
||||||
|
<y>20</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>20</x>
|
||||||
|
<y>20</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>ConfigurePerGame</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>20</x>
|
||||||
|
<y>20</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>20</x>
|
||||||
|
<y>20</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
|
@ -6,8 +6,8 @@
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include "citra_qt/configuration/configure_storage.h"
|
#include "citra_qt/configuration/configure_storage.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "ui_configure_storage.h"
|
#include "ui_configure_storage.h"
|
||||||
|
|
||||||
ConfigureStorage::ConfigureStorage(QWidget* parent)
|
ConfigureStorage::ConfigureStorage(QWidget* parent)
|
||||||
|
@ -60,7 +60,7 @@ ConfigureStorage::ConfigureStorage(QWidget* parent)
|
||||||
ConfigureStorage::~ConfigureStorage() = default;
|
ConfigureStorage::~ConfigureStorage() = default;
|
||||||
|
|
||||||
void ConfigureStorage::SetConfiguration() {
|
void ConfigureStorage::SetConfiguration() {
|
||||||
ui->nand_group->setVisible(Settings::values.use_custom_storage);
|
ui->nand_group->setVisible(Settings::values.use_custom_storage.GetValue());
|
||||||
QString nand_path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
|
QString nand_path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
|
||||||
ui->nand_dir_path->setText(nand_path);
|
ui->nand_dir_path->setText(nand_path);
|
||||||
ui->open_nand_dir->setEnabled(!nand_path.isEmpty());
|
ui->open_nand_dir->setEnabled(!nand_path.isEmpty());
|
||||||
|
@ -71,8 +71,8 @@ void ConfigureStorage::SetConfiguration() {
|
||||||
ui->sdmc_dir_path->setText(sdmc_path);
|
ui->sdmc_dir_path->setText(sdmc_path);
|
||||||
ui->open_sdmc_dir->setEnabled(!sdmc_path.isEmpty());
|
ui->open_sdmc_dir->setEnabled(!sdmc_path.isEmpty());
|
||||||
|
|
||||||
ui->toggle_virtual_sd->setChecked(Settings::values.use_virtual_sd);
|
ui->toggle_virtual_sd->setChecked(Settings::values.use_virtual_sd.GetValue());
|
||||||
ui->toggle_custom_storage->setChecked(Settings::values.use_custom_storage);
|
ui->toggle_custom_storage->setChecked(Settings::values.use_custom_storage.GetValue());
|
||||||
|
|
||||||
ui->storage_group->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
ui->storage_group->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include "citra_qt/configuration/configuration_shared.h"
|
||||||
#include "citra_qt/configuration/configure_system.h"
|
#include "citra_qt/configuration/configure_system.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/service/cfg/cfg.h"
|
#include "core/hle/service/cfg/cfg.h"
|
||||||
#include "core/hle/service/ptm/ptm.h"
|
#include "core/hle/service/ptm/ptm.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "ui_configure_system.h"
|
#include "ui_configure_system.h"
|
||||||
|
|
||||||
static const std::array<int, 12> days_in_month = {{
|
static const std::array<int, 12> days_in_month = {{
|
||||||
|
@ -249,10 +249,14 @@ ConfigureSystem::ConfigureSystem(QWidget* parent)
|
||||||
// This scales across DPIs. (This value should be enough for "xxx%")
|
// This scales across DPIs. (This value should be enough for "xxx%")
|
||||||
ui->clock_display_label->setMinimumWidth(40);
|
ui->clock_display_label->setMinimumWidth(40);
|
||||||
|
|
||||||
connect(ui->slider_clock_speed, &QSlider::valueChanged, [&](int value) {
|
connect(ui->slider_clock_speed, &QSlider::valueChanged, this, [&](int value) {
|
||||||
ui->clock_display_label->setText(QStringLiteral("%1%").arg(SliderToSettings(value)));
|
ui->clock_display_label->setText(QStringLiteral("%1%").arg(SliderToSettings(value)));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ui->clock_speed_label->setVisible(Settings::IsConfiguringGlobal());
|
||||||
|
ui->clock_speed_combo->setVisible(!Settings::IsConfiguringGlobal());
|
||||||
|
|
||||||
|
SetupPerGameUI();
|
||||||
ConfigureTime();
|
ConfigureTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,12 +265,12 @@ ConfigureSystem::~ConfigureSystem() = default;
|
||||||
void ConfigureSystem::SetConfiguration() {
|
void ConfigureSystem::SetConfiguration() {
|
||||||
enabled = !Core::System::GetInstance().IsPoweredOn();
|
enabled = !Core::System::GetInstance().IsPoweredOn();
|
||||||
|
|
||||||
ui->combo_init_clock->setCurrentIndex(static_cast<u8>(Settings::values.init_clock));
|
ui->combo_init_clock->setCurrentIndex(static_cast<u8>(Settings::values.init_clock.GetValue()));
|
||||||
QDateTime date_time;
|
QDateTime date_time;
|
||||||
date_time.setTime_t(Settings::values.init_time);
|
date_time.setTime_t(Settings::values.init_time.GetValue());
|
||||||
ui->edit_init_time->setDateTime(date_time);
|
ui->edit_init_time->setDateTime(date_time);
|
||||||
|
|
||||||
long long init_time_offset = Settings::values.init_time_offset;
|
long long init_time_offset = Settings::values.init_time_offset.GetValue();
|
||||||
long long days_offset = init_time_offset / 86400;
|
long long days_offset = init_time_offset / 86400;
|
||||||
ui->edit_init_time_offset_days->setValue(days_offset);
|
ui->edit_init_time_offset_days->setValue(days_offset);
|
||||||
|
|
||||||
|
@ -287,20 +291,29 @@ void ConfigureSystem::SetConfiguration() {
|
||||||
ui->label_disable_info->hide();
|
ui->label_disable_info->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui->slider_clock_speed->setValue(SettingsToSlider(Settings::values.cpu_clock_percentage));
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
ui->clock_display_label->setText(
|
if (Settings::values.cpu_clock_percentage.UsingGlobal()) {
|
||||||
QStringLiteral("%1%").arg(Settings::values.cpu_clock_percentage));
|
ui->clock_speed_combo->setCurrentIndex(0);
|
||||||
|
ui->slider_clock_speed->setEnabled(false);
|
||||||
|
} else {
|
||||||
|
ui->clock_speed_combo->setCurrentIndex(1);
|
||||||
|
ui->slider_clock_speed->setEnabled(true);
|
||||||
|
}
|
||||||
|
ConfigurationShared::SetHighlight(ui->clock_speed_widget,
|
||||||
|
!Settings::values.cpu_clock_percentage.UsingGlobal());
|
||||||
|
}
|
||||||
|
|
||||||
ui->toggle_new_3ds->setChecked(Settings::values.is_new_3ds);
|
ui->slider_clock_speed->setValue(
|
||||||
|
SettingsToSlider(Settings::values.cpu_clock_percentage.GetValue()));
|
||||||
|
ui->clock_display_label->setText(
|
||||||
|
QStringLiteral("%1%").arg(Settings::values.cpu_clock_percentage.GetValue()));
|
||||||
|
ui->toggle_new_3ds->setChecked(Settings::values.is_new_3ds.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::ReadSystemSettings() {
|
void ConfigureSystem::ReadSystemSettings() {
|
||||||
// set username
|
// set username
|
||||||
username = cfg->GetUsername();
|
username = cfg->GetUsername();
|
||||||
// TODO(wwylele): Use this when we move to Qt 5.5
|
ui->edit_username->setText(QString::fromStdU16String(username));
|
||||||
// ui->edit_username->setText(QString::fromStdU16String(username));
|
|
||||||
ui->edit_username->setText(
|
|
||||||
QString::fromUtf16(reinterpret_cast<const ushort*>(username.data())));
|
|
||||||
|
|
||||||
// set birthday
|
// set birthday
|
||||||
std::tie(birthmonth, birthday) = cfg->GetBirthday();
|
std::tie(birthmonth, birthday) = cfg->GetBirthday();
|
||||||
|
@ -337,32 +350,29 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
// apply username
|
// apply username
|
||||||
// TODO(wwylele): Use this when we move to Qt 5.5
|
std::u16string new_username = ui->edit_username->text().toStdU16String();
|
||||||
// std::u16string new_username = ui->edit_username->text().toStdU16String();
|
|
||||||
std::u16string new_username(
|
|
||||||
reinterpret_cast<const char16_t*>(ui->edit_username->text().utf16()));
|
|
||||||
if (new_username != username) {
|
if (new_username != username) {
|
||||||
cfg->SetUsername(new_username);
|
cfg->SetUsername(new_username);
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply birthday
|
// apply birthday
|
||||||
int new_birthmonth = ui->combo_birthmonth->currentIndex() + 1;
|
s32 new_birthmonth = ui->combo_birthmonth->currentIndex() + 1;
|
||||||
int new_birthday = ui->combo_birthday->currentIndex() + 1;
|
s32 new_birthday = ui->combo_birthday->currentIndex() + 1;
|
||||||
if (birthmonth != new_birthmonth || birthday != new_birthday) {
|
if (birthmonth != new_birthmonth || birthday != new_birthday) {
|
||||||
cfg->SetBirthday(new_birthmonth, new_birthday);
|
cfg->SetBirthday(new_birthmonth, new_birthday);
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply language
|
// apply language
|
||||||
int new_language = ui->combo_language->currentIndex();
|
s32 new_language = ui->combo_language->currentIndex();
|
||||||
if (language_index != new_language) {
|
if (language_index != new_language) {
|
||||||
cfg->SetSystemLanguage(static_cast<Service::CFG::SystemLanguage>(new_language));
|
cfg->SetSystemLanguage(static_cast<Service::CFG::SystemLanguage>(new_language));
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply sound
|
// apply sound
|
||||||
int new_sound = ui->combo_sound->currentIndex();
|
s32 new_sound = ui->combo_sound->currentIndex();
|
||||||
if (sound_index != new_sound) {
|
if (sound_index != new_sound) {
|
||||||
cfg->SetSoundOutputMode(static_cast<Service::CFG::SoundOutputMode>(new_sound));
|
cfg->SetSoundOutputMode(static_cast<Service::CFG::SoundOutputMode>(new_sound));
|
||||||
modified = true;
|
modified = true;
|
||||||
|
@ -386,6 +396,9 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||||
cfg->UpdateConfigNANDSavegame();
|
cfg->UpdateConfigNANDSavegame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.is_new_3ds, ui->toggle_new_3ds,
|
||||||
|
is_new_3ds);
|
||||||
|
|
||||||
Settings::values.init_clock =
|
Settings::values.init_clock =
|
||||||
static_cast<Settings::InitClock>(ui->combo_init_clock->currentIndex());
|
static_cast<Settings::InitClock>(ui->combo_init_clock->currentIndex());
|
||||||
Settings::values.init_time = ui->edit_init_time->dateTime().toTime_t();
|
Settings::values.init_time = ui->edit_init_time->dateTime().toTime_t();
|
||||||
|
@ -398,11 +411,11 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::values.init_time_offset = time_offset_days + time_offset_time;
|
Settings::values.init_time_offset = time_offset_days + time_offset_time;
|
||||||
Settings::values.is_new_3ds = ui->toggle_new_3ds->isChecked();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::values.cpu_clock_percentage = SliderToSettings(ui->slider_clock_speed->value());
|
ConfigurationShared::ApplyPerGameSetting(
|
||||||
Settings::Apply();
|
&Settings::values.cpu_clock_percentage, ui->clock_speed_combo,
|
||||||
|
[this](s32) { return SliderToSettings(ui->slider_clock_speed->value()); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
||||||
|
@ -410,10 +423,10 @@ void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// store current day selection
|
// store current day selection
|
||||||
int birthday_index = ui->combo_birthday->currentIndex();
|
s32 birthday_index = ui->combo_birthday->currentIndex();
|
||||||
|
|
||||||
// get number of days in the new selected month
|
// get number of days in the new selected month
|
||||||
int days = days_in_month[birthmonth_index];
|
s32 days = days_in_month[birthmonth_index];
|
||||||
|
|
||||||
// if the selected day is out of range,
|
// if the selected day is out of range,
|
||||||
// reset it to 1st
|
// reset it to 1st
|
||||||
|
@ -422,7 +435,7 @@ void ConfigureSystem::UpdateBirthdayComboBox(int birthmonth_index) {
|
||||||
|
|
||||||
// update the day combo box
|
// update the day combo box
|
||||||
ui->combo_birthday->clear();
|
ui->combo_birthday->clear();
|
||||||
for (int i = 1; i <= days; ++i) {
|
for (s32 i = 1; i <= days; ++i) {
|
||||||
ui->combo_birthday->addItem(QString::number(i));
|
ui->combo_birthday->addItem(QString::number(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,15 +455,16 @@ void ConfigureSystem::ConfigureTime() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::UpdateInitTime(int init_clock) {
|
void ConfigureSystem::UpdateInitTime(int init_clock) {
|
||||||
|
const bool is_global = Settings::IsConfiguringGlobal();
|
||||||
const bool is_fixed_time =
|
const bool is_fixed_time =
|
||||||
static_cast<Settings::InitClock>(init_clock) == Settings::InitClock::FixedTime;
|
static_cast<Settings::InitClock>(init_clock) == Settings::InitClock::FixedTime;
|
||||||
|
|
||||||
ui->label_init_time->setVisible(is_fixed_time);
|
ui->label_init_time->setVisible(is_fixed_time && is_global);
|
||||||
ui->edit_init_time->setVisible(is_fixed_time);
|
ui->edit_init_time->setVisible(is_fixed_time && is_global);
|
||||||
|
|
||||||
ui->label_init_time_offset->setVisible(!is_fixed_time);
|
ui->label_init_time_offset->setVisible(!is_fixed_time && is_global);
|
||||||
ui->edit_init_time_offset_days->setVisible(!is_fixed_time);
|
ui->edit_init_time_offset_days->setVisible(!is_fixed_time && is_global);
|
||||||
ui->edit_init_time_offset_time->setVisible(!is_fixed_time);
|
ui->edit_init_time_offset_time->setVisible(!is_fixed_time && is_global);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureSystem::RefreshConsoleID() {
|
void ConfigureSystem::RefreshConsoleID() {
|
||||||
|
@ -475,3 +489,43 @@ void ConfigureSystem::RefreshConsoleID() {
|
||||||
void ConfigureSystem::RetranslateUI() {
|
void ConfigureSystem::RetranslateUI() {
|
||||||
ui->retranslateUi(this);
|
ui->retranslateUi(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigureSystem::SetupPerGameUI() {
|
||||||
|
// Block the global settings if a game is currently running that overrides them
|
||||||
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
|
ui->toggle_new_3ds->setEnabled(Settings::values.is_new_3ds.UsingGlobal());
|
||||||
|
ui->slider_clock_speed->setEnabled(Settings::values.cpu_clock_percentage.UsingGlobal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide most settings for now, we can implement them later
|
||||||
|
ui->label_username->setVisible(false);
|
||||||
|
ui->label_birthday->setVisible(false);
|
||||||
|
ui->label_init_clock->setVisible(false);
|
||||||
|
ui->label_init_time->setVisible(false);
|
||||||
|
ui->label_console_id->setVisible(false);
|
||||||
|
ui->label_sound->setVisible(false);
|
||||||
|
ui->label_language->setVisible(false);
|
||||||
|
ui->label_country->setVisible(false);
|
||||||
|
ui->label_play_coins->setVisible(false);
|
||||||
|
ui->edit_username->setVisible(false);
|
||||||
|
ui->spinBox_play_coins->setVisible(false);
|
||||||
|
ui->combo_birthday->setVisible(false);
|
||||||
|
ui->combo_birthmonth->setVisible(false);
|
||||||
|
ui->combo_init_clock->setVisible(false);
|
||||||
|
ui->combo_sound->setVisible(false);
|
||||||
|
ui->combo_language->setVisible(false);
|
||||||
|
ui->combo_country->setVisible(false);
|
||||||
|
ui->label_init_time_offset->setVisible(false);
|
||||||
|
ui->edit_init_time_offset_days->setVisible(false);
|
||||||
|
ui->edit_init_time_offset_time->setVisible(false);
|
||||||
|
ui->button_regenerate_console_id->setVisible(false);
|
||||||
|
|
||||||
|
connect(ui->clock_speed_combo, qOverload<int>(&QComboBox::activated), this, [this](int index) {
|
||||||
|
ui->slider_clock_speed->setEnabled(index == 1);
|
||||||
|
ConfigurationShared::SetHighlight(ui->clock_speed_widget, index == 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
ConfigurationShared::SetColoredTristate(ui->toggle_new_3ds, Settings::values.is_new_3ds,
|
||||||
|
is_new_3ds);
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@ namespace Ui {
|
||||||
class ConfigureSystem;
|
class ConfigureSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ConfigurationShared {
|
||||||
|
enum class CheckState;
|
||||||
|
}
|
||||||
|
|
||||||
namespace Service {
|
namespace Service {
|
||||||
namespace CFG {
|
namespace CFG {
|
||||||
class Module;
|
class Module;
|
||||||
|
@ -37,6 +41,9 @@ private:
|
||||||
void UpdateInitTime(int init_clock);
|
void UpdateInitTime(int init_clock);
|
||||||
void RefreshConsoleID();
|
void RefreshConsoleID();
|
||||||
|
|
||||||
|
void SetupPerGameUI();
|
||||||
|
|
||||||
|
ConfigurationShared::CheckState is_new_3ds;
|
||||||
std::unique_ptr<Ui::ConfigureSystem> ui;
|
std::unique_ptr<Ui::ConfigureSystem> ui;
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>520</width>
|
<width>525</width>
|
||||||
<height>564</height>
|
<height>619</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -344,54 +344,77 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="group_advanced">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Advanced</string>
|
<string>Advanced</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_2">
|
<layout class="QGridLayout" name="gridLayout_2">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label_3">
|
<widget class="QWidget" name="clock_speed_widget" native="true">
|
||||||
<property name="text">
|
<layout class="QHBoxLayout" name="clock_speed_layout">
|
||||||
<string>CPU Clock Speed</string>
|
<property name="spacing">
|
||||||
</property>
|
<number>7</number>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<item>
|
||||||
<item row="0" column="2">
|
<widget class="QComboBox" name="clock_speed_combo">
|
||||||
<widget class="QSlider" name="slider_clock_speed">
|
<item>
|
||||||
<property name="toolTip">
|
<property name="text">
|
||||||
<string><html><body>Changes the emulated CPU clock frequency.<br>Underclocking can increase performance but may cause the game to freeze.<br>Overclocking may reduce in game lag but also might cause freezes</body></html></string>
|
<string>Use global clock speed</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="minimum">
|
</item>
|
||||||
<number>0</number>
|
<item>
|
||||||
</property>
|
<property name="text">
|
||||||
<property name="maximum">
|
<string>Set clock speed:</string>
|
||||||
<number>79</number>
|
</property>
|
||||||
</property>
|
</item>
|
||||||
<property name="singleStep">
|
</widget>
|
||||||
<number>5</number>
|
</item>
|
||||||
</property>
|
<item>
|
||||||
<property name="pageStep">
|
<widget class="QLabel" name="clock_speed_label">
|
||||||
<number>15</number>
|
<property name="text">
|
||||||
</property>
|
<string>CPU Clock Speed</string>
|
||||||
<property name="value">
|
</property>
|
||||||
<number>25</number>
|
</widget>
|
||||||
</property>
|
</item>
|
||||||
<property name="orientation">
|
<item>
|
||||||
<enum>Qt::Horizontal</enum>
|
<widget class="QSlider" name="slider_clock_speed">
|
||||||
</property>
|
<property name="toolTip">
|
||||||
<property name="tickPosition">
|
<string><html><body>Changes the emulated CPU clock frequency.<br>Underclocking can increase performance but may cause the game to freeze.<br>Overclocking may reduce in game lag but also might cause freezes</body></html></string>
|
||||||
<enum>QSlider::TicksBelow</enum>
|
</property>
|
||||||
</property>
|
<property name="minimum">
|
||||||
</widget>
|
<number>0</number>
|
||||||
</item>
|
</property>
|
||||||
<item row="0" column="1">
|
<property name="maximum">
|
||||||
<widget class="QLabel" name="clock_display_label">
|
<number>79</number>
|
||||||
<property name="text">
|
</property>
|
||||||
<string/>
|
<property name="singleStep">
|
||||||
</property>
|
<number>5</number>
|
||||||
<property name="alignment">
|
</property>
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<property name="pageStep">
|
||||||
</property>
|
<number>15</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>25</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="tickPosition">
|
||||||
|
<enum>QSlider::TicksBelow</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="clock_display_label">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="alignment">
|
||||||
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -449,7 +472,6 @@
|
||||||
<tabstop>edit_init_time</tabstop>
|
<tabstop>edit_init_time</tabstop>
|
||||||
<tabstop>spinBox_play_coins</tabstop>
|
<tabstop>spinBox_play_coins</tabstop>
|
||||||
<tabstop>button_regenerate_console_id</tabstop>
|
<tabstop>button_regenerate_console_id</tabstop>
|
||||||
<tabstop>slider_clock_speed</tabstop>
|
|
||||||
</tabstops>
|
</tabstops>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
class QItemSelection;
|
class QItemSelection;
|
||||||
class QModelIndex;
|
class QModelIndex;
|
||||||
|
|
|
@ -46,12 +46,14 @@ void ConfigureUi::SetConfiguration() {
|
||||||
ui->language_combobox->setCurrentIndex(
|
ui->language_combobox->setCurrentIndex(
|
||||||
ui->language_combobox->findData(UISettings::values.language));
|
ui->language_combobox->findData(UISettings::values.language));
|
||||||
ui->icon_size_combobox->setCurrentIndex(
|
ui->icon_size_combobox->setCurrentIndex(
|
||||||
static_cast<int>(UISettings::values.game_list_icon_size));
|
static_cast<int>(UISettings::values.game_list_icon_size.GetValue()));
|
||||||
ui->row_1_text_combobox->setCurrentIndex(static_cast<int>(UISettings::values.game_list_row_1));
|
ui->row_1_text_combobox->setCurrentIndex(
|
||||||
ui->row_2_text_combobox->setCurrentIndex(static_cast<int>(UISettings::values.game_list_row_2) +
|
static_cast<int>(UISettings::values.game_list_row_1.GetValue()));
|
||||||
1);
|
ui->row_2_text_combobox->setCurrentIndex(
|
||||||
ui->toggle_hide_no_icon->setChecked(UISettings::values.game_list_hide_no_icon);
|
static_cast<int>(UISettings::values.game_list_row_2.GetValue()) + 1);
|
||||||
ui->toggle_single_line_mode->setChecked(UISettings::values.game_list_single_line_mode);
|
ui->toggle_hide_no_icon->setChecked(UISettings::values.game_list_hide_no_icon.GetValue());
|
||||||
|
ui->toggle_single_line_mode->setChecked(
|
||||||
|
UISettings::values.game_list_single_line_mode.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureUi::ApplyConfiguration() {
|
void ConfigureUi::ApplyConfiguration() {
|
||||||
|
|
|
@ -87,7 +87,7 @@ void ConfigureWeb::SetConfiguration() {
|
||||||
tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
|
tr("Telemetry ID: 0x%1").arg(QString::number(Core::GetTelemetryId(), 16).toUpper()));
|
||||||
user_verified = true;
|
user_verified = true;
|
||||||
|
|
||||||
ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence);
|
ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureWeb::ApplyConfiguration() {
|
void ConfigureWeb::ApplyConfiguration() {
|
||||||
|
|
|
@ -15,10 +15,10 @@
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
void ToggleConsole() {
|
void ToggleConsole() {
|
||||||
static bool console_shown = false;
|
static bool console_shown = false;
|
||||||
if (console_shown == UISettings::values.show_console) {
|
if (console_shown == UISettings::values.show_console.GetValue()) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
console_shown = UISettings::values.show_console;
|
console_shown = UISettings::values.show_console.GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <QLayout>
|
#include <QLayout>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include "citra_qt/debugger/lle_service_modules.h"
|
#include "citra_qt/debugger/lle_service_modules.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
LLEServiceModulesWidget::LLEServiceModulesWidget(QWidget* parent)
|
LLEServiceModulesWidget::LLEServiceModulesWidget(QWidget* parent)
|
||||||
: QDockWidget(tr("Toggle LLE Service Modules"), parent) {
|
: QDockWidget(tr("Toggle LLE Service Modules"), parent) {
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "citra_qt/util/util.h"
|
#include "citra_qt/util/util.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/hle/kernel/event.h"
|
#include "core/hle/kernel/event.h"
|
||||||
#include "core/hle/kernel/mutex.h"
|
#include "core/hle/kernel/mutex.h"
|
||||||
#include "core/hle/kernel/semaphore.h"
|
#include "core/hle/kernel/semaphore.h"
|
||||||
#include "core/hle/kernel/thread.h"
|
#include "core/hle/kernel/thread.h"
|
||||||
#include "core/hle/kernel/timer.h"
|
#include "core/hle/kernel/timer.h"
|
||||||
#include "core/hle/kernel/wait_object.h"
|
#include "core/hle/kernel/wait_object.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "citra_qt/dumping/dumping_dialog.h"
|
#include "citra_qt/dumping/dumping_dialog.h"
|
||||||
#include "citra_qt/dumping/options_dialog.h"
|
#include "citra_qt/dumping/options_dialog.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
#include "ui_dumping_dialog.h"
|
#include "ui_dumping_dialog.h"
|
||||||
|
|
||||||
DumpingDialog::DumpingDialog(QWidget* parent)
|
DumpingDialog::DumpingDialog(QWidget* parent)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QDir>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
@ -28,9 +29,11 @@
|
||||||
#include "citra_qt/main.h"
|
#include "citra_qt/main.h"
|
||||||
#include "citra_qt/uisettings.h"
|
#include "citra_qt/uisettings.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/file_sys/archive_extsavedata.h"
|
#include "core/file_sys/archive_extsavedata.h"
|
||||||
#include "core/file_sys/archive_source_sd_savedata.h"
|
#include "core/file_sys/archive_source_sd_savedata.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/fs/archive.h"
|
||||||
|
#include "qcursor.h"
|
||||||
|
|
||||||
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent)
|
GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent)
|
||||||
: QObject(parent), gamelist{gamelist} {}
|
: QObject(parent), gamelist{gamelist} {}
|
||||||
|
@ -462,9 +465,20 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
|
context_menu.exec(tree_view->viewport()->mapToGlobal(menu_location));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ForEachOpenGLCacheFile(u64 program_id, auto func) {
|
||||||
|
for (const std::string_view cache_type : {"separable", "conventional"}) {
|
||||||
|
const std::string path = fmt::format("{}opengl/precompiled/{}/{:016X}.bin",
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir),
|
||||||
|
cache_type, program_id);
|
||||||
|
QFile file{QString::fromStdString(path)};
|
||||||
|
func(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 program_id,
|
void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 program_id,
|
||||||
u64 extdata_id) {
|
u64 extdata_id) {
|
||||||
QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
|
QAction* open_save_location = context_menu.addAction(tr("Open Save Data Location"));
|
||||||
|
@ -475,19 +489,32 @@ void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 progra
|
||||||
QAction* open_texture_load_location =
|
QAction* open_texture_load_location =
|
||||||
context_menu.addAction(tr("Open Custom Texture Location"));
|
context_menu.addAction(tr("Open Custom Texture Location"));
|
||||||
QAction* open_mods_location = context_menu.addAction(tr("Open Mods Location"));
|
QAction* open_mods_location = context_menu.addAction(tr("Open Mods Location"));
|
||||||
|
QAction* open_dlc_location = context_menu.addAction(tr("Open DLC Data Location"));
|
||||||
|
QMenu* shader_menu = context_menu.addMenu(tr("Disk Shader Cache"));
|
||||||
QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS"));
|
QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS"));
|
||||||
QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry"));
|
QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry"));
|
||||||
|
context_menu.addSeparator();
|
||||||
|
QAction* properties = context_menu.addAction(tr("Properties"));
|
||||||
|
|
||||||
|
QAction* open_shader_cache_location = shader_menu->addAction(tr("Open Shader Cache Location"));
|
||||||
|
shader_menu->addSeparator();
|
||||||
|
QAction* delete_opengl_disk_shader_cache =
|
||||||
|
shader_menu->addAction(tr("Delete OpenGL Shader Cache"));
|
||||||
|
|
||||||
const bool is_application =
|
const bool is_application =
|
||||||
0x0004000000000000 <= program_id && program_id <= 0x00040000FFFFFFFF;
|
0x0004000000000000 <= program_id && program_id <= 0x00040000FFFFFFFF;
|
||||||
|
|
||||||
|
bool opengl_cache_exists = false;
|
||||||
|
ForEachOpenGLCacheFile(
|
||||||
|
program_id, [&opengl_cache_exists](QFile& file) { opengl_cache_exists |= file.exists(); });
|
||||||
|
|
||||||
std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);
|
std::string sdmc_dir = FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir);
|
||||||
open_save_location->setVisible(
|
open_save_location->setEnabled(
|
||||||
is_application && FileUtil::Exists(FileSys::ArchiveSource_SDSaveData::GetSaveDataPathFor(
|
is_application && FileUtil::Exists(FileSys::ArchiveSource_SDSaveData::GetSaveDataPathFor(
|
||||||
sdmc_dir, program_id)));
|
sdmc_dir, program_id)));
|
||||||
|
|
||||||
if (extdata_id) {
|
if (extdata_id) {
|
||||||
open_extdata_location->setVisible(
|
open_extdata_location->setEnabled(
|
||||||
is_application &&
|
is_application &&
|
||||||
FileUtil::Exists(FileSys::GetExtDataPathFromId(sdmc_dir, extdata_id)));
|
FileUtil::Exists(FileSys::GetExtDataPathFromId(sdmc_dir, extdata_id)));
|
||||||
} else {
|
} else {
|
||||||
|
@ -495,18 +522,20 @@ void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 progra
|
||||||
}
|
}
|
||||||
|
|
||||||
auto media_type = Service::AM::GetTitleMediaType(program_id);
|
auto media_type = Service::AM::GetTitleMediaType(program_id);
|
||||||
open_application_location->setVisible(path.toStdString() ==
|
open_application_location->setEnabled(path.toStdString() ==
|
||||||
Service::AM::GetTitleContentPath(media_type, program_id));
|
Service::AM::GetTitleContentPath(media_type, program_id));
|
||||||
open_update_location->setVisible(
|
open_update_location->setEnabled(
|
||||||
is_application && FileUtil::Exists(Service::AM::GetTitlePath(Service::FS::MediaType::SDMC,
|
is_application && FileUtil::Exists(Service::AM::GetTitlePath(Service::FS::MediaType::SDMC,
|
||||||
program_id + 0xe00000000) +
|
program_id + 0xe00000000) +
|
||||||
"content/"));
|
"content/"));
|
||||||
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
|
||||||
|
|
||||||
open_texture_dump_location->setVisible(is_application);
|
open_texture_dump_location->setEnabled(is_application);
|
||||||
open_texture_load_location->setVisible(is_application);
|
open_texture_load_location->setEnabled(is_application);
|
||||||
open_mods_location->setVisible(is_application);
|
open_mods_location->setEnabled(is_application);
|
||||||
dump_romfs->setVisible(is_application);
|
open_dlc_location->setEnabled(is_application);
|
||||||
|
dump_romfs->setEnabled(is_application);
|
||||||
|
delete_opengl_disk_shader_cache->setEnabled(opengl_cache_exists);
|
||||||
|
|
||||||
navigate_to_gamedb_entry->setVisible(it != compatibility_list.end());
|
navigate_to_gamedb_entry->setVisible(it != compatibility_list.end());
|
||||||
|
|
||||||
|
@ -543,11 +572,32 @@ void GameList::AddGamePopup(QMenu& context_menu, const QString& path, u64 progra
|
||||||
emit OpenFolderRequested(program_id, GameListOpenTarget::MODS);
|
emit OpenFolderRequested(program_id, GameListOpenTarget::MODS);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
connect(open_dlc_location, &QAction::triggered, this, [this, program_id] {
|
||||||
|
const u64 trimmed_id = program_id & 0xFFFFFFF;
|
||||||
|
const std::string dlc_path =
|
||||||
|
fmt::format("{}Nintendo 3DS/00000000000000000000000000000000/"
|
||||||
|
"00000000000000000000000000000000/title/0004008c/{:08x}/content/",
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), trimmed_id);
|
||||||
|
fmt::print("DLC path {}\n", dlc_path);
|
||||||
|
if (FileUtil::CreateFullPath(dlc_path)) {
|
||||||
|
emit OpenFolderRequested(trimmed_id, GameListOpenTarget::DLC_DATA);
|
||||||
|
}
|
||||||
|
});
|
||||||
connect(dump_romfs, &QAction::triggered, this,
|
connect(dump_romfs, &QAction::triggered, this,
|
||||||
[this, path, program_id] { emit DumpRomFSRequested(path, program_id); });
|
[this, path, program_id] { emit DumpRomFSRequested(path, program_id); });
|
||||||
connect(navigate_to_gamedb_entry, &QAction::triggered, this, [this, program_id]() {
|
connect(navigate_to_gamedb_entry, &QAction::triggered, this, [this, program_id]() {
|
||||||
emit NavigateToGamedbEntryRequested(program_id, compatibility_list);
|
emit NavigateToGamedbEntryRequested(program_id, compatibility_list);
|
||||||
});
|
});
|
||||||
|
connect(properties, &QAction::triggered, this,
|
||||||
|
[this, path]() { emit OpenPerGameGeneralRequested(path); });
|
||||||
|
connect(open_shader_cache_location, &QAction::triggered, this, [this, program_id] {
|
||||||
|
if (FileUtil::CreateFullPath(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir))) {
|
||||||
|
emit OpenFolderRequested(program_id, GameListOpenTarget::SHADER_CACHE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
connect(delete_opengl_disk_shader_cache, &QAction::triggered, this, [program_id] {
|
||||||
|
ForEachOpenGLCacheFile(program_id, [](QFile& file) { file.remove(); });
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
void GameList::AddCustomDirPopup(QMenu& context_menu, QModelIndex selected) {
|
void GameList::AddCustomDirPopup(QMenu& context_menu, QModelIndex selected) {
|
||||||
|
|
|
@ -37,6 +37,8 @@ enum class GameListOpenTarget {
|
||||||
TEXTURE_DUMP = 4,
|
TEXTURE_DUMP = 4,
|
||||||
TEXTURE_LOAD = 5,
|
TEXTURE_LOAD = 5,
|
||||||
MODS = 6,
|
MODS = 6,
|
||||||
|
DLC_DATA = 7,
|
||||||
|
SHADER_CACHE = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
class GameList : public QWidget {
|
class GameList : public QWidget {
|
||||||
|
@ -82,6 +84,7 @@ signals:
|
||||||
void OpenFolderRequested(u64 program_id, GameListOpenTarget target);
|
void OpenFolderRequested(u64 program_id, GameListOpenTarget target);
|
||||||
void NavigateToGamedbEntryRequested(u64 program_id,
|
void NavigateToGamedbEntryRequested(u64 program_id,
|
||||||
const CompatibilityList& compatibility_list);
|
const CompatibilityList& compatibility_list);
|
||||||
|
void OpenPerGameGeneralRequested(const QString file);
|
||||||
void DumpRomFSRequested(QString game_path, u64 program_id);
|
void DumpRomFSRequested(QString game_path, u64 program_id);
|
||||||
void OpenDirectory(const QString& directory);
|
void OpenDirectory(const QString& directory);
|
||||||
void AddDirectory();
|
void AddDirectory();
|
||||||
|
|
|
@ -160,17 +160,19 @@ public:
|
||||||
setData(qulonglong(program_id), ProgramIdRole);
|
setData(qulonglong(program_id), ProgramIdRole);
|
||||||
setData(qulonglong(extdata_id), ExtdataIdRole);
|
setData(qulonglong(extdata_id), ExtdataIdRole);
|
||||||
|
|
||||||
if (UISettings::values.game_list_icon_size == UISettings::GameListIconSize::NoIcon) {
|
if (UISettings::values.game_list_icon_size.GetValue() ==
|
||||||
|
UISettings::GameListIconSize::NoIcon) {
|
||||||
// Do not display icons
|
// Do not display icons
|
||||||
setData(QPixmap(), Qt::DecorationRole);
|
setData(QPixmap(), Qt::DecorationRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool large =
|
bool large = UISettings::values.game_list_icon_size.GetValue() ==
|
||||||
UISettings::values.game_list_icon_size == UISettings::GameListIconSize::LargeIcon;
|
UISettings::GameListIconSize::LargeIcon;
|
||||||
|
|
||||||
if (!Loader::IsValidSMDH(smdh_data)) {
|
if (!Loader::IsValidSMDH(smdh_data)) {
|
||||||
// SMDH is not valid, set a default icon
|
// SMDH is not valid, set a default icon
|
||||||
if (UISettings::values.game_list_icon_size != UISettings::GameListIconSize::NoIcon)
|
if (UISettings::values.game_list_icon_size.GetValue() !=
|
||||||
|
UISettings::GameListIconSize::NoIcon)
|
||||||
setData(GetDefaultIcon(large), Qt::DecorationRole);
|
setData(GetDefaultIcon(large), Qt::DecorationRole);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +181,8 @@ public:
|
||||||
memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH));
|
memcpy(&smdh, smdh_data.data(), sizeof(Loader::SMDH));
|
||||||
|
|
||||||
// Get icon from SMDH
|
// Get icon from SMDH
|
||||||
if (UISettings::values.game_list_icon_size != UISettings::GameListIconSize::NoIcon) {
|
if (UISettings::values.game_list_icon_size.GetValue() !=
|
||||||
|
UISettings::GameListIconSize::NoIcon) {
|
||||||
setData(GetQPixmapFromSMDH(smdh, large), Qt::DecorationRole);
|
setData(GetQPixmapFromSMDH(smdh, large), Qt::DecorationRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,16 +214,17 @@ public:
|
||||||
QString::fromStdString(fmt::format("{:016X}", data(ProgramIdRole).toULongLong()))},
|
QString::fromStdString(fmt::format("{:016X}", data(ProgramIdRole).toULongLong()))},
|
||||||
};
|
};
|
||||||
|
|
||||||
const QString& row1 = display_texts.at(UISettings::values.game_list_row_1).simplified();
|
const QString& row1 =
|
||||||
|
display_texts.at(UISettings::values.game_list_row_1.GetValue()).simplified();
|
||||||
|
|
||||||
if (role == SortRole)
|
if (role == SortRole)
|
||||||
return row1.toLower();
|
return row1.toLower();
|
||||||
|
|
||||||
QString row2;
|
QString row2;
|
||||||
auto row_2_id = UISettings::values.game_list_row_2;
|
const auto row_2_id = UISettings::values.game_list_row_2.GetValue();
|
||||||
if (row_2_id != UISettings::GameListText::NoText) {
|
if (row_2_id != UISettings::GameListText::NoText) {
|
||||||
if (!row1.isEmpty()) {
|
if (!row1.isEmpty()) {
|
||||||
row2 = UISettings::values.game_list_single_line_mode
|
row2 = UISettings::values.game_list_single_line_mode.GetValue()
|
||||||
? QStringLiteral(" ")
|
? QStringLiteral(" ")
|
||||||
: QStringLiteral("\n ");
|
: QStringLiteral("\n ");
|
||||||
}
|
}
|
||||||
|
@ -355,7 +359,7 @@ public:
|
||||||
UISettings::GameDir* game_dir = &directory;
|
UISettings::GameDir* game_dir = &directory;
|
||||||
setData(QVariant(UISettings::values.game_dirs.indexOf(directory)), GameDirRole);
|
setData(QVariant(UISettings::values.game_dirs.indexOf(directory)), GameDirRole);
|
||||||
|
|
||||||
const int icon_size = IconSizes.at(UISettings::values.game_list_icon_size);
|
const int icon_size = IconSizes.at(UISettings::values.game_list_icon_size.GetValue());
|
||||||
switch (dir_type) {
|
switch (dir_type) {
|
||||||
case GameListItemType::InstalledDir:
|
case GameListItemType::InstalledDir:
|
||||||
setData(QIcon::fromTheme(QStringLiteral("sd_card")).pixmap(icon_size),
|
setData(QIcon::fromTheme(QStringLiteral("sd_card")).pixmap(icon_size),
|
||||||
|
@ -398,7 +402,7 @@ public:
|
||||||
explicit GameListAddDir() {
|
explicit GameListAddDir() {
|
||||||
setData(type(), TypeRole);
|
setData(type(), TypeRole);
|
||||||
|
|
||||||
int icon_size = IconSizes.at(UISettings::values.game_list_icon_size);
|
int icon_size = IconSizes.at(UISettings::values.game_list_icon_size.GetValue());
|
||||||
setData(QIcon::fromTheme(QStringLiteral("plus")).pixmap(icon_size), Qt::DecorationRole);
|
setData(QIcon::fromTheme(QStringLiteral("plus")).pixmap(icon_size), Qt::DecorationRole);
|
||||||
setData(QObject::tr("Add New Game Directory"), Qt::DisplayRole);
|
setData(QObject::tr("Add New Game Directory"), Qt::DisplayRole);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <clocale>
|
#include <clocale>
|
||||||
|
#include <filesystem>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
@ -34,6 +35,7 @@
|
||||||
#include "citra_qt/compatibility_list.h"
|
#include "citra_qt/compatibility_list.h"
|
||||||
#include "citra_qt/configuration/config.h"
|
#include "citra_qt/configuration/config.h"
|
||||||
#include "citra_qt/configuration/configure_dialog.h"
|
#include "citra_qt/configuration/configure_dialog.h"
|
||||||
|
#include "citra_qt/configuration/configure_per_game.h"
|
||||||
#include "citra_qt/debugger/console.h"
|
#include "citra_qt/debugger/console.h"
|
||||||
#include "citra_qt/debugger/graphics/graphics.h"
|
#include "citra_qt/debugger/graphics/graphics.h"
|
||||||
#include "citra_qt/debugger/graphics/graphics_breakpoints.h"
|
#include "citra_qt/debugger/graphics/graphics_breakpoints.h"
|
||||||
|
@ -70,9 +72,11 @@
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
|
#include "common/string_util.h"
|
||||||
#ifdef ARCHITECTURE_x86_64
|
#ifdef ARCHITECTURE_x86_64
|
||||||
#include "common/x64/cpu_detect.h"
|
#include "common/x64/cpu_detect.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/dumping/backend.h"
|
#include "core/dumping/backend.h"
|
||||||
#include "core/file_sys/archive_extsavedata.h"
|
#include "core/file_sys/archive_extsavedata.h"
|
||||||
|
@ -85,7 +89,6 @@
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "core/savestate.h"
|
#include "core/savestate.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "game_list_p.h"
|
#include "game_list_p.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "network/network_settings.h"
|
#include "network/network_settings.h"
|
||||||
|
@ -124,11 +127,13 @@ enum class CalloutFlag : uint32_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
void GMainWindow::ShowTelemetryCallout() {
|
void GMainWindow::ShowTelemetryCallout() {
|
||||||
if (UISettings::values.callout_flags & static_cast<uint32_t>(CalloutFlag::Telemetry)) {
|
if (UISettings::values.callout_flags.GetValue() &
|
||||||
|
static_cast<uint32_t>(CalloutFlag::Telemetry)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UISettings::values.callout_flags |= static_cast<uint32_t>(CalloutFlag::Telemetry);
|
UISettings::values.callout_flags =
|
||||||
|
UISettings::values.callout_flags.GetValue() | static_cast<uint32_t>(CalloutFlag::Telemetry);
|
||||||
const QString telemetry_message =
|
const QString telemetry_message =
|
||||||
tr("<a href='https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/'>Anonymous "
|
tr("<a href='https://citra-emu.org/entry/telemetry-and-why-thats-a-good-thing/'>Anonymous "
|
||||||
"data is collected</a> to help improve Citra. "
|
"data is collected</a> to help improve Citra. "
|
||||||
|
@ -143,7 +148,7 @@ const int GMainWindow::max_recent_files_item;
|
||||||
|
|
||||||
static void InitializeLogging() {
|
static void InitializeLogging() {
|
||||||
Log::Filter log_filter;
|
Log::Filter log_filter;
|
||||||
log_filter.ParseFilterString(Settings::values.log_filter);
|
log_filter.ParseFilterString(Settings::values.log_filter.GetValue());
|
||||||
Log::SetGlobalFilter(log_filter);
|
Log::SetGlobalFilter(log_filter);
|
||||||
|
|
||||||
const std::string& log_dir = FileUtil::GetUserPath(FileUtil::UserPath::LogDir);
|
const std::string& log_dir = FileUtil::GetUserPath(FileUtil::UserPath::LogDir);
|
||||||
|
@ -175,7 +180,7 @@ GMainWindow::GMainWindow()
|
||||||
default_theme_paths = QIcon::themeSearchPaths();
|
default_theme_paths = QIcon::themeSearchPaths();
|
||||||
UpdateUITheme();
|
UpdateUITheme();
|
||||||
|
|
||||||
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue());
|
||||||
discord_rpc->Update();
|
discord_rpc->Update();
|
||||||
|
|
||||||
Network::Init();
|
Network::Init();
|
||||||
|
@ -556,8 +561,7 @@ void GMainWindow::InitializeHotkeys() {
|
||||||
});
|
});
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Alternate Speed"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Alternate Speed"), this),
|
||||||
&QShortcut::activated, this, [&] {
|
&QShortcut::activated, this, [&] {
|
||||||
Settings::values.use_frame_limit_alternate =
|
Settings::values.frame_limit.SetGlobal(!Settings::values.frame_limit.UsingGlobal());
|
||||||
!Settings::values.use_frame_limit_alternate;
|
|
||||||
UpdateStatusBar();
|
UpdateStatusBar();
|
||||||
});
|
});
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Texture Dumping"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Texture Dumping"), this),
|
||||||
|
@ -568,42 +572,25 @@ void GMainWindow::InitializeHotkeys() {
|
||||||
static constexpr u16 SPEED_LIMIT_STEP = 5;
|
static constexpr u16 SPEED_LIMIT_STEP = 5;
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this),
|
||||||
&QShortcut::activated, this, [&] {
|
&QShortcut::activated, this, [&] {
|
||||||
if (Settings::values.use_frame_limit_alternate) {
|
if (Settings::values.frame_limit.GetValue() == 0) {
|
||||||
if (Settings::values.frame_limit_alternate == 0) {
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (Settings::values.frame_limit.GetValue() < 995 - SPEED_LIMIT_STEP) {
|
||||||
if (Settings::values.frame_limit_alternate < 995 - SPEED_LIMIT_STEP) {
|
Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() +
|
||||||
Settings::values.frame_limit_alternate += SPEED_LIMIT_STEP;
|
SPEED_LIMIT_STEP);
|
||||||
} else {
|
|
||||||
Settings::values.frame_limit_alternate = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (Settings::values.frame_limit == 0) {
|
Settings::values.frame_limit = 0;
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Settings::values.frame_limit < 995 - SPEED_LIMIT_STEP) {
|
|
||||||
Settings::values.frame_limit += SPEED_LIMIT_STEP;
|
|
||||||
} else {
|
|
||||||
Settings::values.frame_limit = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
UpdateStatusBar();
|
UpdateStatusBar();
|
||||||
});
|
});
|
||||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this),
|
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this),
|
||||||
&QShortcut::activated, this, [&] {
|
&QShortcut::activated, this, [&] {
|
||||||
if (Settings::values.use_frame_limit_alternate) {
|
if (Settings::values.frame_limit.GetValue() == 0) {
|
||||||
if (Settings::values.frame_limit_alternate == 0) {
|
Settings::values.frame_limit = 995;
|
||||||
Settings::values.frame_limit_alternate = 995;
|
} else if (Settings::values.frame_limit.GetValue() > SPEED_LIMIT_STEP) {
|
||||||
} else if (Settings::values.frame_limit_alternate > SPEED_LIMIT_STEP) {
|
Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() -
|
||||||
Settings::values.frame_limit_alternate -= SPEED_LIMIT_STEP;
|
SPEED_LIMIT_STEP);
|
||||||
}
|
UpdateStatusBar();
|
||||||
} else {
|
|
||||||
if (Settings::values.frame_limit == 0) {
|
|
||||||
Settings::values.frame_limit = 995;
|
|
||||||
} else if (Settings::values.frame_limit > SPEED_LIMIT_STEP) {
|
|
||||||
Settings::values.frame_limit -= SPEED_LIMIT_STEP;
|
|
||||||
UpdateStatusBar();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
UpdateStatusBar();
|
UpdateStatusBar();
|
||||||
});
|
});
|
||||||
|
@ -663,25 +650,26 @@ void GMainWindow::RestoreUIState() {
|
||||||
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
|
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
|
||||||
#if MICROPROFILE_ENABLED
|
#if MICROPROFILE_ENABLED
|
||||||
microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry);
|
microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry);
|
||||||
microProfileDialog->setVisible(UISettings::values.microprofile_visible);
|
microProfileDialog->setVisible(UISettings::values.microprofile_visible.GetValue());
|
||||||
#endif
|
#endif
|
||||||
ui->action_Cheats->setEnabled(false);
|
ui->action_Cheats->setEnabled(false);
|
||||||
|
|
||||||
game_list->LoadInterfaceLayout();
|
game_list->LoadInterfaceLayout();
|
||||||
|
|
||||||
ui->action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode);
|
ui->action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode.GetValue());
|
||||||
ToggleWindowMode();
|
ToggleWindowMode();
|
||||||
|
|
||||||
ui->action_Fullscreen->setChecked(UISettings::values.fullscreen);
|
ui->action_Fullscreen->setChecked(UISettings::values.fullscreen.GetValue());
|
||||||
SyncMenuUISettings();
|
SyncMenuUISettings();
|
||||||
|
|
||||||
ui->action_Display_Dock_Widget_Headers->setChecked(UISettings::values.display_titlebar);
|
ui->action_Display_Dock_Widget_Headers->setChecked(
|
||||||
|
UISettings::values.display_titlebar.GetValue());
|
||||||
OnDisplayTitleBars(ui->action_Display_Dock_Widget_Headers->isChecked());
|
OnDisplayTitleBars(ui->action_Display_Dock_Widget_Headers->isChecked());
|
||||||
|
|
||||||
ui->action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar);
|
ui->action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar.GetValue());
|
||||||
game_list->SetFilterVisible(ui->action_Show_Filter_Bar->isChecked());
|
game_list->SetFilterVisible(ui->action_Show_Filter_Bar->isChecked());
|
||||||
|
|
||||||
ui->action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar);
|
ui->action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar.GetValue());
|
||||||
statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
|
statusBar()->setVisible(ui->action_Show_Status_Bar->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -717,6 +705,9 @@ void GMainWindow::ConnectWidgetEvents() {
|
||||||
connect(game_list, &GameList::PopulatingCompleted, this,
|
connect(game_list, &GameList::PopulatingCompleted, this,
|
||||||
[this] { multiplayer_state->UpdateGameList(game_list->GetModel()); });
|
[this] { multiplayer_state->UpdateGameList(game_list->GetModel()); });
|
||||||
|
|
||||||
|
connect(game_list, &GameList::OpenPerGameGeneralRequested, this,
|
||||||
|
&GMainWindow::OnGameListOpenPerGameProperties);
|
||||||
|
|
||||||
connect(this, &GMainWindow::EmulationStarting, render_window,
|
connect(this, &GMainWindow::EmulationStarting, render_window,
|
||||||
&GRenderWindow::OnEmulationStarting);
|
&GRenderWindow::OnEmulationStarting);
|
||||||
connect(this, &GMainWindow::EmulationStopping, render_window,
|
connect(this, &GMainWindow::EmulationStopping, render_window,
|
||||||
|
@ -752,6 +743,8 @@ void GMainWindow::ConnectMenuEvents() {
|
||||||
connect(ui->action_Report_Compatibility, &QAction::triggered, this,
|
connect(ui->action_Report_Compatibility, &QAction::triggered, this,
|
||||||
&GMainWindow::OnMenuReportCompatibility);
|
&GMainWindow::OnMenuReportCompatibility);
|
||||||
connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
|
connect(ui->action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure);
|
||||||
|
connect(ui->action_Configure_Current_Game, &QAction::triggered, this,
|
||||||
|
&GMainWindow::OnConfigurePerGame);
|
||||||
connect(ui->action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats);
|
connect(ui->action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats);
|
||||||
|
|
||||||
// View
|
// View
|
||||||
|
@ -1086,6 +1079,22 @@ void GMainWindow::BootGame(const QString& filename) {
|
||||||
Core::Movie::GetInstance().PrepareForPlayback(movie_playback_path.toStdString());
|
Core::Movie::GetInstance().PrepareForPlayback(movie_playback_path.toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 title_id{0};
|
||||||
|
const std::string path = filename.toStdString();
|
||||||
|
const auto loader = Loader::GetLoader(path);
|
||||||
|
|
||||||
|
if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success) {
|
||||||
|
// Load per game settings
|
||||||
|
const std::string name{FileUtil::GetFilename(filename.toStdString())};
|
||||||
|
const std::string config_file_name =
|
||||||
|
title_id == 0 ? name : fmt::format("{:016X}", title_id);
|
||||||
|
Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig);
|
||||||
|
Settings::Apply();
|
||||||
|
|
||||||
|
LOG_INFO(Frontend, "Using per game config file for title id {}", config_file_name);
|
||||||
|
Settings::LogSettings();
|
||||||
|
}
|
||||||
|
|
||||||
// Save configurations
|
// Save configurations
|
||||||
UpdateUISettings();
|
UpdateUISettings();
|
||||||
game_list->SaveInterfaceLayout();
|
game_list->SaveInterfaceLayout();
|
||||||
|
@ -1239,6 +1248,7 @@ void GMainWindow::ShutdownGame() {
|
||||||
ui->action_Stop->setEnabled(false);
|
ui->action_Stop->setEnabled(false);
|
||||||
ui->action_Restart->setEnabled(false);
|
ui->action_Restart->setEnabled(false);
|
||||||
ui->action_Cheats->setEnabled(false);
|
ui->action_Cheats->setEnabled(false);
|
||||||
|
ui->action_Configure_Current_Game->setEnabled(false);
|
||||||
ui->action_Load_Amiibo->setEnabled(false);
|
ui->action_Load_Amiibo->setEnabled(false);
|
||||||
ui->action_Remove_Amiibo->setEnabled(false);
|
ui->action_Remove_Amiibo->setEnabled(false);
|
||||||
ui->action_Report_Compatibility->setEnabled(false);
|
ui->action_Report_Compatibility->setEnabled(false);
|
||||||
|
@ -1398,26 +1408,42 @@ void GMainWindow::OnGameListOpenFolder(u64 data_id, GameListOpenTarget target) {
|
||||||
path = Service::AM::GetTitlePath(media_type, data_id) + "content/";
|
path = Service::AM::GetTitlePath(media_type, data_id) + "content/";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GameListOpenTarget::UPDATE_DATA:
|
case GameListOpenTarget::UPDATE_DATA: {
|
||||||
open_target = "Update Data";
|
open_target = "Update Data";
|
||||||
path = Service::AM::GetTitlePath(Service::FS::MediaType::SDMC, data_id + 0xe00000000) +
|
path = Service::AM::GetTitlePath(Service::FS::MediaType::SDMC, data_id + 0xe00000000) +
|
||||||
"content/";
|
"content/";
|
||||||
break;
|
break;
|
||||||
case GameListOpenTarget::TEXTURE_DUMP:
|
}
|
||||||
|
case GameListOpenTarget::TEXTURE_DUMP: {
|
||||||
open_target = "Dumped Textures";
|
open_target = "Dumped Textures";
|
||||||
path = fmt::format("{}textures/{:016X}/",
|
path = fmt::format("{}textures/{:016X}/",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::DumpDir), data_id);
|
FileUtil::GetUserPath(FileUtil::UserPath::DumpDir), data_id);
|
||||||
break;
|
break;
|
||||||
case GameListOpenTarget::TEXTURE_LOAD:
|
}
|
||||||
|
case GameListOpenTarget::TEXTURE_LOAD: {
|
||||||
open_target = "Custom Textures";
|
open_target = "Custom Textures";
|
||||||
path = fmt::format("{}textures/{:016X}/",
|
path = fmt::format("{}textures/{:016X}/",
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::LoadDir), data_id);
|
FileUtil::GetUserPath(FileUtil::UserPath::LoadDir), data_id);
|
||||||
break;
|
break;
|
||||||
case GameListOpenTarget::MODS:
|
}
|
||||||
|
case GameListOpenTarget::MODS: {
|
||||||
open_target = "Mods";
|
open_target = "Mods";
|
||||||
path = fmt::format("{}mods/{:016X}/", FileUtil::GetUserPath(FileUtil::UserPath::LoadDir),
|
path = fmt::format("{}mods/{:016X}/", FileUtil::GetUserPath(FileUtil::UserPath::LoadDir),
|
||||||
data_id);
|
data_id);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case GameListOpenTarget::DLC_DATA: {
|
||||||
|
open_target = "DLC Data";
|
||||||
|
path = fmt::format("{}Nintendo 3DS/00000000000000000000000000000000/"
|
||||||
|
"00000000000000000000000000000000/title/0004008c/{:08x}/content/",
|
||||||
|
FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir), data_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GameListOpenTarget::SHADER_CACHE: {
|
||||||
|
open_target = "Shader Cache";
|
||||||
|
path = FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Frontend, "Unexpected target {}", static_cast<int>(target));
|
LOG_ERROR(Frontend, "Unexpected target {}", static_cast<int>(target));
|
||||||
return;
|
return;
|
||||||
|
@ -1529,6 +1555,19 @@ void GMainWindow::OnGameListShowList(bool show) {
|
||||||
game_list_placeholder->setVisible(!show);
|
game_list_placeholder->setVisible(!show);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void GMainWindow::OnGameListOpenPerGameProperties(const QString& file) {
|
||||||
|
const auto loader = Loader::GetLoader(file.toStdString());
|
||||||
|
|
||||||
|
u64 title_id{};
|
||||||
|
if (!loader || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) {
|
||||||
|
QMessageBox::information(this, tr("Properties"),
|
||||||
|
tr("The game properties could not be loaded."));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenPerGameConfiguration(title_id, file);
|
||||||
|
}
|
||||||
|
|
||||||
void GMainWindow::OnMenuLoadFile() {
|
void GMainWindow::OnMenuLoadFile() {
|
||||||
const QString extensions = QStringLiteral("*.").append(
|
const QString extensions = QStringLiteral("*.").append(
|
||||||
GameList::supported_file_extensions.join(QStringLiteral(" *.")));
|
GameList::supported_file_extensions.join(QStringLiteral(" *.")));
|
||||||
|
@ -1654,6 +1693,7 @@ void GMainWindow::OnStartGame() {
|
||||||
ui->action_Stop->setEnabled(true);
|
ui->action_Stop->setEnabled(true);
|
||||||
ui->action_Restart->setEnabled(true);
|
ui->action_Restart->setEnabled(true);
|
||||||
ui->action_Cheats->setEnabled(true);
|
ui->action_Cheats->setEnabled(true);
|
||||||
|
ui->action_Configure_Current_Game->setEnabled(true);
|
||||||
ui->action_Load_Amiibo->setEnabled(true);
|
ui->action_Load_Amiibo->setEnabled(true);
|
||||||
ui->action_Report_Compatibility->setEnabled(true);
|
ui->action_Report_Compatibility->setEnabled(true);
|
||||||
ui->action_Capture_Screenshot->setEnabled(true);
|
ui->action_Capture_Screenshot->setEnabled(true);
|
||||||
|
@ -1676,6 +1716,7 @@ void GMainWindow::OnPauseGame() {
|
||||||
|
|
||||||
void GMainWindow::OnStopGame() {
|
void GMainWindow::OnStopGame() {
|
||||||
ShutdownGame();
|
ShutdownGame();
|
||||||
|
Settings::RestoreGlobalState(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnLoadComplete() {
|
void GMainWindow::OnLoadComplete() {
|
||||||
|
@ -1769,7 +1810,7 @@ void GMainWindow::UpdateSecondaryWindowVisibility() {
|
||||||
if (!emulation_running) {
|
if (!emulation_running) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Settings::values.layout_option == Settings::LayoutOption::SeparateWindows) {
|
if (Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows) {
|
||||||
secondary_window->RestoreGeometry();
|
secondary_window->RestoreGeometry();
|
||||||
secondary_window->show();
|
secondary_window->show();
|
||||||
} else {
|
} else {
|
||||||
|
@ -1800,7 +1841,7 @@ void GMainWindow::ChangeScreenLayout() {
|
||||||
|
|
||||||
void GMainWindow::ToggleScreenLayout() {
|
void GMainWindow::ToggleScreenLayout() {
|
||||||
const Settings::LayoutOption new_layout = []() {
|
const Settings::LayoutOption new_layout = []() {
|
||||||
switch (Settings::values.layout_option) {
|
switch (Settings::values.layout_option.GetValue()) {
|
||||||
case Settings::LayoutOption::Default:
|
case Settings::LayoutOption::Default:
|
||||||
return Settings::LayoutOption::SingleScreen;
|
return Settings::LayoutOption::SingleScreen;
|
||||||
case Settings::LayoutOption::SingleScreen:
|
case Settings::LayoutOption::SingleScreen:
|
||||||
|
@ -1812,7 +1853,8 @@ void GMainWindow::ToggleScreenLayout() {
|
||||||
case Settings::LayoutOption::SeparateWindows:
|
case Settings::LayoutOption::SeparateWindows:
|
||||||
return Settings::LayoutOption::Default;
|
return Settings::LayoutOption::Default;
|
||||||
default:
|
default:
|
||||||
LOG_ERROR(Frontend, "Unknown layout option {}", Settings::values.layout_option);
|
LOG_ERROR(Frontend, "Unknown layout option {}",
|
||||||
|
Settings::values.layout_option.GetValue());
|
||||||
return Settings::LayoutOption::Default;
|
return Settings::LayoutOption::Default;
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
@ -1864,6 +1906,7 @@ void GMainWindow::OnLoadState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnConfigure() {
|
void GMainWindow::OnConfigure() {
|
||||||
|
Settings::SetConfiguringGlobal(true);
|
||||||
ConfigureDialog configureDialog(this, hotkey_registry,
|
ConfigureDialog configureDialog(this, hotkey_registry,
|
||||||
!multiplayer_state->IsHostingPublicRoom());
|
!multiplayer_state->IsHostingPublicRoom());
|
||||||
connect(&configureDialog, &ConfigureDialog::LanguageChanged, this,
|
connect(&configureDialog, &ConfigureDialog::LanguageChanged, this,
|
||||||
|
@ -1872,15 +1915,15 @@ void GMainWindow::OnConfigure() {
|
||||||
const int old_input_profile_index = Settings::values.current_input_profile_index;
|
const int old_input_profile_index = Settings::values.current_input_profile_index;
|
||||||
const auto old_input_profiles = Settings::values.input_profiles;
|
const auto old_input_profiles = Settings::values.input_profiles;
|
||||||
const auto old_touch_from_button_maps = Settings::values.touch_from_button_maps;
|
const auto old_touch_from_button_maps = Settings::values.touch_from_button_maps;
|
||||||
const bool old_discord_presence = UISettings::values.enable_discord_presence;
|
const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
|
||||||
auto result = configureDialog.exec();
|
auto result = configureDialog.exec();
|
||||||
if (result == QDialog::Accepted) {
|
if (result == QDialog::Accepted) {
|
||||||
configureDialog.ApplyConfiguration();
|
configureDialog.ApplyConfiguration();
|
||||||
InitializeHotkeys();
|
InitializeHotkeys();
|
||||||
if (UISettings::values.theme != old_theme)
|
if (UISettings::values.theme != old_theme)
|
||||||
UpdateUITheme();
|
UpdateUITheme();
|
||||||
if (UISettings::values.enable_discord_presence != old_discord_presence)
|
if (UISettings::values.enable_discord_presence.GetValue() != old_discord_presence)
|
||||||
SetDiscordEnabled(UISettings::values.enable_discord_presence);
|
SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue());
|
||||||
if (!multiplayer_state->IsHostingPublicRoom())
|
if (!multiplayer_state->IsHostingPublicRoom())
|
||||||
multiplayer_state->UpdateCredentials();
|
multiplayer_state->UpdateCredentials();
|
||||||
emit UpdateThemedIcons();
|
emit UpdateThemedIcons();
|
||||||
|
@ -2057,24 +2100,26 @@ void GMainWindow::OnSaveMovie() {
|
||||||
|
|
||||||
void GMainWindow::OnCaptureScreenshot() {
|
void GMainWindow::OnCaptureScreenshot() {
|
||||||
OnPauseGame();
|
OnPauseGame();
|
||||||
QString path = UISettings::values.screenshot_path;
|
std::string path = UISettings::values.screenshot_path.GetValue();
|
||||||
if (!FileUtil::IsDirectory(path.toStdString())) {
|
if (!FileUtil::IsDirectory(path)) {
|
||||||
if (!FileUtil::CreateFullPath(path.toStdString())) {
|
if (!FileUtil::CreateFullPath(path)) {
|
||||||
QMessageBox::information(this, tr("Invalid Screenshot Directory"),
|
QMessageBox::information(this, tr("Invalid Screenshot Directory"),
|
||||||
tr("Cannot create specified screenshot directory. Screenshot "
|
tr("Cannot create specified screenshot directory. Screenshot "
|
||||||
"path is set back to its default value."));
|
"path is set back to its default value."));
|
||||||
path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::UserDir));
|
path = FileUtil::GetUserPath(FileUtil::UserPath::UserDir);
|
||||||
path.append(QStringLiteral("screenshots/"));
|
path.append("screenshots/");
|
||||||
UISettings::values.screenshot_path = path;
|
UISettings::values.screenshot_path = path;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const QString filename = game_title.remove(QRegularExpression(QStringLiteral("[\\/:?\"<>|]")));
|
const std::string filename =
|
||||||
const QString timestamp =
|
game_title.remove(QRegularExpression(QStringLiteral("[\\/:?\"<>|]"))).toStdString();
|
||||||
QDateTime::currentDateTime().toString(QStringLiteral("dd.MM.yy_hh.mm.ss.z"));
|
const std::string timestamp =
|
||||||
path.append(QStringLiteral("/%1_%2.png").arg(filename, timestamp));
|
QDateTime::currentDateTime().toString(QStringLiteral("dd.MM.yy_hh.mm.ss.z")).toStdString();
|
||||||
|
path.append(fmt::format("/{}_{}.png", filename, timestamp));
|
||||||
|
|
||||||
auto* const screenshot_window = secondary_window->HasFocus() ? secondary_window : render_window;
|
auto* const screenshot_window = secondary_window->HasFocus() ? secondary_window : render_window;
|
||||||
screenshot_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor, path);
|
screenshot_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor.GetValue(),
|
||||||
|
QString::fromStdString(path));
|
||||||
OnStartGame();
|
OnStartGame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2166,22 +2211,12 @@ void GMainWindow::UpdateStatusBar() {
|
||||||
|
|
||||||
auto results = Core::System::GetInstance().GetAndResetPerfStats();
|
auto results = Core::System::GetInstance().GetAndResetPerfStats();
|
||||||
|
|
||||||
if (Settings::values.use_frame_limit_alternate) {
|
if (Settings::values.frame_limit.GetValue() == 0) {
|
||||||
if (Settings::values.frame_limit_alternate == 0) {
|
|
||||||
emu_speed_label->setText(
|
|
||||||
tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
|
|
||||||
|
|
||||||
} else {
|
|
||||||
emu_speed_label->setText(tr("Speed: %1% / %2%")
|
|
||||||
.arg(results.emulation_speed * 100.0, 0, 'f', 0)
|
|
||||||
.arg(Settings::values.frame_limit_alternate));
|
|
||||||
}
|
|
||||||
} else if (Settings::values.frame_limit == 0) {
|
|
||||||
emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
|
emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
|
||||||
} else {
|
} else {
|
||||||
emu_speed_label->setText(tr("Speed: %1% / %2%")
|
emu_speed_label->setText(tr("Speed: %1% / %2%")
|
||||||
.arg(results.emulation_speed * 100.0, 0, 'f', 0)
|
.arg(results.emulation_speed * 100.0, 0, 'f', 0)
|
||||||
.arg(Settings::values.frame_limit));
|
.arg(Settings::values.frame_limit.GetValue()));
|
||||||
}
|
}
|
||||||
game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0));
|
game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0));
|
||||||
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
|
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
|
||||||
|
@ -2192,7 +2227,7 @@ void GMainWindow::UpdateStatusBar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::HideMouseCursor() {
|
void GMainWindow::HideMouseCursor() {
|
||||||
if (emu_thread == nullptr || UISettings::values.hide_mouse == false) {
|
if (emu_thread == nullptr || !UISettings::values.hide_mouse.GetValue()) {
|
||||||
mouse_hide_timer.stop();
|
mouse_hide_timer.stop();
|
||||||
ShowMouseCursor();
|
ShowMouseCursor();
|
||||||
return;
|
return;
|
||||||
|
@ -2455,6 +2490,35 @@ void GMainWindow::OnLanguageChanged(const QString& locale) {
|
||||||
ui->action_Start->setText(tr("Continue"));
|
ui->action_Start->setText(tr("Continue"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GMainWindow::OnConfigurePerGame() {
|
||||||
|
u64 title_id{};
|
||||||
|
Core::System::GetInstance().GetAppLoader().ReadProgramId(title_id);
|
||||||
|
OpenPerGameConfiguration(title_id, game_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GMainWindow::OpenPerGameConfiguration(u64 title_id, const QString& file_name) {
|
||||||
|
Core::System& system = Core::System::GetInstance();
|
||||||
|
|
||||||
|
Settings::SetConfiguringGlobal(false);
|
||||||
|
ConfigurePerGame dialog(this, title_id, file_name, system);
|
||||||
|
const auto result = dialog.exec();
|
||||||
|
|
||||||
|
if (result != QDialog::Accepted) {
|
||||||
|
Settings::RestoreGlobalState(system.IsPoweredOn());
|
||||||
|
return;
|
||||||
|
} else if (result == QDialog::Accepted) {
|
||||||
|
dialog.ApplyConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not cause the global config to write local settings into the config file
|
||||||
|
const bool is_powered_on = system.IsPoweredOn();
|
||||||
|
Settings::RestoreGlobalState(system.IsPoweredOn());
|
||||||
|
|
||||||
|
if (!is_powered_on) {
|
||||||
|
config->Save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GMainWindow::OnMoviePlaybackCompleted() {
|
void GMainWindow::OnMoviePlaybackCompleted() {
|
||||||
OnPauseGame();
|
OnPauseGame();
|
||||||
QMessageBox::information(this, tr("Playback Completed"), tr("Movie playback completed."));
|
QMessageBox::information(this, tr("Playback Completed"), tr("Movie playback completed."));
|
||||||
|
@ -2489,18 +2553,19 @@ void GMainWindow::UpdateUISettings() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::SyncMenuUISettings() {
|
void GMainWindow::SyncMenuUISettings() {
|
||||||
ui->action_Screen_Layout_Default->setChecked(Settings::values.layout_option ==
|
ui->action_Screen_Layout_Default->setChecked(Settings::values.layout_option.GetValue() ==
|
||||||
Settings::LayoutOption::Default);
|
Settings::LayoutOption::Default);
|
||||||
ui->action_Screen_Layout_Single_Screen->setChecked(Settings::values.layout_option ==
|
ui->action_Screen_Layout_Single_Screen->setChecked(Settings::values.layout_option.GetValue() ==
|
||||||
Settings::LayoutOption::SingleScreen);
|
Settings::LayoutOption::SingleScreen);
|
||||||
ui->action_Screen_Layout_Large_Screen->setChecked(Settings::values.layout_option ==
|
ui->action_Screen_Layout_Large_Screen->setChecked(Settings::values.layout_option.GetValue() ==
|
||||||
Settings::LayoutOption::LargeScreen);
|
Settings::LayoutOption::LargeScreen);
|
||||||
ui->action_Screen_Layout_Side_by_Side->setChecked(Settings::values.layout_option ==
|
ui->action_Screen_Layout_Side_by_Side->setChecked(Settings::values.layout_option.GetValue() ==
|
||||||
Settings::LayoutOption::SideScreen);
|
Settings::LayoutOption::SideScreen);
|
||||||
ui->action_Screen_Layout_Separate_Windows->setChecked(Settings::values.layout_option ==
|
ui->action_Screen_Layout_Separate_Windows->setChecked(
|
||||||
Settings::LayoutOption::SeparateWindows);
|
Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows);
|
||||||
ui->action_Screen_Layout_Swap_Screens->setChecked(Settings::values.swap_screen);
|
ui->action_Screen_Layout_Swap_Screens->setChecked(Settings::values.swap_screen.GetValue());
|
||||||
ui->action_Screen_Layout_Upright_Screens->setChecked(Settings::values.upright_screen);
|
ui->action_Screen_Layout_Upright_Screens->setChecked(
|
||||||
|
Settings::values.upright_screen.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::RetranslateStatusBar() {
|
void GMainWindow::RetranslateStatusBar() {
|
||||||
|
@ -2573,11 +2638,13 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
// Register frontend applets
|
// Register frontend applets
|
||||||
Frontend::RegisterDefaultApplets();
|
Frontend::RegisterDefaultApplets();
|
||||||
Core::System::GetInstance().RegisterMiiSelector(std::make_shared<QtMiiSelector>(main_window));
|
|
||||||
Core::System::GetInstance().RegisterSoftwareKeyboard(std::make_shared<QtKeyboard>(main_window));
|
Core::System& system = Core::System::GetInstance();
|
||||||
|
system.RegisterMiiSelector(std::make_shared<QtMiiSelector>(main_window));
|
||||||
|
system.RegisterSoftwareKeyboard(std::make_shared<QtKeyboard>(main_window));
|
||||||
|
|
||||||
// Register Qt image interface
|
// Register Qt image interface
|
||||||
Core::System::GetInstance().RegisterImageInterface(std::make_shared<QtImageInterface>());
|
system.RegisterImageInterface(std::make_shared<QtImageInterface>());
|
||||||
|
|
||||||
main_window.show();
|
main_window.show();
|
||||||
|
|
||||||
|
|
|
@ -183,6 +183,8 @@ private slots:
|
||||||
void OnGameListOpenDirectory(const QString& directory);
|
void OnGameListOpenDirectory(const QString& directory);
|
||||||
void OnGameListAddDirectory();
|
void OnGameListAddDirectory();
|
||||||
void OnGameListShowList(bool show);
|
void OnGameListShowList(bool show);
|
||||||
|
void OnGameListOpenPerGameProperties(const QString& file);
|
||||||
|
void OnConfigurePerGame();
|
||||||
void OnMenuLoadFile();
|
void OnMenuLoadFile();
|
||||||
void OnMenuInstallCIA();
|
void OnMenuInstallCIA();
|
||||||
void OnUpdateProgress(std::size_t written, std::size_t total);
|
void OnUpdateProgress(std::size_t written, std::size_t total);
|
||||||
|
@ -238,6 +240,7 @@ private:
|
||||||
void InstallCIA(QStringList filepaths);
|
void InstallCIA(QStringList filepaths);
|
||||||
void HideMouseCursor();
|
void HideMouseCursor();
|
||||||
void ShowMouseCursor();
|
void ShowMouseCursor();
|
||||||
|
void OpenPerGameConfiguration(u64 title_id, const QString& file_name);
|
||||||
|
|
||||||
std::unique_ptr<Ui::MainWindow> ui;
|
std::unique_ptr<Ui::MainWindow> ui;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1081</width>
|
<width>1081</width>
|
||||||
<height>21</height>
|
<height>25</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QMenu" name="menu_File">
|
<widget class="QMenu" name="menu_File">
|
||||||
|
@ -104,6 +104,7 @@
|
||||||
<addaction name="action_Report_Compatibility"/>
|
<addaction name="action_Report_Compatibility"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="action_Configure"/>
|
<addaction name="action_Configure"/>
|
||||||
|
<addaction name="action_Configure_Current_Game"/>
|
||||||
<addaction name="action_Cheats"/>
|
<addaction name="action_Cheats"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenu" name="menu_View">
|
<widget class="QMenu" name="menu_View">
|
||||||
|
@ -239,20 +240,20 @@
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="action_Save">
|
<action name="action_Save">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Save</string>
|
<string>Save</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="action_Load">
|
<action name="action_Load">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Load</string>
|
<string>Load</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="action_FAQ">
|
<action name="action_FAQ">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -541,6 +542,14 @@
|
||||||
<string>Open Citra Folder</string>
|
<string>Open Citra Folder</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="action_Configure_Current_Game">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Configure Current Game...</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include "common/common_types.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
namespace UISettings {
|
namespace UISettings {
|
||||||
|
|
||||||
|
@ -40,13 +40,13 @@ struct GameDir {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class GameListIconSize {
|
enum class GameListIconSize : u32 {
|
||||||
NoIcon, ///< Do not display icons
|
NoIcon, ///< Do not display icons
|
||||||
SmallIcon, ///< Display a small (24x24) icon
|
SmallIcon, ///< Display a small (24x24) icon
|
||||||
LargeIcon, ///< Display a large (48x48) icon
|
LargeIcon, ///< Display a large (48x48) icon
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class GameListText {
|
enum class GameListText : s32 {
|
||||||
NoText = -1, ///< No text
|
NoText = -1, ///< No text
|
||||||
FileName, ///< Display the file name of the entry
|
FileName, ///< Display the file name of the entry
|
||||||
FullPath, ///< Display the full path of the entry
|
FullPath, ///< Display the full path of the entry
|
||||||
|
@ -65,40 +65,41 @@ struct Values {
|
||||||
QByteArray gamelist_header_state;
|
QByteArray gamelist_header_state;
|
||||||
|
|
||||||
QByteArray microprofile_geometry;
|
QByteArray microprofile_geometry;
|
||||||
bool microprofile_visible;
|
Settings::Setting<bool> microprofile_visible{false, "microProfileDialogVisible"};
|
||||||
|
|
||||||
bool single_window_mode;
|
Settings::Setting<bool> single_window_mode{true, "singleWindowMode"};
|
||||||
bool fullscreen;
|
Settings::Setting<bool> fullscreen{false, "fullscreen"};
|
||||||
bool display_titlebar;
|
Settings::Setting<bool> display_titlebar{true, "displayTitleBars"};
|
||||||
bool show_filter_bar;
|
Settings::Setting<bool> show_filter_bar{true, "showFilterBar"};
|
||||||
bool show_status_bar;
|
Settings::Setting<bool> show_status_bar{true, "showStatusBar"};
|
||||||
|
|
||||||
bool confirm_before_closing;
|
Settings::Setting<bool> confirm_before_closing{true, "confirmClose"};
|
||||||
bool first_start;
|
Settings::Setting<bool> first_start{true, "firstStart"};
|
||||||
bool pause_when_in_background;
|
Settings::Setting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
|
||||||
bool hide_mouse;
|
Settings::Setting<bool> hide_mouse{false, "hideInactiveMouse"};
|
||||||
|
|
||||||
bool updater_found;
|
bool updater_found;
|
||||||
bool update_on_close;
|
Settings::Setting<bool> update_on_close{false, "update_on_close"};
|
||||||
bool check_for_update_on_start;
|
Settings::Setting<bool> check_for_update_on_start{true, "check_for_update_on_start"};
|
||||||
|
|
||||||
// Discord RPC
|
// Discord RPC
|
||||||
bool enable_discord_presence;
|
Settings::Setting<bool> enable_discord_presence{true, "enable_discord_presence"};
|
||||||
|
|
||||||
// Game List
|
// Game List
|
||||||
GameListIconSize game_list_icon_size;
|
Settings::Setting<GameListIconSize> game_list_icon_size{GameListIconSize::LargeIcon,
|
||||||
GameListText game_list_row_1;
|
"iconSize"};
|
||||||
GameListText game_list_row_2;
|
Settings::Setting<GameListText> game_list_row_1{GameListText::TitleName, "row1"};
|
||||||
bool game_list_hide_no_icon;
|
Settings::Setting<GameListText> game_list_row_2{GameListText::FileName, "row2"};
|
||||||
bool game_list_single_line_mode;
|
Settings::Setting<bool> game_list_hide_no_icon{false, "hideNoIcon"};
|
||||||
|
Settings::Setting<bool> game_list_single_line_mode{false, "singleLineMode"};
|
||||||
|
|
||||||
u16 screenshot_resolution_factor;
|
Settings::Setting<u16> screenshot_resolution_factor{0, "screenshot_resolution_factor"};
|
||||||
|
Settings::SwitchableSetting<std::string> screenshot_path{"", "screenshotPath"};
|
||||||
|
|
||||||
QString roms_path;
|
QString roms_path;
|
||||||
QString symbols_path;
|
QString symbols_path;
|
||||||
QString movie_record_path;
|
QString movie_record_path;
|
||||||
QString movie_playback_path;
|
QString movie_playback_path;
|
||||||
QString screenshot_path;
|
|
||||||
QString video_dumping_path;
|
QString video_dumping_path;
|
||||||
QString game_dir_deprecated;
|
QString game_dir_deprecated;
|
||||||
bool game_dir_deprecated_deepscan;
|
bool game_dir_deprecated_deepscan;
|
||||||
|
@ -111,7 +112,7 @@ struct Values {
|
||||||
// Shortcut name <Shortcut, context>
|
// Shortcut name <Shortcut, context>
|
||||||
std::vector<Shortcut> shortcuts;
|
std::vector<Shortcut> shortcuts;
|
||||||
|
|
||||||
uint32_t callout_flags;
|
Settings::Setting<u32> callout_flags{0, "calloutFlags"};
|
||||||
|
|
||||||
// multiplayer settings
|
// multiplayer settings
|
||||||
QString nickname;
|
QString nickname;
|
||||||
|
@ -127,7 +128,7 @@ struct Values {
|
||||||
std::pair<std::vector<std::string>, std::vector<std::string>> ban_list;
|
std::pair<std::vector<std::string>, std::vector<std::string>> ban_list;
|
||||||
|
|
||||||
// logging
|
// logging
|
||||||
bool show_console;
|
Settings::Setting<bool> show_console{false, "showConsole"};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Values values;
|
extern Values values;
|
||||||
|
|
|
@ -99,6 +99,8 @@ add_library(common STATIC
|
||||||
scm_rev.cpp
|
scm_rev.cpp
|
||||||
scm_rev.h
|
scm_rev.h
|
||||||
scope_exit.h
|
scope_exit.h
|
||||||
|
settings.cpp
|
||||||
|
settings.h
|
||||||
serialization/atomic.h
|
serialization/atomic.h
|
||||||
serialization/boost_discrete_interval.hpp
|
serialization/boost_discrete_interval.hpp
|
||||||
serialization/boost_flat_set.h
|
serialization/boost_flat_set.h
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include "audio_core/dsp_interface.h"
|
#include "audio_core/dsp_interface.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/gdbstub/gdbstub.h"
|
#include "core/gdbstub/gdbstub.h"
|
||||||
#include "core/hle/kernel/shared_page.h"
|
#include "core/hle/kernel/shared_page.h"
|
||||||
|
@ -13,24 +14,24 @@
|
||||||
#include "core/hle/service/ir/ir_rst.h"
|
#include "core/hle/service/ir/ir_rst.h"
|
||||||
#include "core/hle/service/ir/ir_user.h"
|
#include "core/hle/service/ir/ir_user.h"
|
||||||
#include "core/hle/service/mic_u.h"
|
#include "core/hle/service/mic_u.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
|
|
||||||
Values values = {};
|
Values values = {};
|
||||||
|
static bool configuring_global = true;
|
||||||
|
|
||||||
void Apply() {
|
void Apply() {
|
||||||
GDBStub::SetServerPort(values.gdbstub_port);
|
GDBStub::SetServerPort(values.gdbstub_port.GetValue());
|
||||||
GDBStub::ToggleServer(values.use_gdbstub);
|
GDBStub::ToggleServer(values.use_gdbstub.GetValue());
|
||||||
|
|
||||||
VideoCore::g_hw_renderer_enabled = values.use_hw_renderer;
|
VideoCore::g_hw_renderer_enabled = values.use_hw_renderer.GetValue();
|
||||||
VideoCore::g_shader_jit_enabled = values.use_shader_jit;
|
VideoCore::g_shader_jit_enabled = values.use_shader_jit.GetValue();
|
||||||
VideoCore::g_hw_shader_enabled = values.use_hw_shader;
|
VideoCore::g_hw_shader_enabled = values.use_hw_shader.GetValue();
|
||||||
VideoCore::g_separable_shader_enabled = values.separable_shader;
|
VideoCore::g_separable_shader_enabled = values.separable_shader.GetValue();
|
||||||
VideoCore::g_hw_shader_accurate_mul = values.shaders_accurate_mul;
|
VideoCore::g_hw_shader_accurate_mul = values.shaders_accurate_mul.GetValue();
|
||||||
VideoCore::g_use_disk_shader_cache = values.use_disk_shader_cache;
|
VideoCore::g_use_disk_shader_cache = values.use_disk_shader_cache.GetValue();
|
||||||
|
|
||||||
#ifndef ANDROID
|
#ifndef ANDROID
|
||||||
if (VideoCore::g_renderer) {
|
if (VideoCore::g_renderer) {
|
||||||
|
@ -45,9 +46,9 @@ void Apply() {
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
if (system.IsPoweredOn()) {
|
if (system.IsPoweredOn()) {
|
||||||
system.CoreTiming().UpdateClockSpeed(values.cpu_clock_percentage);
|
system.CoreTiming().UpdateClockSpeed(values.cpu_clock_percentage.GetValue());
|
||||||
Core::DSP().SetSink(values.sink_id, values.audio_device_id);
|
Core::DSP().SetSink(values.sink_id.GetValue(), values.audio_device_id.GetValue());
|
||||||
Core::DSP().EnableStretching(values.enable_audio_stretching);
|
Core::DSP().EnableStretching(values.enable_audio_stretching.GetValue());
|
||||||
|
|
||||||
auto hid = Service::HID::GetModule(system);
|
auto hid = Service::HID::GetModule(system);
|
||||||
if (hid) {
|
if (hid) {
|
||||||
|
@ -76,39 +77,47 @@ void LogSettings() {
|
||||||
LOG_INFO(Config, "{}: {}", name, value);
|
LOG_INFO(Config, "{}: {}", name, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const auto to_string = [](AudioEmulation emulation) -> std::string_view {
|
||||||
|
switch (emulation) {
|
||||||
|
case AudioEmulation::HLE:
|
||||||
|
return "HLE";
|
||||||
|
case AudioEmulation::LLE:
|
||||||
|
return "LLE";
|
||||||
|
case AudioEmulation::LLEMultithreaded:
|
||||||
|
return "LLE Multithreaded";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
LOG_INFO(Config, "Citra Configuration:");
|
LOG_INFO(Config, "Citra Configuration:");
|
||||||
log_setting("Core_UseCpuJit", values.use_cpu_jit);
|
log_setting("Core_UseCpuJit", values.use_cpu_jit.GetValue());
|
||||||
log_setting("Core_CPUClockPercentage", values.cpu_clock_percentage);
|
log_setting("Core_CPUClockPercentage", values.cpu_clock_percentage.GetValue());
|
||||||
log_setting("Renderer_UseGLES", values.use_gles);
|
log_setting("Renderer_UseGLES", values.use_gles.GetValue());
|
||||||
log_setting("Renderer_UseHwRenderer", values.use_hw_renderer);
|
log_setting("Renderer_UseHwRenderer", values.use_hw_renderer.GetValue());
|
||||||
log_setting("Renderer_UseHwShader", values.use_hw_shader);
|
log_setting("Renderer_UseHwShader", values.use_hw_shader.GetValue());
|
||||||
log_setting("Renderer_SeparableShader", values.separable_shader);
|
log_setting("Renderer_SeparableShader", values.separable_shader.GetValue());
|
||||||
log_setting("Renderer_ShadersAccurateMul", values.shaders_accurate_mul);
|
log_setting("Renderer_ShadersAccurateMul", values.shaders_accurate_mul.GetValue());
|
||||||
log_setting("Renderer_UseShaderJit", values.use_shader_jit);
|
log_setting("Renderer_UseShaderJit", values.use_shader_jit.GetValue());
|
||||||
log_setting("Renderer_UseResolutionFactor", values.resolution_factor);
|
log_setting("Renderer_UseResolutionFactor", values.resolution_factor.GetValue());
|
||||||
log_setting("Renderer_FrameLimit", values.frame_limit);
|
log_setting("Renderer_FrameLimit", values.frame_limit.GetValue());
|
||||||
log_setting("Renderer_UseFrameLimitAlternate", values.use_frame_limit_alternate);
|
log_setting("Renderer_VSyncNew", values.use_vsync_new.GetValue());
|
||||||
log_setting("Renderer_FrameLimitAlternate", values.frame_limit_alternate);
|
log_setting("Renderer_PostProcessingShader", values.pp_shader_name.GetValue());
|
||||||
log_setting("Renderer_VSyncNew", values.use_vsync_new);
|
log_setting("Renderer_FilterMode", values.filter_mode.GetValue());
|
||||||
log_setting("Renderer_PostProcessingShader", values.pp_shader_name);
|
log_setting("Renderer_TextureFilterName", values.texture_filter_name.GetValue());
|
||||||
log_setting("Renderer_FilterMode", values.filter_mode);
|
log_setting("Stereoscopy_Render3d", values.render_3d.GetValue());
|
||||||
log_setting("Renderer_TextureFilterName", values.texture_filter_name);
|
log_setting("Stereoscopy_Factor3d", values.factor_3d.GetValue());
|
||||||
log_setting("Stereoscopy_Render3d", values.render_3d);
|
log_setting("Stereoscopy_MonoRenderLeftEye", values.mono_render_left_eye.GetValue());
|
||||||
log_setting("Stereoscopy_Factor3d", values.factor_3d);
|
log_setting("Layout_LayoutOption", values.layout_option.GetValue());
|
||||||
log_setting("Stereoscopy_MonoRenderLeftEye", values.mono_render_left_eye);
|
log_setting("Layout_SwapScreen", values.swap_screen.GetValue());
|
||||||
log_setting("Layout_LayoutOption", values.layout_option);
|
log_setting("Layout_UprightScreen", values.upright_screen.GetValue());
|
||||||
log_setting("Layout_SwapScreen", values.swap_screen);
|
log_setting("Utility_DumpTextures", values.dump_textures.GetValue());
|
||||||
log_setting("Layout_UprightScreen", values.upright_screen);
|
log_setting("Utility_CustomTextures", values.custom_textures.GetValue());
|
||||||
log_setting("Utility_DumpTextures", values.dump_textures);
|
log_setting("Utility_UseDiskShaderCache", values.use_disk_shader_cache.GetValue());
|
||||||
log_setting("Utility_CustomTextures", values.custom_textures);
|
log_setting("Audio_Emulation", to_string(values.audio_emulation.GetValue()));
|
||||||
log_setting("Utility_UseDiskShaderCache", values.use_disk_shader_cache);
|
log_setting("Audio_OutputEngine", values.sink_id.GetValue());
|
||||||
log_setting("Audio_EnableDspLle", values.enable_dsp_lle);
|
log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
|
||||||
log_setting("Audio_EnableDspLleMultithread", values.enable_dsp_lle_multithread);
|
log_setting("Audio_OutputDevice", values.audio_device_id.GetValue());
|
||||||
log_setting("Audio_OutputEngine", values.sink_id);
|
log_setting("Audio_InputDeviceType", values.mic_input_type.GetValue());
|
||||||
log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching);
|
log_setting("Audio_InputDevice", values.mic_input_device.GetValue());
|
||||||
log_setting("Audio_OutputDevice", values.audio_device_id);
|
|
||||||
log_setting("Audio_InputDeviceType", values.mic_input_type);
|
|
||||||
log_setting("Audio_InputDevice", values.mic_input_device);
|
|
||||||
using namespace Service::CAM;
|
using namespace Service::CAM;
|
||||||
log_setting("Camera_OuterRightName", values.camera_name[OuterRightCamera]);
|
log_setting("Camera_OuterRightName", values.camera_name[OuterRightCamera]);
|
||||||
log_setting("Camera_OuterRightConfig", values.camera_config[OuterRightCamera]);
|
log_setting("Camera_OuterRightConfig", values.camera_config[OuterRightCamera]);
|
||||||
|
@ -119,23 +128,68 @@ void LogSettings() {
|
||||||
log_setting("Camera_OuterLeftName", values.camera_name[OuterLeftCamera]);
|
log_setting("Camera_OuterLeftName", values.camera_name[OuterLeftCamera]);
|
||||||
log_setting("Camera_OuterLeftConfig", values.camera_config[OuterLeftCamera]);
|
log_setting("Camera_OuterLeftConfig", values.camera_config[OuterLeftCamera]);
|
||||||
log_setting("Camera_OuterLeftFlip", values.camera_flip[OuterLeftCamera]);
|
log_setting("Camera_OuterLeftFlip", values.camera_flip[OuterLeftCamera]);
|
||||||
log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd);
|
log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd.GetValue());
|
||||||
log_setting("DataStorage_UseCustomStorage", values.use_custom_storage);
|
log_setting("DataStorage_UseCustomStorage", values.use_custom_storage.GetValue());
|
||||||
if (values.use_custom_storage) {
|
if (values.use_custom_storage) {
|
||||||
log_setting("DataStorage_SdmcDir", FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));
|
log_setting("DataStorage_SdmcDir", FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));
|
||||||
log_setting("DataStorage_NandDir", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
|
log_setting("DataStorage_NandDir", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
|
||||||
}
|
}
|
||||||
log_setting("System_IsNew3ds", values.is_new_3ds);
|
log_setting("System_IsNew3ds", values.is_new_3ds.GetValue());
|
||||||
log_setting("System_RegionValue", values.region_value);
|
log_setting("System_RegionValue", values.region_value.GetValue());
|
||||||
log_setting("Debugging_UseGdbstub", values.use_gdbstub);
|
log_setting("Debugging_UseGdbstub", values.use_gdbstub.GetValue());
|
||||||
log_setting("Debugging_GdbstubPort", values.gdbstub_port);
|
log_setting("Debugging_GdbstubPort", values.gdbstub_port.GetValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsConfiguringGlobal() {
|
||||||
|
return configuring_global;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetConfiguringGlobal(bool is_global) {
|
||||||
|
configuring_global = is_global;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Volume() {
|
float Volume() {
|
||||||
if (values.audio_muted) {
|
if (values.audio_muted) {
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
return values.volume;
|
return values.volume.GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestoreGlobalState(bool is_powered_on) {
|
||||||
|
// If a game is running, DO NOT restore the global settings state
|
||||||
|
if (is_powered_on) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
values.audio_emulation.SetGlobal(true);
|
||||||
|
values.enable_audio_stretching.SetGlobal(true);
|
||||||
|
values.volume.SetGlobal(true);
|
||||||
|
|
||||||
|
// Core
|
||||||
|
values.cpu_clock_percentage.SetGlobal(true);
|
||||||
|
values.is_new_3ds.SetGlobal(true);
|
||||||
|
|
||||||
|
// Renderer
|
||||||
|
values.use_hw_renderer.SetGlobal(true);
|
||||||
|
values.use_hw_shader.SetGlobal(true);
|
||||||
|
values.separable_shader.SetGlobal(true);
|
||||||
|
values.use_disk_shader_cache.SetGlobal(true);
|
||||||
|
values.shaders_accurate_mul.SetGlobal(true);
|
||||||
|
values.use_vsync_new.SetGlobal(true);
|
||||||
|
values.resolution_factor.SetGlobal(true);
|
||||||
|
values.frame_limit.SetGlobal(true);
|
||||||
|
values.texture_filter_name.SetGlobal(true);
|
||||||
|
values.layout_option.SetGlobal(true);
|
||||||
|
values.swap_screen.SetGlobal(true);
|
||||||
|
values.upright_screen.SetGlobal(true);
|
||||||
|
values.bg_red.SetGlobal(true);
|
||||||
|
values.bg_green.SetGlobal(true);
|
||||||
|
values.bg_blue.SetGlobal(true);
|
||||||
|
values.render_3d.SetGlobal(true);
|
||||||
|
values.factor_3d.SetGlobal(true);
|
||||||
|
values.filter_mode.SetGlobal(true);
|
||||||
|
values.pp_shader_name.SetGlobal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadProfile(int index) {
|
void LoadProfile(int index) {
|
538
src/common/settings.h
Normal file
538
src/common/settings.h
Normal file
|
@ -0,0 +1,538 @@
|
||||||
|
// Copyright 2014 Citra Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <atomic>
|
||||||
|
#include <string>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/hle/service/cam/cam_params.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
|
||||||
|
enum class InitClock : u32 {
|
||||||
|
SystemTime = 0,
|
||||||
|
FixedTime = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class LayoutOption : u32 {
|
||||||
|
Default,
|
||||||
|
SingleScreen,
|
||||||
|
LargeScreen,
|
||||||
|
SideScreen,
|
||||||
|
#ifndef ANDROID
|
||||||
|
SeparateWindows,
|
||||||
|
#endif
|
||||||
|
// Similiar to default, but better for mobile devices in portrait mode. Top screen in clamped to
|
||||||
|
// the top of the frame, and the bottom screen is enlarged to match the top screen.
|
||||||
|
MobilePortrait,
|
||||||
|
|
||||||
|
// Similiar to LargeScreen, but better for mobile devices in landscape mode. The screens are
|
||||||
|
// clamped to the top of the frame, and the bottom screen is a bit bigger.
|
||||||
|
MobileLandscape,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MicInputType : u32 {
|
||||||
|
None = 0,
|
||||||
|
Real = 1,
|
||||||
|
Static = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class StereoRenderOption : u32 {
|
||||||
|
Off = 0,
|
||||||
|
SideBySide = 1,
|
||||||
|
Anaglyph = 2,
|
||||||
|
Interlaced = 3,
|
||||||
|
ReverseInterlaced = 4,
|
||||||
|
CardboardVR = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class AudioEmulation : u32 { HLE = 0, LLE = 1, LLEMultithreaded = 2 };
|
||||||
|
|
||||||
|
namespace NativeButton {
|
||||||
|
|
||||||
|
enum Values {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
L,
|
||||||
|
R,
|
||||||
|
Start,
|
||||||
|
Select,
|
||||||
|
Debug,
|
||||||
|
Gpio14,
|
||||||
|
|
||||||
|
ZL,
|
||||||
|
ZR,
|
||||||
|
|
||||||
|
Home,
|
||||||
|
|
||||||
|
NumButtons,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int BUTTON_HID_BEGIN = A;
|
||||||
|
constexpr int BUTTON_IR_BEGIN = ZL;
|
||||||
|
constexpr int BUTTON_NS_BEGIN = Home;
|
||||||
|
|
||||||
|
constexpr int BUTTON_HID_END = BUTTON_IR_BEGIN;
|
||||||
|
constexpr int BUTTON_IR_END = BUTTON_NS_BEGIN;
|
||||||
|
constexpr int BUTTON_NS_END = NumButtons;
|
||||||
|
|
||||||
|
constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
|
||||||
|
constexpr int NUM_BUTTONS_IR = BUTTON_IR_END - BUTTON_IR_BEGIN;
|
||||||
|
constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
|
||||||
|
|
||||||
|
static const std::array<const char*, NumButtons> mapping = {{
|
||||||
|
"button_a",
|
||||||
|
"button_b",
|
||||||
|
"button_x",
|
||||||
|
"button_y",
|
||||||
|
"button_up",
|
||||||
|
"button_down",
|
||||||
|
"button_left",
|
||||||
|
"button_right",
|
||||||
|
"button_l",
|
||||||
|
"button_r",
|
||||||
|
"button_start",
|
||||||
|
"button_select",
|
||||||
|
"button_debug",
|
||||||
|
"button_gpio14",
|
||||||
|
"button_zl",
|
||||||
|
"button_zr",
|
||||||
|
"button_home",
|
||||||
|
}};
|
||||||
|
|
||||||
|
} // namespace NativeButton
|
||||||
|
|
||||||
|
namespace NativeAnalog {
|
||||||
|
enum Values {
|
||||||
|
CirclePad,
|
||||||
|
CStick,
|
||||||
|
NumAnalogs,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr std::array<const char*, NumAnalogs> mapping = {{
|
||||||
|
"circle_pad",
|
||||||
|
"c_stick",
|
||||||
|
}};
|
||||||
|
} // namespace NativeAnalog
|
||||||
|
|
||||||
|
/** The Setting class is a simple resource manager. It defines a label and default value alongside
|
||||||
|
* the actual value of the setting for simpler and less-error prone use with frontend
|
||||||
|
* configurations. Specifying a default value and label is required. A minimum and maximum range can
|
||||||
|
* be specified for sanitization.
|
||||||
|
*/
|
||||||
|
template <typename Type, bool ranged = false>
|
||||||
|
class Setting {
|
||||||
|
protected:
|
||||||
|
Setting() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only sets the setting to the given initializer, leaving the other members to their default
|
||||||
|
* initializers.
|
||||||
|
*
|
||||||
|
* @param global_val Initial value of the setting
|
||||||
|
*/
|
||||||
|
explicit Setting(const Type& val) : value{val} {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Sets a default value, label, and setting value.
|
||||||
|
*
|
||||||
|
* @param default_val Intial value of the setting, and default value of the setting
|
||||||
|
* @param name Label for the setting
|
||||||
|
*/
|
||||||
|
explicit Setting(const Type& default_val, const std::string& name) requires(!ranged)
|
||||||
|
: value{default_val}, default_value{default_val}, label{name} {}
|
||||||
|
virtual ~Setting() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a default value, minimum value, maximum value, and label.
|
||||||
|
*
|
||||||
|
* @param default_val Intial value of the setting, and default value of the setting
|
||||||
|
* @param min_val Sets the minimum allowed value of the setting
|
||||||
|
* @param max_val Sets the maximum allowed value of the setting
|
||||||
|
* @param name Label for the setting
|
||||||
|
*/
|
||||||
|
explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val,
|
||||||
|
const std::string& name) requires(ranged)
|
||||||
|
: value{default_val},
|
||||||
|
default_value{default_val}, maximum{max_val}, minimum{min_val}, label{name} {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the setting's value.
|
||||||
|
*
|
||||||
|
* @returns A reference to the setting
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual const Type& GetValue() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the setting to the given value.
|
||||||
|
*
|
||||||
|
* @param val The desired value
|
||||||
|
*/
|
||||||
|
virtual void SetValue(const Type& val) {
|
||||||
|
Type temp{ranged ? std::clamp(val, minimum, maximum) : val};
|
||||||
|
std::swap(value, temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value that this setting was created with.
|
||||||
|
*
|
||||||
|
* @returns A reference to the default value
|
||||||
|
*/
|
||||||
|
[[nodiscard]] const Type& GetDefault() const {
|
||||||
|
return default_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the label this setting was created with.
|
||||||
|
*
|
||||||
|
* @returns A reference to the label
|
||||||
|
*/
|
||||||
|
[[nodiscard]] const std::string& GetLabel() const {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns a value to the setting.
|
||||||
|
*
|
||||||
|
* @param val The desired setting value
|
||||||
|
*
|
||||||
|
* @returns A reference to the setting
|
||||||
|
*/
|
||||||
|
virtual const Type& operator=(const Type& val) {
|
||||||
|
Type temp{ranged ? std::clamp(val, minimum, maximum) : val};
|
||||||
|
std::swap(value, temp);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a reference to the setting.
|
||||||
|
*
|
||||||
|
* @returns A reference to the setting
|
||||||
|
*/
|
||||||
|
explicit virtual operator const Type&() const {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Type value{}; ///< The setting
|
||||||
|
const Type default_value{}; ///< The default value
|
||||||
|
const Type maximum{}; ///< Maximum allowed value of the setting
|
||||||
|
const Type minimum{}; ///< Minimum allowed value of the setting
|
||||||
|
const std::string label{}; ///< The setting's label
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The SwitchableSetting class is a slightly more complex version of the Setting class. This adds a
|
||||||
|
* custom setting to switch to when a guest application specifically requires it. The effect is that
|
||||||
|
* other components of the emulator can access the setting's intended value without any need for the
|
||||||
|
* component to ask whether the custom or global setting is needed at the moment.
|
||||||
|
*
|
||||||
|
* By default, the global setting is used.
|
||||||
|
*/
|
||||||
|
template <typename Type, bool ranged = false>
|
||||||
|
class SwitchableSetting : virtual public Setting<Type, ranged> {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Sets a default value, label, and setting value.
|
||||||
|
*
|
||||||
|
* @param default_val Intial value of the setting, and default value of the setting
|
||||||
|
* @param name Label for the setting
|
||||||
|
*/
|
||||||
|
explicit SwitchableSetting(const Type& default_val, const std::string& name) requires(!ranged)
|
||||||
|
: Setting<Type>{default_val, name} {}
|
||||||
|
virtual ~SwitchableSetting() = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a default value, minimum value, maximum value, and label.
|
||||||
|
*
|
||||||
|
* @param default_val Intial value of the setting, and default value of the setting
|
||||||
|
* @param min_val Sets the minimum allowed value of the setting
|
||||||
|
* @param max_val Sets the maximum allowed value of the setting
|
||||||
|
* @param name Label for the setting
|
||||||
|
*/
|
||||||
|
explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val,
|
||||||
|
const std::string& name) requires(ranged)
|
||||||
|
: Setting<Type, true>{default_val, min_val, max_val, name} {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells this setting to represent either the global or custom setting when other member
|
||||||
|
* functions are used.
|
||||||
|
*
|
||||||
|
* @param to_global Whether to use the global or custom setting.
|
||||||
|
*/
|
||||||
|
void SetGlobal(bool to_global) {
|
||||||
|
use_global = to_global;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether this setting is using the global setting or not.
|
||||||
|
*
|
||||||
|
* @returns The global state
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool UsingGlobal() const {
|
||||||
|
return use_global;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns either the global or custom setting depending on the values of this setting's global
|
||||||
|
* state or if the global value was specifically requested.
|
||||||
|
*
|
||||||
|
* @param need_global Request global value regardless of setting's state; defaults to false
|
||||||
|
*
|
||||||
|
* @returns The required value of the setting
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual const Type& GetValue() const override {
|
||||||
|
if (use_global) {
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
[[nodiscard]] virtual const Type& GetValue(bool need_global) const {
|
||||||
|
if (use_global || need_global) {
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current setting value depending on the global state.
|
||||||
|
*
|
||||||
|
* @param val The new value
|
||||||
|
*/
|
||||||
|
void SetValue(const Type& val) override {
|
||||||
|
Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val};
|
||||||
|
if (use_global) {
|
||||||
|
std::swap(this->value, temp);
|
||||||
|
} else {
|
||||||
|
std::swap(custom, temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns the current setting value depending on the global state.
|
||||||
|
*
|
||||||
|
* @param val The new value
|
||||||
|
*
|
||||||
|
* @returns A reference to the current setting value
|
||||||
|
*/
|
||||||
|
const Type& operator=(const Type& val) override {
|
||||||
|
Type temp{ranged ? std::clamp(val, this->minimum, this->maximum) : val};
|
||||||
|
if (use_global) {
|
||||||
|
std::swap(this->value, temp);
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
std::swap(custom, temp);
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current setting value depending on the global state.
|
||||||
|
*
|
||||||
|
* @returns A reference to the current setting value
|
||||||
|
*/
|
||||||
|
virtual explicit operator const Type&() const override {
|
||||||
|
if (use_global) {
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool use_global{true}; ///< The setting's global state
|
||||||
|
Type custom{}; ///< The custom value of the setting
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The InputSetting class allows for getting a reference to either the global or custom members.
|
||||||
|
* This is required as we cannot easily modify the values of user-defined types within containers
|
||||||
|
* using the SetValue() member function found in the Setting class. The primary purpose of this
|
||||||
|
* class is to store an array of 10 PlayerInput structs for both the global and custom setting and
|
||||||
|
* allows for easily accessing and modifying both settings.
|
||||||
|
*/
|
||||||
|
template <typename Type>
|
||||||
|
class InputSetting final {
|
||||||
|
public:
|
||||||
|
InputSetting() = default;
|
||||||
|
explicit InputSetting(Type val) : Setting<Type>(val) {}
|
||||||
|
~InputSetting() = default;
|
||||||
|
void SetGlobal(bool to_global) {
|
||||||
|
use_global = to_global;
|
||||||
|
}
|
||||||
|
[[nodiscard]] bool UsingGlobal() const {
|
||||||
|
return use_global;
|
||||||
|
}
|
||||||
|
[[nodiscard]] Type& GetValue(bool need_global = false) {
|
||||||
|
if (use_global || need_global) {
|
||||||
|
return global;
|
||||||
|
}
|
||||||
|
return custom;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool use_global{true}; ///< The setting's global state
|
||||||
|
Type global{}; ///< The setting
|
||||||
|
Type custom{}; ///< The custom setting value
|
||||||
|
};
|
||||||
|
|
||||||
|
struct InputProfile {
|
||||||
|
std::string name;
|
||||||
|
std::array<std::string, NativeButton::NumButtons> buttons;
|
||||||
|
std::array<std::string, NativeAnalog::NumAnalogs> analogs;
|
||||||
|
std::string motion_device;
|
||||||
|
std::string touch_device;
|
||||||
|
bool use_touch_from_button;
|
||||||
|
int touch_from_button_map_index;
|
||||||
|
std::string udp_input_address;
|
||||||
|
u16 udp_input_port;
|
||||||
|
u8 udp_pad_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TouchFromButtonMap {
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::string> buttons;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A special region value indicating that citra will automatically select a region
|
||||||
|
/// value to fit the region lockout info of the game
|
||||||
|
static constexpr s32 REGION_VALUE_AUTO_SELECT = -1;
|
||||||
|
|
||||||
|
struct Values {
|
||||||
|
// Controls
|
||||||
|
InputProfile current_input_profile; ///< The current input profile
|
||||||
|
int current_input_profile_index; ///< The current input profile index
|
||||||
|
std::vector<InputProfile> input_profiles; ///< The list of input profiles
|
||||||
|
std::vector<TouchFromButtonMap> touch_from_button_maps;
|
||||||
|
|
||||||
|
// Core
|
||||||
|
Setting<bool> use_cpu_jit{true, "use_cpu_jit"};
|
||||||
|
SwitchableSetting<s32, true> cpu_clock_percentage{100, 5, 400, "cpu_clock_percentage"};
|
||||||
|
SwitchableSetting<bool> is_new_3ds{true, "is_new_3ds"};
|
||||||
|
|
||||||
|
// Data Storage
|
||||||
|
Setting<bool> use_virtual_sd{true, "use_virtual_sd"};
|
||||||
|
Setting<bool> use_custom_storage{false, "use_custom_storage"};
|
||||||
|
|
||||||
|
// System
|
||||||
|
SwitchableSetting<s32> region_value{REGION_VALUE_AUTO_SELECT, "region_value"};
|
||||||
|
Setting<InitClock> init_clock{InitClock::SystemTime, "init_clock"};
|
||||||
|
Setting<u64> init_time{946681277ULL, "init_time"};
|
||||||
|
Setting<s64> init_time_offset{0, "init_time_offset"};
|
||||||
|
|
||||||
|
// Renderer
|
||||||
|
Setting<bool> use_gles{false, "use_gles"};
|
||||||
|
SwitchableSetting<bool> use_hw_renderer{true, "use_hw_renderer"};
|
||||||
|
SwitchableSetting<bool> use_hw_shader{true, "use_hw_shader"};
|
||||||
|
SwitchableSetting<bool> separable_shader{false, "use_separable_shader"};
|
||||||
|
SwitchableSetting<bool> use_disk_shader_cache{true, "use_disk_shader_cache"};
|
||||||
|
SwitchableSetting<bool> shaders_accurate_mul{true, "shaders_accurate_mul"};
|
||||||
|
SwitchableSetting<bool> use_vsync_new{true, "use_vsync_new"};
|
||||||
|
Setting<bool> use_shader_jit{true, "use_shader_jit"};
|
||||||
|
SwitchableSetting<u16, true> resolution_factor{1, 1, 10, "resolution_factor"};
|
||||||
|
SwitchableSetting<u16, true> frame_limit{100, 0, 1000, "frame_limit"};
|
||||||
|
SwitchableSetting<std::string> texture_filter_name{"none", "texture_filter_name"};
|
||||||
|
|
||||||
|
SwitchableSetting<LayoutOption> layout_option{LayoutOption::Default, "layout_option"};
|
||||||
|
SwitchableSetting<bool> swap_screen{false, "swap_screen"};
|
||||||
|
SwitchableSetting<bool> upright_screen{false, "upright_screen"};
|
||||||
|
Setting<bool> custom_layout{false, "custom_layout"};
|
||||||
|
Setting<u16> custom_top_left{0, "custom_top_left"};
|
||||||
|
Setting<u16> custom_top_top{0, "custom_top_top"};
|
||||||
|
Setting<u16> custom_top_right{400, "custom_top_right"};
|
||||||
|
Setting<u16> custom_top_bottom{240, "custom_top_bottom"};
|
||||||
|
Setting<u16> custom_bottom_left{40, "custom_bottom_left"};
|
||||||
|
Setting<u16> custom_bottom_top{240, "custom_bottom_top"};
|
||||||
|
Setting<u16> custom_bottom_right{360, "custom_bottom_right"};
|
||||||
|
Setting<u16> custom_bottom_bottom{480, "custom_bottom_bottom"};
|
||||||
|
|
||||||
|
SwitchableSetting<double> bg_red{0.f, "bg_red"};
|
||||||
|
SwitchableSetting<double> bg_green{0.f, "bg_green"};
|
||||||
|
SwitchableSetting<double> bg_blue{0.f, "bg_blue"};
|
||||||
|
|
||||||
|
SwitchableSetting<StereoRenderOption> render_3d{StereoRenderOption::Off, "render_3d"};
|
||||||
|
SwitchableSetting<u32> factor_3d{0, "factor_3d"};
|
||||||
|
|
||||||
|
Setting<bool> mono_render_left_eye{false, "mono_render_left_eye"};
|
||||||
|
Setting<s32> cardboard_screen_size{85, "cardboard_screen_size"};
|
||||||
|
Setting<s32> cardboard_x_shift{0, "cardboard_x_shift"};
|
||||||
|
Setting<s32> cardboard_y_shift{0, "cardboard_y_shift"};
|
||||||
|
|
||||||
|
SwitchableSetting<bool> filter_mode{true, "filter_mode"};
|
||||||
|
SwitchableSetting<std::string> pp_shader_name{"none (builtin)", "pp_shader_name"};
|
||||||
|
|
||||||
|
Setting<bool> dump_textures{false, "dump_textures"};
|
||||||
|
Setting<bool> custom_textures{false, "custom_textures"};
|
||||||
|
Setting<bool> preload_textures{false, "preload_textures"};
|
||||||
|
|
||||||
|
// Audio
|
||||||
|
bool audio_muted;
|
||||||
|
SwitchableSetting<AudioEmulation> audio_emulation{AudioEmulation::HLE, "audio_emulation"};
|
||||||
|
Setting<std::string> sink_id{"auto", "output_engine"};
|
||||||
|
SwitchableSetting<bool> enable_audio_stretching{true, "enable_audio_stretching"};
|
||||||
|
Setting<std::string> audio_device_id{"auto", "output_device"};
|
||||||
|
SwitchableSetting<float, true> volume{1.f, 0.f, 1.f, "volume"};
|
||||||
|
Setting<MicInputType> mic_input_type{MicInputType::None, "mic_input_type"};
|
||||||
|
Setting<std::string> mic_input_device{"Default", "mic_input_device"};
|
||||||
|
|
||||||
|
// Camera
|
||||||
|
std::array<std::string, Service::CAM::NumCameras> camera_name;
|
||||||
|
std::array<std::string, Service::CAM::NumCameras> camera_config;
|
||||||
|
std::array<int, Service::CAM::NumCameras> camera_flip;
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
bool record_frame_times;
|
||||||
|
std::unordered_map<std::string, bool> lle_modules;
|
||||||
|
Setting<bool> use_gdbstub{false, "use_gdbstub"};
|
||||||
|
Setting<u16> gdbstub_port{24689, "gdbstub_port"};
|
||||||
|
|
||||||
|
// Miscellaneous
|
||||||
|
Setting<std::string> log_filter{"*:Info", "log_filter"};
|
||||||
|
|
||||||
|
// Video Dumping
|
||||||
|
std::string output_format;
|
||||||
|
std::string format_options;
|
||||||
|
|
||||||
|
std::string video_encoder;
|
||||||
|
std::string video_encoder_options;
|
||||||
|
u64 video_bitrate;
|
||||||
|
|
||||||
|
std::string audio_encoder;
|
||||||
|
std::string audio_encoder_options;
|
||||||
|
u64 audio_bitrate;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Values values;
|
||||||
|
|
||||||
|
bool IsConfiguringGlobal();
|
||||||
|
void SetConfiguringGlobal(bool is_global);
|
||||||
|
|
||||||
|
float Volume();
|
||||||
|
|
||||||
|
void Apply();
|
||||||
|
void LogSettings();
|
||||||
|
|
||||||
|
// Restore the global state of all applicable settings in the Values struct
|
||||||
|
void RestoreGlobalState(bool is_powered_on);
|
||||||
|
|
||||||
|
// Input profiles
|
||||||
|
void LoadProfile(int index);
|
||||||
|
void SaveProfile(int index);
|
||||||
|
void CreateProfile(std::string name);
|
||||||
|
void DeleteProfile(int index);
|
||||||
|
void RenameCurrentProfile(std::string new_name);
|
||||||
|
|
||||||
|
} // namespace Settings
|
|
@ -454,8 +454,6 @@ add_library(core STATIC
|
||||||
rpc/udp_server.h
|
rpc/udp_server.h
|
||||||
savestate.cpp
|
savestate.cpp
|
||||||
savestate.h
|
savestate.h
|
||||||
settings.cpp
|
|
||||||
settings.h
|
|
||||||
telemetry_session.cpp
|
telemetry_session.cpp
|
||||||
telemetry_session.h
|
telemetry_session.h
|
||||||
tracer/citrace.h
|
tracer/citrace.h
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
|
#if defined(ARCHITECTURE_x86_64) || defined(ARCHITECTURE_arm64)
|
||||||
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
#include "core/arm/dynarmic/arm_exclusive_monitor.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/arm/exclusive_monitor.h"
|
#include "core/arm/exclusive_monitor.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include "common/common_types.h"
|
||||||
#include "core/cheats/cheat_base.h"
|
#include "core/cheats/cheat_base.h"
|
||||||
|
|
||||||
namespace Cheats {
|
namespace Cheats {
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#ifdef ENABLE_FFMPEG_VIDEO_DUMPER
|
#ifdef ENABLE_FFMPEG_VIDEO_DUMPER
|
||||||
#include "core/dumping/ffmpeg_backend.h"
|
#include "core/dumping/ffmpeg_backend.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/custom_tex_cache.h"
|
#include "core/custom_tex_cache.h"
|
||||||
#include "core/gdbstub/gdbstub.h"
|
#include "core/gdbstub/gdbstub.h"
|
||||||
#include "core/global.h"
|
#include "core/global.h"
|
||||||
|
@ -45,7 +46,6 @@
|
||||||
#include "core/loader/loader.h"
|
#include "core/loader/loader.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "core/rpc/rpc_server.h"
|
#include "core/rpc/rpc_server.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
@ -365,7 +365,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
|
||||||
|
|
||||||
memory = std::make_unique<Memory::MemorySystem>();
|
memory = std::make_unique<Memory::MemorySystem>();
|
||||||
|
|
||||||
timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage);
|
timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage.GetValue());
|
||||||
|
|
||||||
kernel = std::make_unique<Kernel::KernelSystem>(
|
kernel = std::make_unique<Kernel::KernelSystem>(
|
||||||
*memory, *timing, [this] { PrepareReschedule(); }, system_mode, num_cores, n3ds_mode);
|
*memory, *timing, [this] { PrepareReschedule(); }, system_mode, num_cores, n3ds_mode);
|
||||||
|
@ -395,17 +395,19 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
|
||||||
kernel->SetCPUs(cpu_cores);
|
kernel->SetCPUs(cpu_cores);
|
||||||
kernel->SetRunningCPU(cpu_cores[0].get());
|
kernel->SetRunningCPU(cpu_cores[0].get());
|
||||||
|
|
||||||
if (Settings::values.enable_dsp_lle) {
|
const auto audio_emulation = Settings::values.audio_emulation.GetValue();
|
||||||
dsp_core = std::make_unique<AudioCore::DspLle>(*memory,
|
if (audio_emulation == Settings::AudioEmulation::HLE) {
|
||||||
Settings::values.enable_dsp_lle_multithread);
|
|
||||||
} else {
|
|
||||||
dsp_core = std::make_unique<AudioCore::DspHle>(*memory);
|
dsp_core = std::make_unique<AudioCore::DspHle>(*memory);
|
||||||
|
} else {
|
||||||
|
const bool multithread = audio_emulation == Settings::AudioEmulation::LLEMultithreaded;
|
||||||
|
dsp_core = std::make_unique<AudioCore::DspLle>(*memory, multithread);
|
||||||
}
|
}
|
||||||
|
|
||||||
memory->SetDSP(*dsp_core);
|
memory->SetDSP(*dsp_core);
|
||||||
|
|
||||||
dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id);
|
dsp_core->SetSink(Settings::values.sink_id.GetValue(),
|
||||||
dsp_core->EnableStretching(Settings::values.enable_audio_stretching);
|
Settings::values.audio_device_id.GetValue());
|
||||||
|
dsp_core->EnableStretching(Settings::values.enable_audio_stretching.GetValue());
|
||||||
|
|
||||||
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,10 @@
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/dumping/ffmpeg_backend.h"
|
#include "core/dumping/ffmpeg_backend.h"
|
||||||
#include "core/hw/gpu.h"
|
#include "core/hw/gpu.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,11 @@
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/file_sys/archive_sdmc.h"
|
#include "core/file_sys/archive_sdmc.h"
|
||||||
#include "core/file_sys/disk_archive.h"
|
#include "core/file_sys/disk_archive.h"
|
||||||
#include "core/file_sys/errors.h"
|
#include "core/file_sys/errors.h"
|
||||||
#include "core/file_sys/path_parser.h"
|
#include "core/file_sys/path_parser.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// FileSys namespace
|
// FileSys namespace
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/file_sys/archive_sdmcwriteonly.h"
|
#include "core/file_sys/archive_sdmcwriteonly.h"
|
||||||
#include "core/file_sys/directory_backend.h"
|
#include "core/file_sys/directory_backend.h"
|
||||||
#include "core/file_sys/errors.h"
|
#include "core/file_sys/errors.h"
|
||||||
#include "core/file_sys/file_backend.h"
|
#include "core/file_sys/file_backend.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// FileSys namespace
|
// FileSys namespace
|
||||||
|
|
|
@ -4,9 +4,10 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include "common/settings.h"
|
||||||
|
#include "core/3ds.h"
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
#include "core/frontend/input.h"
|
#include "core/frontend/input.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
namespace Frontend {
|
namespace Frontend {
|
||||||
/// We need a global touch state that is shared across the different window instances
|
/// We need a global touch state that is shared across the different window instances
|
||||||
|
@ -63,14 +64,14 @@ EmuWindow::~EmuWindow() = default;
|
||||||
*/
|
*/
|
||||||
static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x,
|
static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x,
|
||||||
unsigned framebuffer_y) {
|
unsigned framebuffer_y) {
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) {
|
||||||
return (framebuffer_y >= layout.bottom_screen.top &&
|
return (framebuffer_y >= layout.bottom_screen.top &&
|
||||||
framebuffer_y < layout.bottom_screen.bottom &&
|
framebuffer_y < layout.bottom_screen.bottom &&
|
||||||
((framebuffer_x >= layout.bottom_screen.left / 2 &&
|
((framebuffer_x >= layout.bottom_screen.left / 2 &&
|
||||||
framebuffer_x < layout.bottom_screen.right / 2) ||
|
framebuffer_x < layout.bottom_screen.right / 2) ||
|
||||||
(framebuffer_x >= (layout.bottom_screen.left / 2) + (layout.width / 2) &&
|
(framebuffer_x >= (layout.bottom_screen.left / 2) + (layout.width / 2) &&
|
||||||
framebuffer_x < (layout.bottom_screen.right / 2) + (layout.width / 2))));
|
framebuffer_x < (layout.bottom_screen.right / 2) + (layout.width / 2))));
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) {
|
} else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) {
|
||||||
return (framebuffer_y >= layout.bottom_screen.top &&
|
return (framebuffer_y >= layout.bottom_screen.top &&
|
||||||
framebuffer_y < layout.bottom_screen.bottom &&
|
framebuffer_y < layout.bottom_screen.bottom &&
|
||||||
((framebuffer_x >= layout.bottom_screen.left &&
|
((framebuffer_x >= layout.bottom_screen.left &&
|
||||||
|
@ -88,13 +89,13 @@ static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigne
|
||||||
|
|
||||||
std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) const {
|
std::tuple<unsigned, unsigned> EmuWindow::ClipToTouchScreen(unsigned new_x, unsigned new_y) const {
|
||||||
if (new_x >= framebuffer_layout.width / 2) {
|
if (new_x >= framebuffer_layout.width / 2) {
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide)
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide)
|
||||||
new_x -= framebuffer_layout.width / 2;
|
new_x -= framebuffer_layout.width / 2;
|
||||||
else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR)
|
else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR)
|
||||||
new_x -=
|
new_x -=
|
||||||
(framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2);
|
(framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2);
|
||||||
}
|
}
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) {
|
||||||
new_x = std::max(new_x, framebuffer_layout.bottom_screen.left / 2);
|
new_x = std::max(new_x, framebuffer_layout.bottom_screen.left / 2);
|
||||||
new_x = std::min(new_x, framebuffer_layout.bottom_screen.right / 2 - 1);
|
new_x = std::min(new_x, framebuffer_layout.bottom_screen.right / 2 - 1);
|
||||||
} else {
|
} else {
|
||||||
|
@ -122,14 +123,14 @@ bool EmuWindow::TouchPressed(unsigned framebuffer_x, unsigned framebuffer_y) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (framebuffer_x >= framebuffer_layout.width / 2) {
|
if (framebuffer_x >= framebuffer_layout.width / 2) {
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide)
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide)
|
||||||
framebuffer_x -= framebuffer_layout.width / 2;
|
framebuffer_x -= framebuffer_layout.width / 2;
|
||||||
else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR)
|
else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR)
|
||||||
framebuffer_x -=
|
framebuffer_x -=
|
||||||
(framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2);
|
(framebuffer_layout.width / 2) - (framebuffer_layout.cardboard.user_x_shift * 2);
|
||||||
}
|
}
|
||||||
std::lock_guard guard(touch_state->mutex);
|
std::lock_guard guard(touch_state->mutex);
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) {
|
||||||
touch_state->touch_x =
|
touch_state->touch_x =
|
||||||
static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) /
|
static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left / 2) /
|
||||||
(framebuffer_layout.bottom_screen.right / 2 -
|
(framebuffer_layout.bottom_screen.right / 2 -
|
||||||
|
@ -173,55 +174,59 @@ void EmuWindow::UpdateCurrentFramebufferLayout(unsigned width, unsigned height,
|
||||||
bool is_portrait_mode) {
|
bool is_portrait_mode) {
|
||||||
Layout::FramebufferLayout layout;
|
Layout::FramebufferLayout layout;
|
||||||
const auto layout_option = Settings::values.layout_option;
|
const auto layout_option = Settings::values.layout_option;
|
||||||
const auto min_size =
|
const auto min_size = Layout::GetMinimumSizeFromLayout(
|
||||||
Layout::GetMinimumSizeFromLayout(layout_option, Settings::values.upright_screen);
|
layout_option.GetValue(), Settings::values.upright_screen.GetValue());
|
||||||
|
|
||||||
if (Settings::values.custom_layout == true) {
|
if (Settings::values.custom_layout.GetValue() == true) {
|
||||||
layout = Layout::CustomFrameLayout(width, height);
|
layout = Layout::CustomFrameLayout(width, height);
|
||||||
} else {
|
} else {
|
||||||
width = std::max(width, min_size.first);
|
width = std::max(width, min_size.first);
|
||||||
height = std::max(height, min_size.second);
|
height = std::max(height, min_size.second);
|
||||||
|
|
||||||
// If in portrait mode, only the MobilePortrait option really makes sense
|
// If in portrait mode, only the MobilePortrait option really makes sense
|
||||||
const Settings::LayoutOption layout_option = is_portrait_mode
|
const Settings::LayoutOption layout_option =
|
||||||
? Settings::LayoutOption::MobilePortrait
|
is_portrait_mode ? Settings::LayoutOption::MobilePortrait
|
||||||
: Settings::values.layout_option;
|
: Settings::values.layout_option.GetValue();
|
||||||
|
|
||||||
switch (layout_option) {
|
switch (layout_option) {
|
||||||
case Settings::LayoutOption::SingleScreen:
|
case Settings::LayoutOption::SingleScreen:
|
||||||
layout = Layout::SingleFrameLayout(width, height, Settings::values.swap_screen,
|
layout =
|
||||||
Settings::values.upright_screen);
|
Layout::SingleFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||||
|
Settings::values.upright_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::LargeScreen:
|
case Settings::LayoutOption::LargeScreen:
|
||||||
layout = Layout::LargeFrameLayout(width, height, Settings::values.swap_screen,
|
layout =
|
||||||
Settings::values.upright_screen);
|
Layout::LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||||
|
Settings::values.upright_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::SideScreen:
|
case Settings::LayoutOption::SideScreen:
|
||||||
layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen,
|
layout = Layout::SideFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||||
Settings::values.upright_screen);
|
Settings::values.upright_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
#ifndef ANDROID
|
#ifndef ANDROID
|
||||||
case Settings::LayoutOption::SeparateWindows:
|
case Settings::LayoutOption::SeparateWindows:
|
||||||
layout = Layout::SeparateWindowsLayout(width, height, is_secondary,
|
layout = Layout::SeparateWindowsLayout(width, height, is_secondary,
|
||||||
Settings::values.upright_screen);
|
Settings::values.upright_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case Settings::LayoutOption::MobilePortrait:
|
case Settings::LayoutOption::MobilePortrait:
|
||||||
layout = Layout::MobilePortraitFrameLayout(width, height, Settings::values.swap_screen);
|
layout = Layout::MobilePortraitFrameLayout(width, height,
|
||||||
|
Settings::values.swap_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::MobileLandscape:
|
case Settings::LayoutOption::MobileLandscape:
|
||||||
layout = Layout::MobileLandscapeFrameLayout(width, height, Settings::values.swap_screen,
|
layout = Layout::MobileLandscapeFrameLayout(
|
||||||
2.25f, false);
|
width, height, Settings::values.swap_screen.GetValue(), 2.25f, false);
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::Default:
|
case Settings::LayoutOption::Default:
|
||||||
default:
|
default:
|
||||||
layout = Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen,
|
layout =
|
||||||
Settings::values.upright_screen);
|
Layout::DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||||
|
Settings::values.upright_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
UpdateMinimumWindowSize(min_size);
|
UpdateMinimumWindowSize(min_size);
|
||||||
}
|
}
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) {
|
||||||
layout = Layout::GetCardboardSettings(layout);
|
layout = Layout::GetCardboardSettings(layout);
|
||||||
}
|
}
|
||||||
NotifyFramebufferLayoutChanged(layout);
|
NotifyFramebufferLayoutChanged(layout);
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/3ds.h"
|
#include "core/3ds.h"
|
||||||
#include "core/frontend/framebuffer_layout.h"
|
#include "core/frontend/framebuffer_layout.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
|
|
||||||
|
@ -355,12 +355,14 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height) {
|
||||||
|
|
||||||
FramebufferLayout res{width, height, true, true, {}, {}, !Settings::values.upright_screen};
|
FramebufferLayout res{width, height, true, true, {}, {}, !Settings::values.upright_screen};
|
||||||
|
|
||||||
Common::Rectangle<u32> top_screen{
|
Common::Rectangle<u32> top_screen{Settings::values.custom_top_left.GetValue(),
|
||||||
Settings::values.custom_top_left, Settings::values.custom_top_top,
|
Settings::values.custom_top_top.GetValue(),
|
||||||
Settings::values.custom_top_right, Settings::values.custom_top_bottom};
|
Settings::values.custom_top_right.GetValue(),
|
||||||
Common::Rectangle<u32> bot_screen{
|
Settings::values.custom_top_bottom.GetValue()};
|
||||||
Settings::values.custom_bottom_left, Settings::values.custom_bottom_top,
|
Common::Rectangle<u32> bot_screen{Settings::values.custom_bottom_left.GetValue(),
|
||||||
Settings::values.custom_bottom_right, Settings::values.custom_bottom_bottom};
|
Settings::values.custom_bottom_top.GetValue(),
|
||||||
|
Settings::values.custom_bottom_right.GetValue(),
|
||||||
|
Settings::values.custom_bottom_bottom.GetValue()};
|
||||||
|
|
||||||
res.top_screen = top_screen;
|
res.top_screen = top_screen;
|
||||||
res.bottom_screen = bot_screen;
|
res.bottom_screen = bot_screen;
|
||||||
|
@ -369,20 +371,21 @@ FramebufferLayout CustomFrameLayout(u32 width, u32 height) {
|
||||||
|
|
||||||
FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary) {
|
FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondary) {
|
||||||
FramebufferLayout layout;
|
FramebufferLayout layout;
|
||||||
if (Settings::values.custom_layout == true) {
|
if (Settings::values.custom_layout.GetValue() == true) {
|
||||||
layout = CustomFrameLayout(
|
layout = CustomFrameLayout(std::max(Settings::values.custom_top_right.GetValue(),
|
||||||
std::max(Settings::values.custom_top_right, Settings::values.custom_bottom_right),
|
Settings::values.custom_bottom_right.GetValue()),
|
||||||
std::max(Settings::values.custom_top_bottom, Settings::values.custom_bottom_bottom));
|
std::max(Settings::values.custom_top_bottom.GetValue(),
|
||||||
|
Settings::values.custom_bottom_bottom.GetValue()));
|
||||||
} else {
|
} else {
|
||||||
int width, height;
|
int width, height;
|
||||||
switch (Settings::values.layout_option) {
|
switch (Settings::values.layout_option.GetValue()) {
|
||||||
case Settings::LayoutOption::SingleScreen:
|
case Settings::LayoutOption::SingleScreen:
|
||||||
#ifndef ANDROID
|
#ifndef ANDROID
|
||||||
case Settings::LayoutOption::SeparateWindows:
|
case Settings::LayoutOption::SeparateWindows:
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const bool swap_screens = is_secondary || Settings::values.swap_screen;
|
const bool swap_screens = is_secondary || Settings::values.swap_screen.GetValue();
|
||||||
if (Settings::values.upright_screen) {
|
if (Settings::values.upright_screen.GetValue()) {
|
||||||
if (swap_screens) {
|
if (swap_screens) {
|
||||||
width = Core::kScreenBottomHeight * res_scale;
|
width = Core::kScreenBottomHeight * res_scale;
|
||||||
height = Core::kScreenBottomWidth * res_scale;
|
height = Core::kScreenBottomWidth * res_scale;
|
||||||
|
@ -399,13 +402,13 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
|
||||||
height = Core::kScreenTopHeight * res_scale;
|
height = Core::kScreenTopHeight * res_scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layout =
|
layout = SingleFrameLayout(width, height, swap_screens,
|
||||||
SingleFrameLayout(width, height, swap_screens, Settings::values.upright_screen);
|
Settings::values.upright_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Settings::LayoutOption::LargeScreen:
|
case Settings::LayoutOption::LargeScreen:
|
||||||
if (Settings::values.upright_screen) {
|
if (Settings::values.upright_screen.GetValue()) {
|
||||||
if (Settings::values.swap_screen) {
|
if (Settings::values.swap_screen.GetValue()) {
|
||||||
width = Core::kScreenBottomHeight * res_scale;
|
width = Core::kScreenBottomHeight * res_scale;
|
||||||
height = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale;
|
height = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale;
|
||||||
} else {
|
} else {
|
||||||
|
@ -413,7 +416,7 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
|
||||||
height = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale;
|
height = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 4) * res_scale;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Settings::values.swap_screen) {
|
if (Settings::values.swap_screen.GetValue()) {
|
||||||
width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale;
|
width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 4) * res_scale;
|
||||||
height = Core::kScreenBottomHeight * res_scale;
|
height = Core::kScreenBottomHeight * res_scale;
|
||||||
} else {
|
} else {
|
||||||
|
@ -421,51 +424,52 @@ FramebufferLayout FrameLayoutFromResolutionScale(u32 res_scale, bool is_secondar
|
||||||
height = Core::kScreenTopHeight * res_scale;
|
height = Core::kScreenTopHeight * res_scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layout = LargeFrameLayout(width, height, Settings::values.swap_screen,
|
layout = LargeFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||||
Settings::values.upright_screen);
|
Settings::values.upright_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::SideScreen:
|
case Settings::LayoutOption::SideScreen:
|
||||||
if (Settings::values.upright_screen) {
|
if (Settings::values.upright_screen.GetValue()) {
|
||||||
width = Core::kScreenTopHeight * res_scale;
|
width = Core::kScreenTopHeight * res_scale;
|
||||||
height = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale;
|
height = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale;
|
||||||
} else {
|
} else {
|
||||||
width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale;
|
width = (Core::kScreenTopWidth + Core::kScreenBottomWidth) * res_scale;
|
||||||
height = Core::kScreenTopHeight * res_scale;
|
height = Core::kScreenTopHeight * res_scale;
|
||||||
}
|
}
|
||||||
layout = SideFrameLayout(width, height, Settings::values.swap_screen,
|
layout = SideFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||||
Settings::values.upright_screen);
|
Settings::values.upright_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::MobilePortrait:
|
case Settings::LayoutOption::MobilePortrait:
|
||||||
width = Core::kScreenTopWidth * res_scale;
|
width = Core::kScreenTopWidth * res_scale;
|
||||||
height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale;
|
height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale;
|
||||||
layout = MobilePortraitFrameLayout(width, height, Settings::values.swap_screen);
|
layout =
|
||||||
|
MobilePortraitFrameLayout(width, height, Settings::values.swap_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::MobileLandscape:
|
case Settings::LayoutOption::MobileLandscape:
|
||||||
if (Settings::values.swap_screen) {
|
if (Settings::values.swap_screen.GetValue()) {
|
||||||
width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 2.25f) * res_scale;
|
width = (Core::kScreenBottomWidth + Core::kScreenTopWidth / 2.25f) * res_scale;
|
||||||
height = Core::kScreenBottomHeight * res_scale;
|
height = Core::kScreenBottomHeight * res_scale;
|
||||||
} else {
|
} else {
|
||||||
width = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 2.25f) * res_scale;
|
width = (Core::kScreenTopWidth + Core::kScreenBottomWidth / 2.25f) * res_scale;
|
||||||
height = Core::kScreenTopHeight * res_scale;
|
height = Core::kScreenTopHeight * res_scale;
|
||||||
}
|
}
|
||||||
layout = MobileLandscapeFrameLayout(width, height, Settings::values.swap_screen, 2.25f,
|
layout = MobileLandscapeFrameLayout(
|
||||||
false);
|
width, height, Settings::values.swap_screen.GetValue(), 2.25f, false);
|
||||||
break;
|
break;
|
||||||
case Settings::LayoutOption::Default:
|
case Settings::LayoutOption::Default:
|
||||||
default:
|
default:
|
||||||
if (Settings::values.upright_screen) {
|
if (Settings::values.upright_screen.GetValue()) {
|
||||||
width = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale;
|
width = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale;
|
||||||
height = Core::kScreenTopWidth * res_scale;
|
height = Core::kScreenTopWidth * res_scale;
|
||||||
} else {
|
} else {
|
||||||
width = Core::kScreenTopWidth * res_scale;
|
width = Core::kScreenTopWidth * res_scale;
|
||||||
height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale;
|
height = (Core::kScreenTopHeight + Core::kScreenBottomHeight) * res_scale;
|
||||||
}
|
}
|
||||||
layout = DefaultFrameLayout(width, height, Settings::values.swap_screen,
|
layout = DefaultFrameLayout(width, height, Settings::values.swap_screen.GetValue(),
|
||||||
Settings::values.upright_screen);
|
Settings::values.upright_screen.GetValue());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) {
|
||||||
layout = Layout::GetCardboardSettings(layout);
|
layout = Layout::GetCardboardSettings(layout);
|
||||||
}
|
}
|
||||||
return layout;
|
return layout;
|
||||||
|
@ -478,17 +482,17 @@ FramebufferLayout GetCardboardSettings(FramebufferLayout layout) {
|
||||||
float bottom_screen_left = 0;
|
float bottom_screen_left = 0;
|
||||||
float bottom_screen_top = 0;
|
float bottom_screen_top = 0;
|
||||||
|
|
||||||
float cardboardScreenScale = Settings::values.cardboard_screen_size / 100.0f;
|
float cardboardScreenScale = Settings::values.cardboard_screen_size.GetValue() / 100.0f;
|
||||||
float top_screen_width = layout.top_screen.GetWidth() / 2.0f * cardboardScreenScale;
|
float top_screen_width = layout.top_screen.GetWidth() / 2.0f * cardboardScreenScale;
|
||||||
float top_screen_height = layout.top_screen.GetHeight() / 2.0f * cardboardScreenScale;
|
float top_screen_height = layout.top_screen.GetHeight() / 2.0f * cardboardScreenScale;
|
||||||
float bottom_screen_width = layout.bottom_screen.GetWidth() / 2.0f * cardboardScreenScale;
|
float bottom_screen_width = layout.bottom_screen.GetWidth() / 2.0f * cardboardScreenScale;
|
||||||
float bottom_screen_height = layout.bottom_screen.GetHeight() / 2.0f * cardboardScreenScale;
|
float bottom_screen_height = layout.bottom_screen.GetHeight() / 2.0f * cardboardScreenScale;
|
||||||
bool is_swapped = Settings::values.swap_screen;
|
const bool is_swapped = Settings::values.swap_screen.GetValue();
|
||||||
bool is_portrait = layout.height > layout.width;
|
const bool is_portrait = layout.height > layout.width;
|
||||||
|
|
||||||
float cardboardScreenWidth;
|
float cardboardScreenWidth;
|
||||||
float cardboardScreenHeight;
|
float cardboardScreenHeight;
|
||||||
switch (Settings::values.layout_option) {
|
switch (Settings::values.layout_option.GetValue()) {
|
||||||
case Settings::LayoutOption::MobileLandscape:
|
case Settings::LayoutOption::MobileLandscape:
|
||||||
case Settings::LayoutOption::SideScreen:
|
case Settings::LayoutOption::SideScreen:
|
||||||
// If orientation is portrait, only use MobilePortrait
|
// If orientation is portrait, only use MobilePortrait
|
||||||
|
@ -524,9 +528,11 @@ FramebufferLayout GetCardboardSettings(FramebufferLayout layout) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
float cardboardMaxXShift = (layout.width / 2.0f - cardboardScreenWidth) / 2.0f;
|
float cardboardMaxXShift = (layout.width / 2.0f - cardboardScreenWidth) / 2.0f;
|
||||||
float cardboardUserXShift = (Settings::values.cardboard_x_shift / 100.0f) * cardboardMaxXShift;
|
float cardboardUserXShift =
|
||||||
|
(Settings::values.cardboard_x_shift.GetValue() / 100.0f) * cardboardMaxXShift;
|
||||||
float cardboardMaxYShift = ((float)layout.height - cardboardScreenHeight) / 2.0f;
|
float cardboardMaxYShift = ((float)layout.height - cardboardScreenHeight) / 2.0f;
|
||||||
float cardboardUserYShift = (Settings::values.cardboard_y_shift / 100.0f) * cardboardMaxYShift;
|
float cardboardUserYShift =
|
||||||
|
(Settings::values.cardboard_y_shift.GetValue() / 100.0f) * cardboardMaxYShift;
|
||||||
|
|
||||||
// Center the screens and apply user Y shift
|
// Center the screens and apply user Y shift
|
||||||
newLayout.top_screen.left = top_screen_left + cardboardMaxXShift;
|
newLayout.top_screen.left = top_screen_left + cardboardMaxXShift;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/math_util.h"
|
#include "common/math_util.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
|
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/config_mem.h"
|
#include "core/hle/kernel/config_mem.h"
|
||||||
#include "core/hle/kernel/memory.h"
|
#include "core/hle/kernel/memory.h"
|
||||||
|
@ -19,7 +20,6 @@
|
||||||
#include "core/hle/kernel/vm_manager.h"
|
#include "core/hle/kernel/vm_manager.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ enum N3DSMode : u8 {
|
||||||
void KernelSystem::MemoryInit(u32 mem_type, u8 n3ds_mode) {
|
void KernelSystem::MemoryInit(u32 mem_type, u8 n3ds_mode) {
|
||||||
ASSERT(mem_type != 1);
|
ASSERT(mem_type != 1);
|
||||||
|
|
||||||
const bool is_new_3ds = Settings::values.is_new_3ds;
|
const bool is_new_3ds = Settings::values.is_new_3ds.GetValue();
|
||||||
u32 reported_mem_type = mem_type;
|
u32 reported_mem_type = mem_type;
|
||||||
if (is_new_3ds) {
|
if (is_new_3ds) {
|
||||||
if (n3ds_mode == MemoryMode::Mode6 || n3ds_mode == MemoryMode::Mode6_2) {
|
if (n3ds_mode == MemoryMode::Mode6 || n3ds_mode == MemoryMode::Mode6_2) {
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/kernel/shared_page.h"
|
#include "core/hle/kernel/shared_page.h"
|
||||||
#include "core/hle/service/ptm/ptm.h"
|
#include "core/hle/service/ptm/ptm.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ static std::chrono::seconds GetInitTime() {
|
||||||
return std::chrono::seconds(override_init_time);
|
return std::chrono::seconds(override_init_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Settings::values.init_clock) {
|
switch (Settings::values.init_clock.GetValue()) {
|
||||||
case Settings::InitClock::SystemTime: {
|
case Settings::InitClock::SystemTime: {
|
||||||
auto now = std::chrono::system_clock::now();
|
auto now = std::chrono::system_clock::now();
|
||||||
// If the system time is in daylight saving, we give an additional hour to console time
|
// If the system time is in daylight saving, we give an additional hour to console time
|
||||||
|
@ -47,7 +47,7 @@ static std::chrono::seconds GetInitTime() {
|
||||||
now = now + std::chrono::hours(1);
|
now = now + std::chrono::hours(1);
|
||||||
|
|
||||||
// add the offset
|
// add the offset
|
||||||
s64 init_time_offset = Settings::values.init_time_offset;
|
s64 init_time_offset = Settings::values.init_time_offset.GetValue();
|
||||||
long long days_offset = init_time_offset / 86400;
|
long long days_offset = init_time_offset / 86400;
|
||||||
long long days_offset_in_seconds = days_offset * 86400; // h/m/s truncated
|
long long days_offset_in_seconds = days_offset * 86400; // h/m/s truncated
|
||||||
unsigned long long seconds_offset =
|
unsigned long long seconds_offset =
|
||||||
|
@ -58,9 +58,9 @@ static std::chrono::seconds GetInitTime() {
|
||||||
return std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
|
return std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch());
|
||||||
}
|
}
|
||||||
case Settings::InitClock::FixedTime:
|
case Settings::InitClock::FixedTime:
|
||||||
return std::chrono::seconds(Settings::values.init_time);
|
return std::chrono::seconds(Settings::values.init_time.GetValue());
|
||||||
default:
|
default:
|
||||||
UNREACHABLE_MSG("Invalid InitClock value ({})", Settings::values.init_clock);
|
UNREACHABLE_MSG("Invalid InitClock value ({})", Settings::values.init_clock.GetValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ Handler::Handler(Core::Timing& timing) : timing(timing) {
|
||||||
std::bind(&Handler::UpdateTimeCallback, this, _1, _2));
|
std::bind(&Handler::UpdateTimeCallback, this, _1, _2));
|
||||||
timing.ScheduleEvent(0, update_time_event, 0, 0);
|
timing.ScheduleEvent(0, update_time_event, 0, 0);
|
||||||
|
|
||||||
float slidestate = Settings::values.factor_3d / 100.0f;
|
float slidestate = Settings::values.factor_3d.GetValue() / 100.0f;
|
||||||
shared_page.sliderstate_3d = static_cast<float_le>(slidestate);
|
shared_page.sliderstate_3d = static_cast<float_le>(slidestate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/file_sys/archive_ncch.h"
|
#include "core/file_sys/archive_ncch.h"
|
||||||
#include "core/file_sys/file_backend.h"
|
#include "core/file_sys/file_backend.h"
|
||||||
|
@ -28,7 +29,6 @@
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/hw/aes/ccm.h"
|
#include "core/hw/aes/ccm.h"
|
||||||
#include "core/hw/aes/key.h"
|
#include "core/hw/aes/key.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
SERVICE_CONSTRUCT_IMPL(Service::APT::Module)
|
SERVICE_CONSTRUCT_IMPL(Service::APT::Module)
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
#include "common/bit_set.h"
|
#include "common/bit_set.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/frontend/camera/factory.h"
|
#include "core/frontend/camera/factory.h"
|
||||||
|
@ -19,7 +20,6 @@
|
||||||
#include "core/hle/service/cam/cam_s.h"
|
#include "core/hle/service/cam/cam_s.h"
|
||||||
#include "core/hle/service/cam/cam_u.h"
|
#include "core/hle/service/cam/cam_u.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
SERVICE_CONSTRUCT_IMPL(Service::CAM::Module)
|
SERVICE_CONSTRUCT_IMPL(Service::CAM::Module)
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
@ -25,7 +26,6 @@
|
||||||
#include "core/hle/service/cfg/cfg_nor.h"
|
#include "core/hle/service/cfg/cfg_nor.h"
|
||||||
#include "core/hle/service/cfg/cfg_s.h"
|
#include "core/hle/service/cfg/cfg_s.h"
|
||||||
#include "core/hle/service/cfg/cfg_u.h"
|
#include "core/hle/service/cfg/cfg_u.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
SERIALIZE_EXPORT_IMPL(Service::CFG::Module)
|
SERIALIZE_EXPORT_IMPL(Service::CFG::Module)
|
||||||
|
|
||||||
|
@ -189,10 +189,10 @@ void Module::Interface::GetCountryCodeID(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Module::GetRegionValue() {
|
u32 Module::GetRegionValue() {
|
||||||
if (Settings::values.region_value == Settings::REGION_VALUE_AUTO_SELECT)
|
if (Settings::values.region_value.GetValue() == Settings::REGION_VALUE_AUTO_SELECT)
|
||||||
return preferred_region_code;
|
return preferred_region_code;
|
||||||
|
|
||||||
return Settings::values.region_value;
|
return Settings::values.region_value.GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Module::Interface::SecureInfoGetRegion(Kernel::HLERequestContext& ctx, u16 id) {
|
void Module::Interface::SecureInfoGetRegion(Kernel::HLERequestContext& ctx, u16 id) {
|
||||||
|
@ -654,7 +654,7 @@ void Module::SetPreferredRegionCodes(const std::vector<u32>& region_codes) {
|
||||||
preferred_region_code = region;
|
preferred_region_code = region;
|
||||||
LOG_INFO(Service_CFG, "Preferred region code set to {}", preferred_region_code);
|
LOG_INFO(Service_CFG, "Preferred region code set to {}", preferred_region_code);
|
||||||
|
|
||||||
if (Settings::values.region_value == Settings::REGION_VALUE_AUTO_SELECT) {
|
if (Settings::values.region_value.GetValue() == Settings::REGION_VALUE_AUTO_SELECT) {
|
||||||
if (current_language != adjusted_language) {
|
if (current_language != adjusted_language) {
|
||||||
LOG_WARNING(Service_CFG, "System language {} does not fit the region. Adjusted to {}",
|
LOG_WARNING(Service_CFG, "System language {} does not fit the region. Adjusted to {}",
|
||||||
current_language, adjusted_language);
|
current_language, adjusted_language);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/file_sys/errors.h"
|
#include "core/file_sys/errors.h"
|
||||||
|
@ -25,7 +26,6 @@
|
||||||
#include "core/hle/service/am/am.h"
|
#include "core/hle/service/am/am.h"
|
||||||
#include "core/hle/service/fs/archive.h"
|
#include "core/hle/service/fs/archive.h"
|
||||||
#include "core/hle/service/fs/fs_user.h"
|
#include "core/hle/service/fs/fs_user.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
SERVICE_CONSTRUCT_IMPL(Service::FS::FS_USER)
|
SERVICE_CONSTRUCT_IMPL(Service::FS::FS_USER)
|
||||||
SERIALIZE_EXPORT_IMPL(Service::FS::FS_USER)
|
SERIALIZE_EXPORT_IMPL(Service::FS::FS_USER)
|
||||||
|
@ -350,7 +350,7 @@ void FS_USER::IsSdmcDetected(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx, 0x817, 0, 0);
|
IPC::RequestParser rp(ctx, 0x817, 0, 0);
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.Push(Settings::values.use_virtual_sd);
|
rb.Push(Settings::values.use_virtual_sd.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FS_USER::IsSdmcWriteable(Kernel::HLERequestContext& ctx) {
|
void FS_USER::IsSdmcWriteable(Kernel::HLERequestContext& ctx) {
|
||||||
|
@ -358,7 +358,7 @@ void FS_USER::IsSdmcWriteable(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
// If the SD isn't enabled, it can't be writeable...else, stubbed true
|
// If the SD isn't enabled, it can't be writeable...else, stubbed true
|
||||||
rb.Push(Settings::values.use_virtual_sd);
|
rb.Push(Settings::values.use_virtual_sd.GetValue());
|
||||||
LOG_DEBUG(Service_FS, " (STUBBED)");
|
LOG_DEBUG(Service_FS, " (STUBBED)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,8 +218,9 @@ void Module::UpdatePadCallback(std::uintptr_t user_data, s64 cycles_late) {
|
||||||
|
|
||||||
// TODO(xperia64): How the 3D Slider is updated by the HID module needs to be RE'd
|
// TODO(xperia64): How the 3D Slider is updated by the HID module needs to be RE'd
|
||||||
// and possibly moved to its own Core::Timing event.
|
// and possibly moved to its own Core::Timing event.
|
||||||
mem->pad.sliderstate_3d = (Settings::values.factor_3d / 100.0f);
|
mem->pad.sliderstate_3d = (Settings::values.factor_3d.GetValue() / 100.0f);
|
||||||
system.Kernel().GetSharedPageHandler().Set3DSlider(Settings::values.factor_3d / 100.0f);
|
system.Kernel().GetSharedPageHandler().Set3DSlider(Settings::values.factor_3d.GetValue() /
|
||||||
|
100.0f);
|
||||||
|
|
||||||
// Reschedule recurrent event
|
// Reschedule recurrent event
|
||||||
system.CoreTiming().ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
|
system.CoreTiming().ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
|
||||||
|
@ -406,7 +407,7 @@ void Module::Interface::GetGyroscopeLowCalibrateParam(Kernel::HLERequestContext&
|
||||||
void Module::Interface::GetSoundVolume(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::GetSoundVolume(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ctx, 0x17, 0, 0};
|
IPC::RequestParser rp{ctx, 0x17, 0, 0};
|
||||||
|
|
||||||
const u8 volume = static_cast<u8>(0x3F * Settings::values.volume);
|
const u8 volume = static_cast<u8>(0x3F * Settings::values.volume.GetValue());
|
||||||
|
|
||||||
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
|
|
|
@ -13,10 +13,10 @@
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_funcs.h"
|
#include "common/common_funcs.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/frontend/input.h"
|
#include "core/frontend/input.h"
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "common/alignment.h"
|
#include "common/alignment.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/service/ir/extra_hid.h"
|
#include "core/hle/service/ir/extra_hid.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
namespace Service::IR {
|
namespace Service::IR {
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <boost/serialization/base_object.hpp>
|
#include <boost/serialization/base_object.hpp>
|
||||||
#include <boost/serialization/shared_ptr.hpp>
|
#include <boost/serialization/shared_ptr.hpp>
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
|
@ -13,7 +14,6 @@
|
||||||
#include "core/hle/service/hid/hid.h"
|
#include "core/hle/service/hid/hid.h"
|
||||||
#include "core/hle/service/ir/ir_rst.h"
|
#include "core/hle/service/ir/ir_rst.h"
|
||||||
#include "core/movie.h"
|
#include "core/movie.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
SERIALIZE_EXPORT_IMPL(Service::IR::IR_RST)
|
SERIALIZE_EXPORT_IMPL(Service::IR::IR_RST)
|
||||||
SERVICE_CONSTRUCT_IMPL(Service::IR::IR_RST)
|
SERVICE_CONSTRUCT_IMPL(Service::IR::IR_RST)
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <boost/serialization/weak_ptr.hpp>
|
#include <boost/serialization/weak_ptr.hpp>
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/mic.h"
|
#include "core/frontend/mic.h"
|
||||||
#include "core/hle/ipc.h"
|
#include "core/hle/ipc.h"
|
||||||
|
@ -14,7 +15,6 @@
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/shared_memory.h"
|
#include "core/hle/kernel/shared_memory.h"
|
||||||
#include "core/hle/service/mic_u.h"
|
#include "core/hle/service/mic_u.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
SERVICE_CONSTRUCT_IMPL(Service::MIC::MIC_U)
|
SERVICE_CONSTRUCT_IMPL(Service::MIC::MIC_U)
|
||||||
SERIALIZE_EXPORT_IMPL(Service::MIC::MIC_U)
|
SERIALIZE_EXPORT_IMPL(Service::MIC::MIC_U)
|
||||||
|
@ -350,12 +350,12 @@ struct MIC_U::Impl {
|
||||||
|
|
||||||
void CreateMic() {
|
void CreateMic() {
|
||||||
std::unique_ptr<Frontend::Mic::Interface> new_mic;
|
std::unique_ptr<Frontend::Mic::Interface> new_mic;
|
||||||
switch (Settings::values.mic_input_type) {
|
switch (Settings::values.mic_input_type.GetValue()) {
|
||||||
case Settings::MicInputType::None:
|
case Settings::MicInputType::None:
|
||||||
new_mic = std::make_unique<Frontend::Mic::NullMic>();
|
new_mic = std::make_unique<Frontend::Mic::NullMic>();
|
||||||
break;
|
break;
|
||||||
case Settings::MicInputType::Real:
|
case Settings::MicInputType::Real:
|
||||||
new_mic = Frontend::Mic::CreateRealMic(Settings::values.mic_input_device);
|
new_mic = Frontend::Mic::CreateRealMic(Settings::values.mic_input_device.GetValue());
|
||||||
break;
|
break;
|
||||||
case Settings::MicInputType::Static:
|
case Settings::MicInputType::Static:
|
||||||
new_mic = std::make_unique<Frontend::Mic::StaticMic>();
|
new_mic = std::make_unique<Frontend::Mic::StaticMic>();
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/file_sys/archive_extsavedata.h"
|
#include "core/file_sys/archive_extsavedata.h"
|
||||||
#include "core/file_sys/errors.h"
|
#include "core/file_sys/errors.h"
|
||||||
|
@ -17,7 +18,6 @@
|
||||||
#include "core/hle/service/ptm/ptm_sets.h"
|
#include "core/hle/service/ptm/ptm_sets.h"
|
||||||
#include "core/hle/service/ptm/ptm_sysm.h"
|
#include "core/hle/service/ptm/ptm_sysm.h"
|
||||||
#include "core/hle/service/ptm/ptm_u.h"
|
#include "core/hle/service/ptm/ptm_u.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
SERIALIZE_EXPORT_IMPL(Service::PTM::Module)
|
SERIALIZE_EXPORT_IMPL(Service::PTM::Module)
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ void Module::Interface::GetSoftwareClosedFlag(Kernel::HLERequestContext& ctx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckNew3DS(IPC::RequestBuilder& rb) {
|
void CheckNew3DS(IPC::RequestBuilder& rb) {
|
||||||
const bool is_new_3ds = Settings::values.is_new_3ds;
|
const bool is_new_3ds = Settings::values.is_new_3ds.GetValue();
|
||||||
|
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.Push(is_new_3ds);
|
rb.Push(is_new_3ds);
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "common/atomic_ops.h"
|
#include "common/atomic_ops.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/swap.h"
|
#include "common/swap.h"
|
||||||
#include "core/arm/arm_interface.h"
|
#include "core/arm/arm_interface.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
@ -20,7 +21,6 @@
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/lock.h"
|
#include "core/hle/lock.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/video_core.h"
|
#include "video_core/video_core.h"
|
||||||
|
|
||||||
|
@ -289,7 +289,7 @@ private:
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, const unsigned int file_version) {
|
void serialize(Archive& ar, const unsigned int file_version) {
|
||||||
bool save_n3ds_ram = Settings::values.is_new_3ds;
|
bool save_n3ds_ram = Settings::values.is_new_3ds.GetValue();
|
||||||
ar& save_n3ds_ram;
|
ar& save_n3ds_ram;
|
||||||
ar& boost::serialization::make_binary_object(vram.get(), Memory::VRAM_SIZE);
|
ar& boost::serialization::make_binary_object(vram.get(), Memory::VRAM_SIZE);
|
||||||
ar& boost::serialization::make_binary_object(
|
ar& boost::serialization::make_binary_object(
|
||||||
|
|
|
@ -601,8 +601,8 @@ void Movie::PrepareForPlayback(const std::string& movie_file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Movie::PrepareForRecording() {
|
void Movie::PrepareForRecording() {
|
||||||
if (Settings::values.init_clock == Settings::InitClock::SystemTime) {
|
if (Settings::values.init_clock.GetValue() == Settings::InitClock::SystemTime) {
|
||||||
long long init_time_offset = Settings::values.init_time_offset;
|
long long init_time_offset = Settings::values.init_time_offset.GetValue();
|
||||||
long long days_offset = init_time_offset / 86400;
|
long long days_offset = init_time_offset / 86400;
|
||||||
unsigned long long seconds_offset =
|
unsigned long long seconds_offset =
|
||||||
std::abs(init_time_offset) - std::abs(days_offset * 86400);
|
std::abs(init_time_offset) - std::abs(days_offset * 86400);
|
||||||
|
@ -610,7 +610,7 @@ void Movie::PrepareForRecording() {
|
||||||
init_time =
|
init_time =
|
||||||
Common::Timer::GetTimeSinceJan1970().count() + seconds_offset + (days_offset * 86400);
|
Common::Timer::GetTimeSinceJan1970().count() + seconds_offset + (days_offset * 86400);
|
||||||
} else {
|
} else {
|
||||||
init_time = Settings::values.init_time;
|
init_time = Settings::values.init_time.GetValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
#include <fmt/chrono.h>
|
#include <fmt/chrono.h>
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/hw/gpu.h"
|
#include "core/hw/gpu.h"
|
||||||
#include "core/perf_stats.h"
|
#include "core/perf_stats.h"
|
||||||
#include "core/settings.h"
|
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
using namespace std::chrono_literals;
|
||||||
using DoubleSecs = std::chrono::duration<double, std::chrono::seconds::period>;
|
using DoubleSecs = std::chrono::duration<double, std::chrono::seconds::period>;
|
||||||
|
@ -136,14 +136,9 @@ void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto now = Clock::now();
|
auto now = Clock::now();
|
||||||
double sleep_scale = Settings::values.frame_limit / 100.0;
|
double sleep_scale = Settings::values.frame_limit.GetValue() / 100.0;
|
||||||
|
|
||||||
if (Settings::values.use_frame_limit_alternate) {
|
if (Settings::values.frame_limit.GetValue() == 0) {
|
||||||
if (Settings::values.frame_limit_alternate == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
sleep_scale = Settings::values.frame_limit_alternate / 100.0;
|
|
||||||
} else if (Settings::values.frame_limit == 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,268 +0,0 @@
|
||||||
// Copyright 2014 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <atomic>
|
|
||||||
#include <string>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
#include "common/common_types.h"
|
|
||||||
#include "core/hle/service/cam/cam_params.h"
|
|
||||||
|
|
||||||
namespace Settings {
|
|
||||||
|
|
||||||
enum class InitClock {
|
|
||||||
SystemTime = 0,
|
|
||||||
FixedTime = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class LayoutOption {
|
|
||||||
Default,
|
|
||||||
SingleScreen,
|
|
||||||
LargeScreen,
|
|
||||||
SideScreen,
|
|
||||||
#ifndef ANDROID
|
|
||||||
SeparateWindows,
|
|
||||||
#endif
|
|
||||||
// Similiar to default, but better for mobile devices in portrait mode. Top screen in clamped to
|
|
||||||
// the top of the frame, and the bottom screen is enlarged to match the top screen.
|
|
||||||
MobilePortrait,
|
|
||||||
|
|
||||||
// Similiar to LargeScreen, but better for mobile devices in landscape mode. The screens are
|
|
||||||
// clamped to the top of the frame, and the bottom screen is a bit bigger.
|
|
||||||
MobileLandscape,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class MicInputType {
|
|
||||||
None,
|
|
||||||
Real,
|
|
||||||
Static,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class StereoRenderOption {
|
|
||||||
Off,
|
|
||||||
SideBySide,
|
|
||||||
Anaglyph,
|
|
||||||
Interlaced,
|
|
||||||
ReverseInterlaced,
|
|
||||||
CardboardVR
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace NativeButton {
|
|
||||||
enum Values {
|
|
||||||
A,
|
|
||||||
B,
|
|
||||||
X,
|
|
||||||
Y,
|
|
||||||
Up,
|
|
||||||
Down,
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
L,
|
|
||||||
R,
|
|
||||||
Start,
|
|
||||||
Select,
|
|
||||||
Debug,
|
|
||||||
Gpio14,
|
|
||||||
|
|
||||||
ZL,
|
|
||||||
ZR,
|
|
||||||
|
|
||||||
Home,
|
|
||||||
|
|
||||||
NumButtons,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr int BUTTON_HID_BEGIN = A;
|
|
||||||
constexpr int BUTTON_IR_BEGIN = ZL;
|
|
||||||
constexpr int BUTTON_NS_BEGIN = Home;
|
|
||||||
|
|
||||||
constexpr int BUTTON_HID_END = BUTTON_IR_BEGIN;
|
|
||||||
constexpr int BUTTON_IR_END = BUTTON_NS_BEGIN;
|
|
||||||
constexpr int BUTTON_NS_END = NumButtons;
|
|
||||||
|
|
||||||
constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
|
|
||||||
constexpr int NUM_BUTTONS_IR = BUTTON_IR_END - BUTTON_IR_BEGIN;
|
|
||||||
constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
|
|
||||||
|
|
||||||
static const std::array<const char*, NumButtons> mapping = {{
|
|
||||||
"button_a",
|
|
||||||
"button_b",
|
|
||||||
"button_x",
|
|
||||||
"button_y",
|
|
||||||
"button_up",
|
|
||||||
"button_down",
|
|
||||||
"button_left",
|
|
||||||
"button_right",
|
|
||||||
"button_l",
|
|
||||||
"button_r",
|
|
||||||
"button_start",
|
|
||||||
"button_select",
|
|
||||||
"button_debug",
|
|
||||||
"button_gpio14",
|
|
||||||
"button_zl",
|
|
||||||
"button_zr",
|
|
||||||
"button_home",
|
|
||||||
}};
|
|
||||||
} // namespace NativeButton
|
|
||||||
|
|
||||||
namespace NativeAnalog {
|
|
||||||
enum Values {
|
|
||||||
CirclePad,
|
|
||||||
CStick,
|
|
||||||
|
|
||||||
NumAnalogs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const std::array<const char*, NumAnalogs> mapping = {{
|
|
||||||
"circle_pad",
|
|
||||||
"c_stick",
|
|
||||||
}};
|
|
||||||
} // namespace NativeAnalog
|
|
||||||
|
|
||||||
struct InputProfile {
|
|
||||||
std::string name;
|
|
||||||
std::array<std::string, NativeButton::NumButtons> buttons;
|
|
||||||
std::array<std::string, NativeAnalog::NumAnalogs> analogs;
|
|
||||||
std::string motion_device;
|
|
||||||
std::string touch_device;
|
|
||||||
bool use_touch_from_button;
|
|
||||||
int touch_from_button_map_index;
|
|
||||||
std::string udp_input_address;
|
|
||||||
u16 udp_input_port;
|
|
||||||
u8 udp_pad_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TouchFromButtonMap {
|
|
||||||
std::string name;
|
|
||||||
std::vector<std::string> buttons;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Values {
|
|
||||||
// CheckNew3DS
|
|
||||||
bool is_new_3ds;
|
|
||||||
|
|
||||||
// Controls
|
|
||||||
InputProfile current_input_profile; ///< The current input profile
|
|
||||||
int current_input_profile_index; ///< The current input profile index
|
|
||||||
std::vector<InputProfile> input_profiles; ///< The list of input profiles
|
|
||||||
std::vector<TouchFromButtonMap> touch_from_button_maps;
|
|
||||||
|
|
||||||
// Core
|
|
||||||
bool use_cpu_jit;
|
|
||||||
int cpu_clock_percentage;
|
|
||||||
|
|
||||||
// Data Storage
|
|
||||||
bool use_virtual_sd;
|
|
||||||
bool use_custom_storage;
|
|
||||||
|
|
||||||
// System
|
|
||||||
int region_value;
|
|
||||||
InitClock init_clock;
|
|
||||||
u64 init_time;
|
|
||||||
s64 init_time_offset;
|
|
||||||
|
|
||||||
// Renderer
|
|
||||||
bool use_gles;
|
|
||||||
bool use_hw_renderer;
|
|
||||||
bool use_hw_shader;
|
|
||||||
bool separable_shader;
|
|
||||||
bool use_disk_shader_cache;
|
|
||||||
bool shaders_accurate_mul;
|
|
||||||
bool use_shader_jit;
|
|
||||||
u16 resolution_factor;
|
|
||||||
bool use_frame_limit_alternate;
|
|
||||||
u16 frame_limit;
|
|
||||||
u16 frame_limit_alternate;
|
|
||||||
std::string texture_filter_name;
|
|
||||||
|
|
||||||
LayoutOption layout_option;
|
|
||||||
bool swap_screen;
|
|
||||||
bool upright_screen;
|
|
||||||
bool custom_layout;
|
|
||||||
u16 custom_top_left;
|
|
||||||
u16 custom_top_top;
|
|
||||||
u16 custom_top_right;
|
|
||||||
u16 custom_top_bottom;
|
|
||||||
u16 custom_bottom_left;
|
|
||||||
u16 custom_bottom_top;
|
|
||||||
u16 custom_bottom_right;
|
|
||||||
u16 custom_bottom_bottom;
|
|
||||||
|
|
||||||
float bg_red;
|
|
||||||
float bg_green;
|
|
||||||
float bg_blue;
|
|
||||||
|
|
||||||
StereoRenderOption render_3d;
|
|
||||||
std::atomic<u8> factor_3d;
|
|
||||||
|
|
||||||
bool mono_render_left_eye;
|
|
||||||
|
|
||||||
int cardboard_screen_size;
|
|
||||||
int cardboard_x_shift;
|
|
||||||
int cardboard_y_shift;
|
|
||||||
|
|
||||||
bool filter_mode;
|
|
||||||
std::string pp_shader_name;
|
|
||||||
|
|
||||||
bool dump_textures;
|
|
||||||
bool custom_textures;
|
|
||||||
bool preload_textures;
|
|
||||||
|
|
||||||
bool use_vsync_new;
|
|
||||||
|
|
||||||
// Audio
|
|
||||||
bool audio_muted;
|
|
||||||
bool enable_dsp_lle;
|
|
||||||
bool enable_dsp_lle_multithread;
|
|
||||||
std::string sink_id;
|
|
||||||
bool enable_audio_stretching;
|
|
||||||
std::string audio_device_id;
|
|
||||||
float volume;
|
|
||||||
MicInputType mic_input_type;
|
|
||||||
std::string mic_input_device;
|
|
||||||
|
|
||||||
// Camera
|
|
||||||
std::array<std::string, Service::CAM::NumCameras> camera_name;
|
|
||||||
std::array<std::string, Service::CAM::NumCameras> camera_config;
|
|
||||||
std::array<int, Service::CAM::NumCameras> camera_flip;
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
bool record_frame_times;
|
|
||||||
bool use_gdbstub;
|
|
||||||
u16 gdbstub_port;
|
|
||||||
std::string log_filter;
|
|
||||||
std::unordered_map<std::string, bool> lle_modules;
|
|
||||||
|
|
||||||
// Video Dumping
|
|
||||||
std::string output_format;
|
|
||||||
std::string format_options;
|
|
||||||
|
|
||||||
std::string video_encoder;
|
|
||||||
std::string video_encoder_options;
|
|
||||||
u64 video_bitrate;
|
|
||||||
|
|
||||||
std::string audio_encoder;
|
|
||||||
std::string audio_encoder_options;
|
|
||||||
u64 audio_bitrate;
|
|
||||||
} extern values;
|
|
||||||
|
|
||||||
float Volume();
|
|
||||||
|
|
||||||
// a special value for Values::region_value indicating that citra will automatically select a region
|
|
||||||
// value to fit the region lockout info of the game
|
|
||||||
static constexpr int REGION_VALUE_AUTO_SELECT = -1;
|
|
||||||
|
|
||||||
void Apply();
|
|
||||||
void LogSettings();
|
|
||||||
|
|
||||||
// Input profiles
|
|
||||||
void LoadProfile(int index);
|
|
||||||
void SaveProfile(int index);
|
|
||||||
void CreateProfile(std::string name);
|
|
||||||
void DeleteProfile(int index);
|
|
||||||
void RenameCurrentProfile(std::string new_name);
|
|
||||||
} // namespace Settings
|
|
|
@ -9,8 +9,8 @@
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "core/telemetry_session.h"
|
#include "core/telemetry_session.h"
|
||||||
#include "network/network_settings.h"
|
#include "network/network_settings.h"
|
||||||
|
|
||||||
|
@ -124,35 +124,37 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) {
|
||||||
Telemetry::AppendOSInfo(field_collection);
|
Telemetry::AppendOSInfo(field_collection);
|
||||||
|
|
||||||
// Log user configuration information
|
// Log user configuration information
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Audio_SinkId", Settings::values.sink_id);
|
AddField(Telemetry::FieldType::UserConfig, "Audio_SinkId", Settings::values.sink_id.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching",
|
AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching",
|
||||||
Settings::values.enable_audio_stretching);
|
Settings::values.enable_audio_stretching.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit", Settings::values.use_cpu_jit);
|
AddField(Telemetry::FieldType::UserConfig, "Core_UseCpuJit",
|
||||||
|
Settings::values.use_cpu_jit.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_ResolutionFactor",
|
||||||
Settings::values.resolution_factor);
|
Settings::values.resolution_factor.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_FrameLimit", Settings::values.frame_limit);
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_FrameLimit",
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseFrameLimitAlternate",
|
Settings::values.frame_limit.GetValue());
|
||||||
Settings::values.use_frame_limit_alternate);
|
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_FrameLimitAlternate",
|
|
||||||
Settings::values.frame_limit_alternate);
|
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwRenderer",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwRenderer",
|
||||||
Settings::values.use_hw_renderer);
|
Settings::values.use_hw_renderer.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwShader",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseHwShader",
|
||||||
Settings::values.use_hw_shader);
|
Settings::values.use_hw_shader.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_ShadersAccurateMul",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_ShadersAccurateMul",
|
||||||
Settings::values.shaders_accurate_mul);
|
Settings::values.shaders_accurate_mul.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseShaderJit",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseShaderJit",
|
||||||
Settings::values.use_shader_jit);
|
Settings::values.use_shader_jit.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseVsync", Settings::values.use_vsync_new);
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_UseVsync",
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_FilterMode", Settings::values.filter_mode);
|
Settings::values.use_vsync_new.GetValue());
|
||||||
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_FilterMode",
|
||||||
|
Settings::values.filter_mode.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_Render3d",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_Render3d",
|
||||||
static_cast<int>(Settings::values.render_3d));
|
static_cast<int>(Settings::values.render_3d.GetValue()));
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_Factor3d",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_Factor3d",
|
||||||
Settings::values.factor_3d.load());
|
Settings::values.factor_3d.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "Renderer_MonoRenderLeftEye",
|
AddField(Telemetry::FieldType::UserConfig, "Renderer_MonoRenderLeftEye",
|
||||||
Settings::values.mono_render_left_eye);
|
Settings::values.mono_render_left_eye.GetValue());
|
||||||
AddField(Telemetry::FieldType::UserConfig, "System_IsNew3ds", Settings::values.is_new_3ds);
|
AddField(Telemetry::FieldType::UserConfig, "System_IsNew3ds",
|
||||||
AddField(Telemetry::FieldType::UserConfig, "System_RegionValue", Settings::values.region_value);
|
Settings::values.is_new_3ds.GetValue());
|
||||||
|
AddField(Telemetry::FieldType::UserConfig, "System_RegionValue",
|
||||||
|
Settings::values.region_value.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TelemetrySession::SubmitTestcase() {
|
bool TelemetrySession::SubmitTestcase() {
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/frontend/input.h"
|
#include "core/frontend/input.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "input_common/gcadapter/gc_adapter.h"
|
#include "input_common/gcadapter/gc_adapter.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/threadsafe_queue.h"
|
#include "common/threadsafe_queue.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "input_common/sdl/sdl.h"
|
#include "input_common/sdl/sdl.h"
|
||||||
|
|
||||||
union SDL_Event;
|
union SDL_Event;
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/3ds.h"
|
#include "core/3ds.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "input_common/touch_from_button.h"
|
#include "input_common/touch_from_button.h"
|
||||||
|
|
||||||
namespace InputCommon {
|
namespace InputCommon {
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/frontend/input.h"
|
#include "core/frontend/input.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "input_common/udp/client.h"
|
#include "input_common/udp/client.h"
|
||||||
#include "input_common/udp/udp.h"
|
#include "input_common/udp/udp.h"
|
||||||
|
|
||||||
|
|
|
@ -241,8 +241,8 @@ static Surface FindMatch(const SurfaceCache& surface_cache, const SurfaceParams&
|
||||||
|
|
||||||
RasterizerCacheOpenGL::RasterizerCacheOpenGL() {
|
RasterizerCacheOpenGL::RasterizerCacheOpenGL() {
|
||||||
resolution_scale_factor = VideoCore::GetResolutionScaleFactor();
|
resolution_scale_factor = VideoCore::GetResolutionScaleFactor();
|
||||||
texture_filterer = std::make_unique<TextureFilterer>(Settings::values.texture_filter_name,
|
texture_filterer = std::make_unique<TextureFilterer>(
|
||||||
resolution_scale_factor);
|
Settings::values.texture_filter_name.GetValue(), resolution_scale_factor);
|
||||||
format_reinterpreter = std::make_unique<FormatReinterpreterOpenGL>();
|
format_reinterpreter = std::make_unique<FormatReinterpreterOpenGL>();
|
||||||
texture_downloader_es = std::make_unique<TextureDownloaderES>(false);
|
texture_downloader_es = std::make_unique<TextureDownloaderES>(false);
|
||||||
}
|
}
|
||||||
|
@ -592,7 +592,7 @@ SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
|
||||||
resolution_scale_factor != VideoCore::GetResolutionScaleFactor();
|
resolution_scale_factor != VideoCore::GetResolutionScaleFactor();
|
||||||
const bool texture_filter_changed =
|
const bool texture_filter_changed =
|
||||||
VideoCore::g_texture_filter_update_requested.exchange(false) &&
|
VideoCore::g_texture_filter_update_requested.exchange(false) &&
|
||||||
texture_filterer->Reset(Settings::values.texture_filter_name,
|
texture_filterer->Reset(Settings::values.texture_filter_name.GetValue(),
|
||||||
VideoCore::GetResolutionScaleFactor());
|
VideoCore::GetResolutionScaleFactor());
|
||||||
|
|
||||||
if (resolution_scale_changed || texture_filter_changed) {
|
if (resolution_scale_changed || texture_filter_changed) {
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "common/zstd_compression.h"
|
#include "common/zstd_compression.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "video_core/renderer_opengl/gl_shader_disk_cache.h"
|
#include "video_core/renderer_opengl/gl_shader_disk_cache.h"
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/microprofile.h"
|
#include "common/microprofile.h"
|
||||||
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/dumping/backend.h"
|
#include "core/dumping/backend.h"
|
||||||
#include "core/frontend/emu_window.h"
|
#include "core/frontend/emu_window.h"
|
||||||
|
@ -12,7 +13,6 @@
|
||||||
#include "core/hw/hw.h"
|
#include "core/hw/hw.h"
|
||||||
#include "core/hw/lcd.h"
|
#include "core/hw/lcd.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/settings.h"
|
|
||||||
#include "core/tracer/recorder.h"
|
#include "core/tracer/recorder.h"
|
||||||
#include "video_core/debug_utils/debug_utils.h"
|
#include "video_core/debug_utils/debug_utils.h"
|
||||||
#include "video_core/rasterizer_interface.h"
|
#include "video_core/rasterizer_interface.h"
|
||||||
|
@ -381,7 +381,7 @@ void RendererOpenGL::SwapBuffers() {
|
||||||
RenderToMailbox(main_layout, render_window.mailbox, false);
|
RenderToMailbox(main_layout, render_window.mailbox, false);
|
||||||
|
|
||||||
#ifndef ANDROID
|
#ifndef ANDROID
|
||||||
if (Settings::values.layout_option == Settings::LayoutOption::SeparateWindows) {
|
if (Settings::values.layout_option.GetValue() == Settings::LayoutOption::SeparateWindows) {
|
||||||
ASSERT(secondary_window);
|
ASSERT(secondary_window);
|
||||||
const auto& secondary_layout = secondary_window->GetFramebufferLayout();
|
const auto& secondary_layout = secondary_window->GetFramebufferLayout();
|
||||||
RenderToMailbox(secondary_layout, secondary_window->mailbox, false);
|
RenderToMailbox(secondary_layout, secondary_window->mailbox, false);
|
||||||
|
@ -618,8 +618,8 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color
|
||||||
* Initializes the OpenGL state and creates persistent objects.
|
* Initializes the OpenGL state and creates persistent objects.
|
||||||
*/
|
*/
|
||||||
void RendererOpenGL::InitOpenGLObjects() {
|
void RendererOpenGL::InitOpenGLObjects() {
|
||||||
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
|
glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(),
|
||||||
0.0f);
|
Settings::values.bg_blue.GetValue(), 0.0f);
|
||||||
|
|
||||||
filter_sampler.Create();
|
filter_sampler.Create();
|
||||||
ReloadSampler();
|
ReloadSampler();
|
||||||
|
@ -685,12 +685,13 @@ void RendererOpenGL::ReloadShader() {
|
||||||
if (GLES) {
|
if (GLES) {
|
||||||
shader_data += fragment_shader_precision_OES;
|
shader_data += fragment_shader_precision_OES;
|
||||||
}
|
}
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::Anaglyph) {
|
|
||||||
if (Settings::values.pp_shader_name == "dubois (builtin)") {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph) {
|
||||||
|
if (Settings::values.pp_shader_name.GetValue() == "dubois (builtin)") {
|
||||||
shader_data += fragment_shader_anaglyph;
|
shader_data += fragment_shader_anaglyph;
|
||||||
} else {
|
} else {
|
||||||
std::string shader_text =
|
std::string shader_text = OpenGL::GetPostProcessingShaderCode(
|
||||||
OpenGL::GetPostProcessingShaderCode(true, Settings::values.pp_shader_name);
|
true, Settings::values.pp_shader_name.GetValue());
|
||||||
if (shader_text.empty()) {
|
if (shader_text.empty()) {
|
||||||
// Should probably provide some information that the shader couldn't load
|
// Should probably provide some information that the shader couldn't load
|
||||||
shader_data += fragment_shader_anaglyph;
|
shader_data += fragment_shader_anaglyph;
|
||||||
|
@ -698,13 +699,14 @@ void RendererOpenGL::ReloadShader() {
|
||||||
shader_data += shader_text;
|
shader_data += shader_text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::Interlaced ||
|
} else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced ||
|
||||||
Settings::values.render_3d == Settings::StereoRenderOption::ReverseInterlaced) {
|
Settings::values.render_3d.GetValue() ==
|
||||||
if (Settings::values.pp_shader_name == "horizontal (builtin)") {
|
Settings::StereoRenderOption::ReverseInterlaced) {
|
||||||
|
if (Settings::values.pp_shader_name.GetValue() == "horizontal (builtin)") {
|
||||||
shader_data += fragment_shader_interlaced;
|
shader_data += fragment_shader_interlaced;
|
||||||
} else {
|
} else {
|
||||||
std::string shader_text =
|
std::string shader_text = OpenGL::GetPostProcessingShaderCode(
|
||||||
OpenGL::GetPostProcessingShaderCode(false, Settings::values.pp_shader_name);
|
false, Settings::values.pp_shader_name.GetValue());
|
||||||
if (shader_text.empty()) {
|
if (shader_text.empty()) {
|
||||||
// Should probably provide some information that the shader couldn't load
|
// Should probably provide some information that the shader couldn't load
|
||||||
shader_data += fragment_shader_interlaced;
|
shader_data += fragment_shader_interlaced;
|
||||||
|
@ -713,11 +715,11 @@ void RendererOpenGL::ReloadShader() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Settings::values.pp_shader_name == "none (builtin)") {
|
if (Settings::values.pp_shader_name.GetValue() == "none (builtin)") {
|
||||||
shader_data += fragment_shader;
|
shader_data += fragment_shader;
|
||||||
} else {
|
} else {
|
||||||
std::string shader_text =
|
std::string shader_text = OpenGL::GetPostProcessingShaderCode(
|
||||||
OpenGL::GetPostProcessingShaderCode(false, Settings::values.pp_shader_name);
|
false, Settings::values.pp_shader_name.GetValue());
|
||||||
if (shader_text.empty()) {
|
if (shader_text.empty()) {
|
||||||
// Should probably provide some information that the shader couldn't load
|
// Should probably provide some information that the shader couldn't load
|
||||||
shader_data += fragment_shader;
|
shader_data += fragment_shader;
|
||||||
|
@ -731,16 +733,17 @@ void RendererOpenGL::ReloadShader() {
|
||||||
state.Apply();
|
state.Apply();
|
||||||
uniform_modelview_matrix = glGetUniformLocation(shader.handle, "modelview_matrix");
|
uniform_modelview_matrix = glGetUniformLocation(shader.handle, "modelview_matrix");
|
||||||
uniform_color_texture = glGetUniformLocation(shader.handle, "color_texture");
|
uniform_color_texture = glGetUniformLocation(shader.handle, "color_texture");
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::Anaglyph ||
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph ||
|
||||||
Settings::values.render_3d == Settings::StereoRenderOption::Interlaced ||
|
Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced ||
|
||||||
Settings::values.render_3d == Settings::StereoRenderOption::ReverseInterlaced) {
|
Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::ReverseInterlaced) {
|
||||||
uniform_color_texture_r = glGetUniformLocation(shader.handle, "color_texture_r");
|
uniform_color_texture_r = glGetUniformLocation(shader.handle, "color_texture_r");
|
||||||
}
|
}
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::Interlaced ||
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced ||
|
||||||
Settings::values.render_3d == Settings::StereoRenderOption::ReverseInterlaced) {
|
Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::ReverseInterlaced) {
|
||||||
GLuint uniform_reverse_interlaced =
|
GLuint uniform_reverse_interlaced =
|
||||||
glGetUniformLocation(shader.handle, "reverse_interlaced");
|
glGetUniformLocation(shader.handle, "reverse_interlaced");
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::ReverseInterlaced)
|
if (Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::ReverseInterlaced)
|
||||||
glUniform1i(uniform_reverse_interlaced, 1);
|
glUniform1i(uniform_reverse_interlaced, 1);
|
||||||
else
|
else
|
||||||
glUniform1i(uniform_reverse_interlaced, 0);
|
glUniform1i(uniform_reverse_interlaced, 0);
|
||||||
|
@ -958,8 +961,8 @@ void RendererOpenGL::DrawSingleScreenStereo(const ScreenInfo& screen_info_l,
|
||||||
void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool flipped) {
|
void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool flipped) {
|
||||||
if (VideoCore::g_renderer_bg_color_update_requested.exchange(false)) {
|
if (VideoCore::g_renderer_bg_color_update_requested.exchange(false)) {
|
||||||
// Update background color before drawing
|
// Update background color before drawing
|
||||||
glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue,
|
glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(),
|
||||||
0.0f);
|
Settings::values.bg_blue.GetValue(), 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VideoCore::g_renderer_sampler_update_requested.exchange(false)) {
|
if (VideoCore::g_renderer_sampler_update_requested.exchange(false)) {
|
||||||
|
@ -989,9 +992,9 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||||
glUniform1i(uniform_color_texture, 0);
|
glUniform1i(uniform_color_texture, 0);
|
||||||
|
|
||||||
const bool stereo_single_screen =
|
const bool stereo_single_screen =
|
||||||
Settings::values.render_3d == Settings::StereoRenderOption::Anaglyph ||
|
Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Anaglyph ||
|
||||||
Settings::values.render_3d == Settings::StereoRenderOption::Interlaced ||
|
Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Interlaced ||
|
||||||
Settings::values.render_3d == Settings::StereoRenderOption::ReverseInterlaced;
|
Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::ReverseInterlaced;
|
||||||
|
|
||||||
// Bind a second texture for the right eye if in Anaglyph mode
|
// Bind a second texture for the right eye if in Anaglyph mode
|
||||||
if (stereo_single_screen) {
|
if (stereo_single_screen) {
|
||||||
|
@ -1001,12 +1004,13 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||||
glUniform1i(uniform_layer, 0);
|
glUniform1i(uniform_layer, 0);
|
||||||
if (layout.top_screen_enabled) {
|
if (layout.top_screen_enabled) {
|
||||||
if (layout.is_rotated) {
|
if (layout.is_rotated) {
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::Off) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Off) {
|
||||||
int eye = Settings::values.mono_render_left_eye ? 0 : 1;
|
int eye = Settings::values.mono_render_left_eye ? 0 : 1;
|
||||||
DrawSingleScreenRotated(screen_infos[eye], (float)top_screen.left,
|
DrawSingleScreenRotated(screen_infos[eye], (float)top_screen.left,
|
||||||
(float)top_screen.top, (float)top_screen.GetWidth(),
|
(float)top_screen.top, (float)top_screen.GetWidth(),
|
||||||
(float)top_screen.GetHeight());
|
(float)top_screen.GetHeight());
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) {
|
} else if (Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::SideBySide) {
|
||||||
DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left / 2,
|
DrawSingleScreenRotated(screen_infos[0], (float)top_screen.left / 2,
|
||||||
(float)top_screen.top, (float)top_screen.GetWidth() / 2,
|
(float)top_screen.top, (float)top_screen.GetWidth() / 2,
|
||||||
(float)top_screen.GetHeight());
|
(float)top_screen.GetHeight());
|
||||||
|
@ -1015,7 +1019,8 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||||
((float)top_screen.left / 2) + ((float)layout.width / 2),
|
((float)top_screen.left / 2) + ((float)layout.width / 2),
|
||||||
(float)top_screen.top, (float)top_screen.GetWidth() / 2,
|
(float)top_screen.top, (float)top_screen.GetWidth() / 2,
|
||||||
(float)top_screen.GetHeight());
|
(float)top_screen.GetHeight());
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) {
|
} else if (Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::CardboardVR) {
|
||||||
DrawSingleScreenRotated(screen_infos[0], layout.top_screen.left,
|
DrawSingleScreenRotated(screen_infos[0], layout.top_screen.left,
|
||||||
layout.top_screen.top, layout.top_screen.GetWidth(),
|
layout.top_screen.top, layout.top_screen.GetWidth(),
|
||||||
layout.top_screen.GetHeight());
|
layout.top_screen.GetHeight());
|
||||||
|
@ -1031,11 +1036,12 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||||
(float)top_screen.GetWidth(), (float)top_screen.GetHeight());
|
(float)top_screen.GetWidth(), (float)top_screen.GetHeight());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::Off) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Off) {
|
||||||
int eye = Settings::values.mono_render_left_eye ? 0 : 1;
|
int eye = Settings::values.mono_render_left_eye.GetValue() ? 0 : 1;
|
||||||
DrawSingleScreen(screen_infos[eye], (float)top_screen.left, (float)top_screen.top,
|
DrawSingleScreen(screen_infos[eye], (float)top_screen.left, (float)top_screen.top,
|
||||||
(float)top_screen.GetWidth(), (float)top_screen.GetHeight());
|
(float)top_screen.GetWidth(), (float)top_screen.GetHeight());
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) {
|
} else if (Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::SideBySide) {
|
||||||
DrawSingleScreen(screen_infos[0], (float)top_screen.left / 2, (float)top_screen.top,
|
DrawSingleScreen(screen_infos[0], (float)top_screen.left / 2, (float)top_screen.top,
|
||||||
(float)top_screen.GetWidth() / 2, (float)top_screen.GetHeight());
|
(float)top_screen.GetWidth() / 2, (float)top_screen.GetHeight());
|
||||||
glUniform1i(uniform_layer, 1);
|
glUniform1i(uniform_layer, 1);
|
||||||
|
@ -1043,7 +1049,8 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||||
((float)top_screen.left / 2) + ((float)layout.width / 2),
|
((float)top_screen.left / 2) + ((float)layout.width / 2),
|
||||||
(float)top_screen.top, (float)top_screen.GetWidth() / 2,
|
(float)top_screen.top, (float)top_screen.GetWidth() / 2,
|
||||||
(float)top_screen.GetHeight());
|
(float)top_screen.GetHeight());
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) {
|
} else if (Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::CardboardVR) {
|
||||||
DrawSingleScreen(screen_infos[0], layout.top_screen.left, layout.top_screen.top,
|
DrawSingleScreen(screen_infos[0], layout.top_screen.left, layout.top_screen.top,
|
||||||
layout.top_screen.GetWidth(), layout.top_screen.GetHeight());
|
layout.top_screen.GetWidth(), layout.top_screen.GetHeight());
|
||||||
glUniform1i(uniform_layer, 1);
|
glUniform1i(uniform_layer, 1);
|
||||||
|
@ -1061,11 +1068,12 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||||
glUniform1i(uniform_layer, 0);
|
glUniform1i(uniform_layer, 0);
|
||||||
if (layout.bottom_screen_enabled) {
|
if (layout.bottom_screen_enabled) {
|
||||||
if (layout.is_rotated) {
|
if (layout.is_rotated) {
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::Off) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Off) {
|
||||||
DrawSingleScreenRotated(screen_infos[2], (float)bottom_screen.left,
|
DrawSingleScreenRotated(screen_infos[2], (float)bottom_screen.left,
|
||||||
(float)bottom_screen.top, (float)bottom_screen.GetWidth(),
|
(float)bottom_screen.top, (float)bottom_screen.GetWidth(),
|
||||||
(float)bottom_screen.GetHeight());
|
(float)bottom_screen.GetHeight());
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) {
|
} else if (Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::SideBySide) {
|
||||||
DrawSingleScreenRotated(
|
DrawSingleScreenRotated(
|
||||||
screen_infos[2], (float)bottom_screen.left / 2, (float)bottom_screen.top,
|
screen_infos[2], (float)bottom_screen.left / 2, (float)bottom_screen.top,
|
||||||
(float)bottom_screen.GetWidth() / 2, (float)bottom_screen.GetHeight());
|
(float)bottom_screen.GetWidth() / 2, (float)bottom_screen.GetHeight());
|
||||||
|
@ -1074,7 +1082,8 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||||
screen_infos[2], ((float)bottom_screen.left / 2) + ((float)layout.width / 2),
|
screen_infos[2], ((float)bottom_screen.left / 2) + ((float)layout.width / 2),
|
||||||
(float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2,
|
(float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2,
|
||||||
(float)bottom_screen.GetHeight());
|
(float)bottom_screen.GetHeight());
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) {
|
} else if (Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::CardboardVR) {
|
||||||
DrawSingleScreenRotated(screen_infos[2], layout.bottom_screen.left,
|
DrawSingleScreenRotated(screen_infos[2], layout.bottom_screen.left,
|
||||||
layout.bottom_screen.top, layout.bottom_screen.GetWidth(),
|
layout.bottom_screen.top, layout.bottom_screen.GetWidth(),
|
||||||
layout.bottom_screen.GetHeight());
|
layout.bottom_screen.GetHeight());
|
||||||
|
@ -1091,11 +1100,12 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||||
(float)bottom_screen.GetHeight());
|
(float)bottom_screen.GetHeight());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Settings::values.render_3d == Settings::StereoRenderOption::Off) {
|
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::Off) {
|
||||||
DrawSingleScreen(screen_infos[2], (float)bottom_screen.left,
|
DrawSingleScreen(screen_infos[2], (float)bottom_screen.left,
|
||||||
(float)bottom_screen.top, (float)bottom_screen.GetWidth(),
|
(float)bottom_screen.top, (float)bottom_screen.GetWidth(),
|
||||||
(float)bottom_screen.GetHeight());
|
(float)bottom_screen.GetHeight());
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::SideBySide) {
|
} else if (Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::SideBySide) {
|
||||||
DrawSingleScreen(screen_infos[2], (float)bottom_screen.left / 2,
|
DrawSingleScreen(screen_infos[2], (float)bottom_screen.left / 2,
|
||||||
(float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2,
|
(float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2,
|
||||||
(float)bottom_screen.GetHeight());
|
(float)bottom_screen.GetHeight());
|
||||||
|
@ -1104,7 +1114,8 @@ void RendererOpenGL::DrawScreens(const Layout::FramebufferLayout& layout, bool f
|
||||||
((float)bottom_screen.left / 2) + ((float)layout.width / 2),
|
((float)bottom_screen.left / 2) + ((float)layout.width / 2),
|
||||||
(float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2,
|
(float)bottom_screen.top, (float)bottom_screen.GetWidth() / 2,
|
||||||
(float)bottom_screen.GetHeight());
|
(float)bottom_screen.GetHeight());
|
||||||
} else if (Settings::values.render_3d == Settings::StereoRenderOption::CardboardVR) {
|
} else if (Settings::values.render_3d.GetValue() ==
|
||||||
|
Settings::StereoRenderOption::CardboardVR) {
|
||||||
DrawSingleScreen(screen_infos[2], layout.bottom_screen.left,
|
DrawSingleScreen(screen_infos[2], layout.bottom_screen.left,
|
||||||
layout.bottom_screen.top, layout.bottom_screen.GetWidth(),
|
layout.bottom_screen.top, layout.bottom_screen.GetWidth(),
|
||||||
layout.bottom_screen.GetHeight());
|
layout.bottom_screen.GetHeight());
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/archives.h"
|
#include "common/archives.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/settings.h"
|
#include "common/settings.h"
|
||||||
#include "video_core/pica.h"
|
#include "video_core/pica.h"
|
||||||
#include "video_core/pica_state.h"
|
#include "video_core/pica_state.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
|
@ -44,7 +44,7 @@ ResultStatus Init(Frontend::EmuWindow& emu_window, Frontend::EmuWindow* secondar
|
||||||
g_memory = &memory;
|
g_memory = &memory;
|
||||||
Pica::Init();
|
Pica::Init();
|
||||||
|
|
||||||
OpenGL::GLES = Settings::values.use_gles;
|
OpenGL::GLES = Settings::values.use_gles.GetValue();
|
||||||
|
|
||||||
g_renderer = std::make_unique<OpenGL::RendererOpenGL>(emu_window, secondary_window);
|
g_renderer = std::make_unique<OpenGL::RendererOpenGL>(emu_window, secondary_window);
|
||||||
ResultStatus result = g_renderer->Init();
|
ResultStatus result = g_renderer->Init();
|
||||||
|
@ -82,8 +82,8 @@ void RequestScreenshot(void* data, std::function<void()> callback,
|
||||||
|
|
||||||
u16 GetResolutionScaleFactor() {
|
u16 GetResolutionScaleFactor() {
|
||||||
if (g_hw_renderer_enabled) {
|
if (g_hw_renderer_enabled) {
|
||||||
return Settings::values.resolution_factor
|
return Settings::values.resolution_factor.GetValue()
|
||||||
? Settings::values.resolution_factor
|
? Settings::values.resolution_factor.GetValue()
|
||||||
: g_renderer->GetRenderWindow().GetFramebufferLayout().GetScalingRatio();
|
: g_renderer->GetRenderWindow().GetFramebufferLayout().GetScalingRatio();
|
||||||
} else {
|
} else {
|
||||||
// Software renderer always render at native resolution
|
// Software renderer always render at native resolution
|
||||||
|
|
Loading…
Reference in a new issue