diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/common/assert.cpp | 7 | ||||
-rw-r--r-- | src/common/logging/backend.cpp | 2 | ||||
-rw-r--r-- | src/common/nvidia_flags.h | 2 | ||||
-rw-r--r-- | src/common/settings.cpp | 143 | ||||
-rw-r--r-- | src/common/settings.h | 261 | ||||
-rw-r--r-- | src/common/settings_input.cpp | 47 | ||||
-rw-r--r-- | src/common/settings_input.h | 373 |
8 files changed, 836 insertions, 3 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 9f8dafa3b..88644eeb6 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -152,6 +152,10 @@ add_library(common STATIC scm_rev.cpp scm_rev.h scope_exit.h + settings.cpp + settings.h + settings_input.cpp + settings_input.h spin_lock.cpp spin_lock.h stream.cpp diff --git a/src/common/assert.cpp b/src/common/assert.cpp index d7d91b96b..72f1121aa 100644 --- a/src/common/assert.cpp +++ b/src/common/assert.cpp @@ -3,9 +3,12 @@ // Refer to the license.txt file included. #include "common/assert.h" - #include "common/common_funcs.h" +#include "common/settings.h" + void assert_handle_failure() { - Crash(); + if (Settings::values.use_debug_asserts) { + Crash(); + } } diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 2e0467ef4..bc82905c0 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -21,9 +21,9 @@ #include "common/logging/backend.h" #include "common/logging/log.h" #include "common/logging/text_formatter.h" +#include "common/settings.h" #include "common/string_util.h" #include "common/threadsafe_queue.h" -#include "core/settings.h" namespace Common::Log { diff --git a/src/common/nvidia_flags.h b/src/common/nvidia_flags.h index 75a0233ac..8930efcec 100644 --- a/src/common/nvidia_flags.h +++ b/src/common/nvidia_flags.h @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#pragma once + namespace Common { /// Configure platform specific flags for Nvidia's driver diff --git a/src/common/settings.cpp b/src/common/settings.cpp new file mode 100644 index 000000000..702b6598d --- /dev/null +++ b/src/common/settings.cpp @@ -0,0 +1,143 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include <string_view> + +#include "common/assert.h" +#include "common/file_util.h" +#include "common/logging/log.h" +#include "common/settings.h" + +namespace Settings { + +Values values = {}; +static bool configuring_global = true; + +std::string GetTimeZoneString() { + static constexpr std::array timezones{ + "auto", "default", "CET", "CST6CDT", "Cuba", "EET", "Egypt", "Eire", + "EST", "EST5EDT", "GB", "GB-Eire", "GMT", "GMT+0", "GMT-0", "GMT0", + "Greenwich", "Hongkong", "HST", "Iceland", "Iran", "Israel", "Jamaica", "Japan", + "Kwajalein", "Libya", "MET", "MST", "MST7MDT", "Navajo", "NZ", "NZ-CHAT", + "Poland", "Portugal", "PRC", "PST8PDT", "ROC", "ROK", "Singapore", "Turkey", + "UCT", "Universal", "UTC", "W-SU", "WET", "Zulu", + }; + + const auto time_zone_index = static_cast<std::size_t>(values.time_zone_index.GetValue()); + ASSERT(time_zone_index < timezones.size()); + return timezones[time_zone_index]; +} + +void LogSettings() { + const auto log_setting = [](std::string_view name, const auto& value) { + LOG_INFO(Config, "{}: {}", name, value); + }; + + LOG_INFO(Config, "yuzu Configuration:"); + log_setting("Controls_UseDockedMode", values.use_docked_mode.GetValue()); + log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0)); + log_setting("System_CurrentUser", values.current_user); + log_setting("System_LanguageIndex", values.language_index.GetValue()); + log_setting("System_RegionIndex", values.region_index.GetValue()); + log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue()); + log_setting("Core_UseMultiCore", values.use_multi_core.GetValue()); + log_setting("CPU_Accuracy", values.cpu_accuracy); + log_setting("Renderer_UseResolutionFactor", values.resolution_factor.GetValue()); + log_setting("Renderer_UseFrameLimit", values.use_frame_limit.GetValue()); + log_setting("Renderer_FrameLimit", values.frame_limit.GetValue()); + log_setting("Renderer_UseDiskShaderCache", values.use_disk_shader_cache.GetValue()); + log_setting("Renderer_GPUAccuracyLevel", values.gpu_accuracy.GetValue()); + log_setting("Renderer_UseAsynchronousGpuEmulation", + values.use_asynchronous_gpu_emulation.GetValue()); + log_setting("Renderer_UseNvdecEmulation", values.use_nvdec_emulation.GetValue()); + log_setting("Renderer_UseVsync", values.use_vsync.GetValue()); + log_setting("Renderer_UseAssemblyShaders", values.use_assembly_shaders.GetValue()); + log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); + log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); + log_setting("Audio_OutputEngine", values.sink_id); + log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); + log_setting("Audio_OutputDevice", values.audio_device_id); + log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd); + log_setting("DataStorage_CacheDir", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)); + log_setting("DataStorage_ConfigDir", Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir)); + log_setting("DataStorage_LoadDir", Common::FS::GetUserPath(Common::FS::UserPath::LoadDir)); + log_setting("DataStorage_NandDir", Common::FS::GetUserPath(Common::FS::UserPath::NANDDir)); + log_setting("DataStorage_SdmcDir", Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir)); + log_setting("Debugging_ProgramArgs", values.program_args); + log_setting("Services_BCATBackend", values.bcat_backend); + log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local); +} + +bool IsConfiguringGlobal() { + return configuring_global; +} + +void SetConfiguringGlobal(bool is_global) { + configuring_global = is_global; +} + +bool IsGPULevelExtreme() { + return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme; +} + +bool IsGPULevelHigh() { + return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme || + values.gpu_accuracy.GetValue() == GPUAccuracy::High; +} + +float Volume() { + if (values.audio_muted) { + return 0.0f; + } + 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.enable_audio_stretching.SetGlobal(true); + values.volume.SetGlobal(true); + + // Core + values.use_multi_core.SetGlobal(true); + + // Renderer + values.renderer_backend.SetGlobal(true); + values.vulkan_device.SetGlobal(true); + values.aspect_ratio.SetGlobal(true); + values.max_anisotropy.SetGlobal(true); + values.use_frame_limit.SetGlobal(true); + values.frame_limit.SetGlobal(true); + values.use_disk_shader_cache.SetGlobal(true); + values.gpu_accuracy.SetGlobal(true); + values.use_asynchronous_gpu_emulation.SetGlobal(true); + values.use_nvdec_emulation.SetGlobal(true); + values.use_vsync.SetGlobal(true); + values.use_assembly_shaders.SetGlobal(true); + values.use_asynchronous_shaders.SetGlobal(true); + values.use_fast_gpu_time.SetGlobal(true); + values.bg_red.SetGlobal(true); + values.bg_green.SetGlobal(true); + values.bg_blue.SetGlobal(true); + + // System + values.language_index.SetGlobal(true); + values.region_index.SetGlobal(true); + values.time_zone_index.SetGlobal(true); + values.rng_seed.SetGlobal(true); + values.custom_rtc.SetGlobal(true); + values.sound_index.SetGlobal(true); + + // Controls + values.players.SetGlobal(true); + values.use_docked_mode.SetGlobal(true); + values.vibration_enabled.SetGlobal(true); + values.motion_enabled.SetGlobal(true); +} + +} // namespace Settings diff --git a/src/common/settings.h b/src/common/settings.h new file mode 100644 index 000000000..d39b4aa45 --- /dev/null +++ b/src/common/settings.h @@ -0,0 +1,261 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <array> +#include <atomic> +#include <chrono> +#include <map> +#include <optional> +#include <string> +#include <vector> + +#include "common/common_types.h" +#include "common/settings_input.h" + +namespace Settings { + +enum class RendererBackend : u32 { + OpenGL = 0, + Vulkan = 1, +}; + +enum class GPUAccuracy : u32 { + Normal = 0, + High = 1, + Extreme = 2, +}; + +enum class CPUAccuracy : u32 { + Accurate = 0, + Unsafe = 1, + DebugMode = 2, +}; + +template <typename Type> +class Setting final { +public: + Setting() = default; + explicit Setting(Type val) : global{val} {} + ~Setting() = default; + void SetGlobal(bool to_global) { + use_global = to_global; + } + bool UsingGlobal() const { + return use_global; + } + Type GetValue(bool need_global = false) const { + if (use_global || need_global) { + return global; + } + return local; + } + void SetValue(const Type& value) { + if (use_global) { + global = value; + } else { + local = value; + } + } + +private: + bool use_global = true; + Type global{}; + Type local{}; +}; + +/** + * The InputSetting class allows for getting a reference to either the global or local 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 local (per-game) + * setting and allows for easily accessing and modifying both settings. + */ +template <typename Type> +class InputSetting final { +public: + InputSetting() = default; + explicit InputSetting(Type val) : global{val} {} + ~InputSetting() = default; + void SetGlobal(bool to_global) { + use_global = to_global; + } + bool UsingGlobal() const { + return use_global; + } + Type& GetValue(bool need_global = false) { + if (use_global || need_global) { + return global; + } + return local; + } + +private: + bool use_global = true; + Type global{}; + Type local{}; +}; + +struct TouchFromButtonMap { + std::string name; + std::vector<std::string> buttons; +}; + +struct Values { + // Audio + std::string audio_device_id; + std::string sink_id; + bool audio_muted; + Setting<bool> enable_audio_stretching; + Setting<float> volume; + + // Core + Setting<bool> use_multi_core; + + // Cpu + CPUAccuracy cpu_accuracy; + + bool cpuopt_page_tables; + bool cpuopt_block_linking; + bool cpuopt_return_stack_buffer; + bool cpuopt_fast_dispatcher; + bool cpuopt_context_elimination; + bool cpuopt_const_prop; + bool cpuopt_misc_ir; + bool cpuopt_reduce_misalign_checks; + + bool cpuopt_unsafe_unfuse_fma; + bool cpuopt_unsafe_reduce_fp_error; + bool cpuopt_unsafe_inaccurate_nan; + + // Renderer + Setting<RendererBackend> renderer_backend; + bool renderer_debug; + Setting<int> vulkan_device; + + Setting<u16> resolution_factor{1}; + Setting<int> fullscreen_mode; + Setting<int> aspect_ratio; + Setting<int> max_anisotropy; + Setting<bool> use_frame_limit; + Setting<u16> frame_limit; + Setting<bool> use_disk_shader_cache; + Setting<GPUAccuracy> gpu_accuracy; + Setting<bool> use_asynchronous_gpu_emulation; + Setting<bool> use_nvdec_emulation; + Setting<bool> use_vsync; + Setting<bool> use_assembly_shaders; + Setting<bool> use_asynchronous_shaders; + Setting<bool> use_fast_gpu_time; + + Setting<float> bg_red; + Setting<float> bg_green; + Setting<float> bg_blue; + + // System + Setting<std::optional<u32>> rng_seed; + // Measured in seconds since epoch + Setting<std::optional<std::chrono::seconds>> custom_rtc; + // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` + std::chrono::seconds custom_rtc_differential; + + s32 current_user; + Setting<s32> language_index; + Setting<s32> region_index; + Setting<s32> time_zone_index; + Setting<s32> sound_index; + + // Controls + InputSetting<std::array<PlayerInput, 10>> players; + + Setting<bool> use_docked_mode; + + Setting<bool> vibration_enabled; + Setting<bool> enable_accurate_vibrations; + + Setting<bool> motion_enabled; + std::string motion_device; + std::string udp_input_servers; + + bool mouse_panning; + float mouse_panning_sensitivity; + bool mouse_enabled; + std::string mouse_device; + MouseButtonsRaw mouse_buttons; + + bool emulate_analog_keyboard; + bool keyboard_enabled; + KeyboardKeysRaw keyboard_keys; + KeyboardModsRaw keyboard_mods; + + bool debug_pad_enabled; + ButtonsRaw debug_pad_buttons; + AnalogsRaw debug_pad_analogs; + + TouchscreenInput touchscreen; + + bool use_touch_from_button; + std::string touch_device; + int touch_from_button_map_index; + std::vector<TouchFromButtonMap> touch_from_button_maps; + + std::atomic_bool is_device_reload_pending{true}; + + // Data Storage + bool use_virtual_sd; + bool gamecard_inserted; + bool gamecard_current_game; + std::string gamecard_path; + + // Debugging + bool record_frame_times; + bool use_gdbstub; + u16 gdbstub_port; + std::string program_args; + bool dump_exefs; + bool dump_nso; + bool reporting_services; + bool quest_flag; + bool disable_macro_jit; + bool extended_logging; + bool use_debug_asserts; + bool use_auto_stub; + + // Miscellaneous + std::string log_filter; + bool use_dev_keys; + + // Services + std::string bcat_backend; + bool bcat_boxcat_local; + + // WebService + bool enable_telemetry; + std::string web_api_url; + std::string yuzu_username; + std::string yuzu_token; + + // Add-Ons + std::map<u64, std::vector<std::string>> disabled_addons; +}; + +extern Values values; + +bool IsConfiguringGlobal(); +void SetConfiguringGlobal(bool is_global); + +bool IsGPULevelExtreme(); +bool IsGPULevelHigh(); + +float Volume(); + +std::string GetTimeZoneString(); + +void LogSettings(); + +// Restore the global state of all applicable settings in the Values struct +void RestoreGlobalState(bool is_powered_on); + +} // namespace Settings diff --git a/src/common/settings_input.cpp b/src/common/settings_input.cpp new file mode 100644 index 000000000..bea2b837b --- /dev/null +++ b/src/common/settings_input.cpp @@ -0,0 +1,47 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/settings_input.h" + +namespace Settings { +namespace NativeButton { +const std::array<const char*, NumButtons> mapping = {{ + "button_a", "button_b", "button_x", "button_y", "button_lstick", + "button_rstick", "button_l", "button_r", "button_zl", "button_zr", + "button_plus", "button_minus", "button_dleft", "button_dup", "button_dright", + "button_ddown", "button_sl", "button_sr", "button_home", "button_screenshot", +}}; +} + +namespace NativeAnalog { +const std::array<const char*, NumAnalogs> mapping = {{ + "lstick", + "rstick", +}}; +} + +namespace NativeVibration { +const std::array<const char*, NumVibrations> mapping = {{ + "left_vibration_device", + "right_vibration_device", +}}; +} + +namespace NativeMotion { +const std::array<const char*, NumMotions> mapping = {{ + "motionleft", + "motionright", +}}; +} + +namespace NativeMouseButton { +const std::array<const char*, NumMouseButtons> mapping = {{ + "left", + "right", + "middle", + "forward", + "back", +}}; +} +} // namespace Settings diff --git a/src/common/settings_input.h b/src/common/settings_input.h new file mode 100644 index 000000000..609600582 --- /dev/null +++ b/src/common/settings_input.h @@ -0,0 +1,373 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <array> +#include <string> + +#include "common/common_types.h" + +namespace Settings { +namespace NativeButton { +enum Values : int { + A, + B, + X, + Y, + LStick, + RStick, + L, + R, + ZL, + ZR, + Plus, + Minus, + + DLeft, + DUp, + DRight, + DDown, + + SL, + SR, + + Home, + Screenshot, + + NumButtons, +}; + +constexpr int BUTTON_HID_BEGIN = A; +constexpr int BUTTON_NS_BEGIN = Home; + +constexpr int BUTTON_HID_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_NS = BUTTON_NS_END - BUTTON_NS_BEGIN; + +extern const std::array<const char*, NumButtons> mapping; + +} // namespace NativeButton + +namespace NativeAnalog { +enum Values : int { + LStick, + RStick, + + NumAnalogs, +}; + +constexpr int STICK_HID_BEGIN = LStick; +constexpr int STICK_HID_END = NumAnalogs; +constexpr int NUM_STICKS_HID = NumAnalogs; + +extern const std::array<const char*, NumAnalogs> mapping; +} // namespace NativeAnalog + +namespace NativeVibration { +enum Values : int { + LeftVibrationDevice, + RightVibrationDevice, + + NumVibrations, +}; + +constexpr int VIBRATION_HID_BEGIN = LeftVibrationDevice; +constexpr int VIBRATION_HID_END = NumVibrations; +constexpr int NUM_VIBRATIONS_HID = NumVibrations; + +extern const std::array<const char*, NumVibrations> mapping; +}; // namespace NativeVibration + +namespace NativeMotion { +enum Values : int { + MotionLeft, + MotionRight, + + NumMotions, +}; + +constexpr int MOTION_HID_BEGIN = MotionLeft; +constexpr int MOTION_HID_END = NumMotions; +constexpr int NUM_MOTIONS_HID = NumMotions; + +extern const std::array<const char*, NumMotions> mapping; +} // namespace NativeMotion + +namespace NativeMouseButton { +enum Values { + Left, + Right, + Middle, + Forward, + Back, + + NumMouseButtons, +}; + +constexpr int MOUSE_HID_BEGIN = Left; +constexpr int MOUSE_HID_END = NumMouseButtons; +constexpr int NUM_MOUSE_HID = NumMouseButtons; + +extern const std::array<const char*, NumMouseButtons> mapping; +} // namespace NativeMouseButton + +namespace NativeKeyboard { +enum Keys { + None, + Error, + + A = 4, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + N1, + N2, + N3, + N4, + N5, + N6, + N7, + N8, + N9, + N0, + Enter, + Escape, + Backspace, + Tab, + Space, + Minus, + Equal, + LeftBrace, + RightBrace, + Backslash, + Tilde, + Semicolon, + Apostrophe, + Grave, + Comma, + Dot, + Slash, + CapsLockKey, + + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + + SystemRequest, + ScrollLockKey, + Pause, + Insert, + Home, + PageUp, + Delete, + End, + PageDown, + Right, + Left, + Down, + Up, + + NumLockKey, + KPSlash, + KPAsterisk, + KPMinus, + KPPlus, + KPEnter, + KP1, + KP2, + KP3, + KP4, + KP5, + KP6, + KP7, + KP8, + KP9, + KP0, + KPDot, + + Key102, + Compose, + Power, + KPEqual, + + F13, + F14, + F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, + + Open, + Help, + Properties, + Front, + Stop, + Repeat, + Undo, + Cut, + Copy, + Paste, + Find, + Mute, + VolumeUp, + VolumeDown, + CapsLockActive, + NumLockActive, + ScrollLockActive, + KPComma, + + KPLeftParenthesis, + KPRightParenthesis, + + LeftControlKey = 0xE0, + LeftShiftKey, + LeftAltKey, + LeftMetaKey, + RightControlKey, + RightShiftKey, + RightAltKey, + RightMetaKey, + + MediaPlayPause, + MediaStopCD, + MediaPrevious, + MediaNext, + MediaEject, + MediaVolumeUp, + MediaVolumeDown, + MediaMute, + MediaWebsite, + MediaBack, + MediaForward, + MediaStop, + MediaFind, + MediaScrollUp, + MediaScrollDown, + MediaEdit, + MediaSleep, + MediaCoffee, + MediaRefresh, + MediaCalculator, + + NumKeyboardKeys, +}; + +static_assert(NumKeyboardKeys == 0xFC, "Incorrect number of keyboard keys."); + +enum Modifiers { + LeftControl, + LeftShift, + LeftAlt, + LeftMeta, + RightControl, + RightShift, + RightAlt, + RightMeta, + CapsLock, + ScrollLock, + NumLock, + + NumKeyboardMods, +}; + +constexpr int KEYBOARD_KEYS_HID_BEGIN = None; +constexpr int KEYBOARD_KEYS_HID_END = NumKeyboardKeys; +constexpr int NUM_KEYBOARD_KEYS_HID = NumKeyboardKeys; + +constexpr int KEYBOARD_MODS_HID_BEGIN = LeftControl; +constexpr int KEYBOARD_MODS_HID_END = NumKeyboardMods; +constexpr int NUM_KEYBOARD_MODS_HID = NumKeyboardMods; + +} // namespace NativeKeyboard + +using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>; +using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>; +using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>; +using VibrationsRaw = std::array<std::string, NativeVibration::NumVibrations>; + +using MouseButtonsRaw = std::array<std::string, NativeMouseButton::NumMouseButtons>; +using KeyboardKeysRaw = std::array<std::string, NativeKeyboard::NumKeyboardKeys>; +using KeyboardModsRaw = std::array<std::string, NativeKeyboard::NumKeyboardMods>; + +constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28; +constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A; +constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6; +constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E; + +enum class ControllerType { + ProController, + DualJoyconDetached, + LeftJoycon, + RightJoycon, + Handheld, + GameCube, +}; + +struct PlayerInput { + bool connected; + ControllerType controller_type; + ButtonsRaw buttons; + AnalogsRaw analogs; + VibrationsRaw vibrations; + MotionsRaw motions; + + bool vibration_enabled; + int vibration_strength; + + u32 body_color_left; + u32 body_color_right; + u32 button_color_left; + u32 button_color_right; +}; + +struct TouchscreenInput { + bool enabled; + std::string device; + + u32 finger; + u32 diameter_x; + u32 diameter_y; + u32 rotation_angle; +}; +} // namespace Settings |