summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt6
-rw-r--r--src/common/assert.cpp14
-rw-r--r--src/common/assert.h14
-rw-r--r--src/common/common_sizes.h43
-rw-r--r--src/common/logging/backend.cpp28
-rw-r--r--src/common/logging/backend.h4
-rw-r--r--src/common/logging/filter.cpp4
-rw-r--r--src/common/logging/filter.h4
-rw-r--r--src/common/logging/log.h35
-rw-r--r--src/common/logging/text_formatter.cpp4
-rw-r--r--src/common/logging/text_formatter.h4
-rw-r--r--src/common/nvidia_flags.h2
-rw-r--r--src/common/settings.cpp143
-rw-r--r--src/common/settings.h261
-rw-r--r--src/common/settings_input.cpp47
-rw-r--r--src/common/settings_input.h373
-rw-r--r--src/common/threadsafe_queue.h10
17 files changed, 953 insertions, 43 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 788516ded..88644eeb6 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -97,6 +97,7 @@ add_custom_command(OUTPUT scm_rev.cpp
97add_library(common STATIC 97add_library(common STATIC
98 algorithm.h 98 algorithm.h
99 alignment.h 99 alignment.h
100 assert.cpp
100 assert.h 101 assert.h
101 atomic_ops.h 102 atomic_ops.h
102 detached_tasks.cpp 103 detached_tasks.cpp
@@ -109,6 +110,7 @@ add_library(common STATIC
109 cityhash.h 110 cityhash.h
110 common_funcs.h 111 common_funcs.h
111 common_paths.h 112 common_paths.h
113 common_sizes.h
112 common_types.h 114 common_types.h
113 concepts.h 115 concepts.h
114 div_ceil.h 116 div_ceil.h
@@ -150,6 +152,10 @@ add_library(common STATIC
150 scm_rev.cpp 152 scm_rev.cpp
151 scm_rev.h 153 scm_rev.h
152 scope_exit.h 154 scope_exit.h
155 settings.cpp
156 settings.h
157 settings_input.cpp
158 settings_input.h
153 spin_lock.cpp 159 spin_lock.cpp
154 spin_lock.h 160 spin_lock.h
155 stream.cpp 161 stream.cpp
diff --git a/src/common/assert.cpp b/src/common/assert.cpp
new file mode 100644
index 000000000..72f1121aa
--- /dev/null
+++ b/src/common/assert.cpp
@@ -0,0 +1,14 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6#include "common/common_funcs.h"
7
8#include "common/settings.h"
9
10void assert_handle_failure() {
11 if (Settings::values.use_debug_asserts) {
12 Crash();
13 }
14}
diff --git a/src/common/assert.h b/src/common/assert.h
index 06d7b5612..b3ba35c0f 100644
--- a/src/common/assert.h
+++ b/src/common/assert.h
@@ -4,10 +4,13 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <cstdlib>
8#include "common/common_funcs.h"
9#include "common/logging/log.h" 7#include "common/logging/log.h"
10 8
9// Sometimes we want to try to continue even after hitting an assert.
10// However touching this file yields a global recompilation as this header is included almost
11// everywhere. So let's just move the handling of the failed assert to a single cpp file.
12void assert_handle_failure();
13
11// For asserts we'd like to keep all the junk executed when an assert happens away from the 14// For asserts we'd like to keep all the junk executed when an assert happens away from the
12// important code in the function. One way of doing this is to put all the relevant code inside a 15// important code in the function. One way of doing this is to put all the relevant code inside a
13// lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to 16// lambda and force the compiler to not inline it. Unfortunately, MSVC seems to have no syntax to
@@ -17,15 +20,14 @@
17// enough for our purposes. 20// enough for our purposes.
18template <typename Fn> 21template <typename Fn>
19#if defined(_MSC_VER) 22#if defined(_MSC_VER)
20[[msvc::noinline, noreturn]] 23[[msvc::noinline]]
21#elif defined(__GNUC__) 24#elif defined(__GNUC__)
22[[gnu::cold, gnu::noinline, noreturn]] 25[[gnu::cold, gnu::noinline]]
23#endif 26#endif
24static void 27static void
25assert_noinline_call(const Fn& fn) { 28assert_noinline_call(const Fn& fn) {
26 fn(); 29 fn();
27 Crash(); 30 assert_handle_failure();
28 exit(1); // Keeps GCC's mouth shut about this actually returning
29} 31}
30 32
31#define ASSERT(_a_) \ 33#define ASSERT(_a_) \
diff --git a/src/common/common_sizes.h b/src/common/common_sizes.h
new file mode 100644
index 000000000..7e9fd968b
--- /dev/null
+++ b/src/common/common_sizes.h
@@ -0,0 +1,43 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <limits>
8
9#include "common/common_types.h"
10
11namespace Common {
12
13enum : u64 {
14 Size_1_KB = 0x400ULL,
15 Size_64_KB = 64ULL * Size_1_KB,
16 Size_128_KB = 128ULL * Size_1_KB,
17 Size_1_MB = 0x100000ULL,
18 Size_2_MB = 2ULL * Size_1_MB,
19 Size_4_MB = 4ULL * Size_1_MB,
20 Size_5_MB = 5ULL * Size_1_MB,
21 Size_14_MB = 14ULL * Size_1_MB,
22 Size_32_MB = 32ULL * Size_1_MB,
23 Size_33_MB = 33ULL * Size_1_MB,
24 Size_128_MB = 128ULL * Size_1_MB,
25 Size_448_MB = 448ULL * Size_1_MB,
26 Size_507_MB = 507ULL * Size_1_MB,
27 Size_562_MB = 562ULL * Size_1_MB,
28 Size_1554_MB = 1554ULL * Size_1_MB,
29 Size_2048_MB = 2048ULL * Size_1_MB,
30 Size_2193_MB = 2193ULL * Size_1_MB,
31 Size_3285_MB = 3285ULL * Size_1_MB,
32 Size_4916_MB = 4916ULL * Size_1_MB,
33 Size_1_GB = 0x40000000ULL,
34 Size_2_GB = 2ULL * Size_1_GB,
35 Size_4_GB = 4ULL * Size_1_GB,
36 Size_6_GB = 6ULL * Size_1_GB,
37 Size_8_GB = 8ULL * Size_1_GB,
38 Size_64_GB = 64ULL * Size_1_GB,
39 Size_512_GB = 512ULL * Size_1_GB,
40 Size_Invalid = std::numeric_limits<u64>::max(),
41};
42
43} // namespace Common
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 2d4d2e9e7..bc82905c0 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -21,11 +21,11 @@
21#include "common/logging/backend.h" 21#include "common/logging/backend.h"
22#include "common/logging/log.h" 22#include "common/logging/log.h"
23#include "common/logging/text_formatter.h" 23#include "common/logging/text_formatter.h"
24#include "common/settings.h"
24#include "common/string_util.h" 25#include "common/string_util.h"
25#include "common/threadsafe_queue.h" 26#include "common/threadsafe_queue.h"
26#include "core/settings.h"
27 27
28namespace Log { 28namespace Common::Log {
29 29
30/** 30/**
31 * Static state as a singleton. 31 * Static state as a singleton.
@@ -37,8 +37,11 @@ public:
37 return backend; 37 return backend;
38 } 38 }
39 39
40 Impl(Impl const&) = delete; 40 Impl(const Impl&) = delete;
41 const Impl& operator=(Impl const&) = delete; 41 Impl& operator=(const Impl&) = delete;
42
43 Impl(Impl&&) = delete;
44 Impl& operator=(Impl&&) = delete;
42 45
43 void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num, 46 void PushEntry(Class log_class, Level log_level, const char* filename, unsigned int line_num,
44 const char* function, std::string message) { 47 const char* function, std::string message) {
@@ -132,7 +135,7 @@ private:
132 std::mutex writing_mutex; 135 std::mutex writing_mutex;
133 std::thread backend_thread; 136 std::thread backend_thread;
134 std::vector<std::unique_ptr<Backend>> backends; 137 std::vector<std::unique_ptr<Backend>> backends;
135 Common::MPSCQueue<Log::Entry> message_queue; 138 MPSCQueue<Entry> message_queue;
136 Filter filter; 139 Filter filter;
137 std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()}; 140 std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
138}; 141};
@@ -146,16 +149,16 @@ void ColorConsoleBackend::Write(const Entry& entry) {
146} 149}
147 150
148FileBackend::FileBackend(const std::string& filename) : bytes_written(0) { 151FileBackend::FileBackend(const std::string& filename) : bytes_written(0) {
149 if (Common::FS::Exists(filename + ".old.txt")) { 152 if (FS::Exists(filename + ".old.txt")) {
150 Common::FS::Delete(filename + ".old.txt"); 153 FS::Delete(filename + ".old.txt");
151 } 154 }
152 if (Common::FS::Exists(filename)) { 155 if (FS::Exists(filename)) {
153 Common::FS::Rename(filename, filename + ".old.txt"); 156 FS::Rename(filename, filename + ".old.txt");
154 } 157 }
155 158
156 // _SH_DENYWR allows read only access to the file for other programs. 159 // _SH_DENYWR allows read only access to the file for other programs.
157 // It is #defined to 0 on other platforms 160 // It is #defined to 0 on other platforms
158 file = Common::FS::IOFile(filename, "w", _SH_DENYWR); 161 file = FS::IOFile(filename, "w", _SH_DENYWR);
159} 162}
160 163
161void FileBackend::Write(const Entry& entry) { 164void FileBackend::Write(const Entry& entry) {
@@ -182,7 +185,7 @@ void FileBackend::Write(const Entry& entry) {
182 185
183void DebuggerBackend::Write(const Entry& entry) { 186void DebuggerBackend::Write(const Entry& entry) {
184#ifdef _WIN32 187#ifdef _WIN32
185 ::OutputDebugStringW(Common::UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str()); 188 ::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str());
186#endif 189#endif
187} 190}
188 191
@@ -212,6 +215,7 @@ void DebuggerBackend::Write(const Entry& entry) {
212 SUB(Service, ARP) \ 215 SUB(Service, ARP) \
213 SUB(Service, BCAT) \ 216 SUB(Service, BCAT) \
214 SUB(Service, BPC) \ 217 SUB(Service, BPC) \
218 SUB(Service, BGTC) \
215 SUB(Service, BTDRV) \ 219 SUB(Service, BTDRV) \
216 SUB(Service, BTM) \ 220 SUB(Service, BTM) \
217 SUB(Service, Capture) \ 221 SUB(Service, Capture) \
@@ -341,4 +345,4 @@ void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
341 instance.PushEntry(log_class, log_level, filename, line_num, function, 345 instance.PushEntry(log_class, log_level, filename, line_num, function,
342 fmt::vformat(format, args)); 346 fmt::vformat(format, args));
343} 347}
344} // namespace Log 348} // namespace Common::Log
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h
index da1c2f185..84a544ea4 100644
--- a/src/common/logging/backend.h
+++ b/src/common/logging/backend.h
@@ -11,7 +11,7 @@
11#include "common/logging/filter.h" 11#include "common/logging/filter.h"
12#include "common/logging/log.h" 12#include "common/logging/log.h"
13 13
14namespace Log { 14namespace Common::Log {
15 15
16class Filter; 16class Filter;
17 17
@@ -135,4 +135,4 @@ const char* GetLevelName(Level log_level);
135 * never get the message 135 * never get the message
136 */ 136 */
137void SetGlobalFilter(const Filter& filter); 137void SetGlobalFilter(const Filter& filter);
138} // namespace Log \ No newline at end of file 138} // namespace Common::Log \ No newline at end of file
diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp
index 2eccbcd8d..20a2dd106 100644
--- a/src/common/logging/filter.cpp
+++ b/src/common/logging/filter.cpp
@@ -7,7 +7,7 @@
7#include "common/logging/filter.h" 7#include "common/logging/filter.h"
8#include "common/string_util.h" 8#include "common/string_util.h"
9 9
10namespace Log { 10namespace Common::Log {
11namespace { 11namespace {
12template <typename It> 12template <typename It>
13Level GetLevelByName(const It begin, const It end) { 13Level GetLevelByName(const It begin, const It end) {
@@ -103,4 +103,4 @@ bool Filter::IsDebug() const {
103 }); 103 });
104} 104}
105 105
106} // namespace Log 106} // namespace Common::Log
diff --git a/src/common/logging/filter.h b/src/common/logging/filter.h
index 773df6f2c..f5673a9f6 100644
--- a/src/common/logging/filter.h
+++ b/src/common/logging/filter.h
@@ -9,7 +9,7 @@
9#include <string_view> 9#include <string_view>
10#include "common/logging/log.h" 10#include "common/logging/log.h"
11 11
12namespace Log { 12namespace Common::Log {
13 13
14/** 14/**
15 * Implements a log message filter which allows different log classes to have different minimum 15 * Implements a log message filter which allows different log classes to have different minimum
@@ -51,4 +51,4 @@ public:
51private: 51private:
52 std::array<Level, static_cast<std::size_t>(Class::Count)> class_levels; 52 std::array<Level, static_cast<std::size_t>(Class::Count)> class_levels;
53}; 53};
54} // namespace Log 54} // namespace Common::Log
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index 835894918..1f0f8db52 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -7,7 +7,7 @@
7#include <fmt/format.h> 7#include <fmt/format.h>
8#include "common/common_types.h" 8#include "common/common_types.h"
9 9
10namespace Log { 10namespace Common::Log {
11 11
12// trims up to and including the last of ../, ..\, src/, src\ in a string 12// trims up to and including the last of ../, ..\, src/, src\ in a string
13constexpr const char* TrimSourcePath(std::string_view source) { 13constexpr const char* TrimSourcePath(std::string_view source) {
@@ -66,6 +66,7 @@ enum class Class : ClassType {
66 Service_ARP, ///< The ARP service 66 Service_ARP, ///< The ARP service
67 Service_Audio, ///< The Audio (Audio control) service 67 Service_Audio, ///< The Audio (Audio control) service
68 Service_BCAT, ///< The BCAT service 68 Service_BCAT, ///< The BCAT service
69 Service_BGTC, ///< The BGTC (Background Task Controller) service
69 Service_BPC, ///< The BPC service 70 Service_BPC, ///< The BPC service
70 Service_BTDRV, ///< The Bluetooth driver service 71 Service_BTDRV, ///< The Bluetooth driver service
71 Service_BTM, ///< The BTM service 72 Service_BTM, ///< The BTM service
@@ -147,28 +148,34 @@ void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsig
147 fmt::make_format_args(args...)); 148 fmt::make_format_args(args...));
148} 149}
149 150
150} // namespace Log 151} // namespace Common::Log
151 152
152#ifdef _DEBUG 153#ifdef _DEBUG
153#define LOG_TRACE(log_class, ...) \ 154#define LOG_TRACE(log_class, ...) \
154 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Trace, \ 155 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Trace, \
155 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 156 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
157 __VA_ARGS__)
156#else 158#else
157#define LOG_TRACE(log_class, fmt, ...) (void(0)) 159#define LOG_TRACE(log_class, fmt, ...) (void(0))
158#endif 160#endif
159 161
160#define LOG_DEBUG(log_class, ...) \ 162#define LOG_DEBUG(log_class, ...) \
161 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Debug, \ 163 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Debug, \
162 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 164 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
165 __VA_ARGS__)
163#define LOG_INFO(log_class, ...) \ 166#define LOG_INFO(log_class, ...) \
164 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Info, \ 167 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Info, \
165 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 168 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
169 __VA_ARGS__)
166#define LOG_WARNING(log_class, ...) \ 170#define LOG_WARNING(log_class, ...) \
167 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Warning, \ 171 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Warning, \
168 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 172 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
173 __VA_ARGS__)
169#define LOG_ERROR(log_class, ...) \ 174#define LOG_ERROR(log_class, ...) \
170 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Error, \ 175 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Error, \
171 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 176 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
177 __VA_ARGS__)
172#define LOG_CRITICAL(log_class, ...) \ 178#define LOG_CRITICAL(log_class, ...) \
173 ::Log::FmtLogMessage(::Log::Class::log_class, ::Log::Level::Critical, \ 179 Common::Log::FmtLogMessage(Common::Log::Class::log_class, Common::Log::Level::Critical, \
174 ::Log::TrimSourcePath(__FILE__), __LINE__, __func__, __VA_ARGS__) 180 Common::Log::TrimSourcePath(__FILE__), __LINE__, __func__, \
181 __VA_ARGS__)
diff --git a/src/common/logging/text_formatter.cpp b/src/common/logging/text_formatter.cpp
index 6a0605c63..80ee2cca1 100644
--- a/src/common/logging/text_formatter.cpp
+++ b/src/common/logging/text_formatter.cpp
@@ -16,7 +16,7 @@
16#include "common/logging/text_formatter.h" 16#include "common/logging/text_formatter.h"
17#include "common/string_util.h" 17#include "common/string_util.h"
18 18
19namespace Log { 19namespace Common::Log {
20 20
21std::string FormatLogMessage(const Entry& entry) { 21std::string FormatLogMessage(const Entry& entry) {
22 unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000); 22 unsigned int time_seconds = static_cast<unsigned int>(entry.timestamp.count() / 1000000);
@@ -108,4 +108,4 @@ void PrintColoredMessage(const Entry& entry) {
108#undef ESC 108#undef ESC
109#endif 109#endif
110} 110}
111} // namespace Log 111} // namespace Common::Log
diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h
index b6d9e57c8..171e74cfe 100644
--- a/src/common/logging/text_formatter.h
+++ b/src/common/logging/text_formatter.h
@@ -7,7 +7,7 @@
7#include <cstddef> 7#include <cstddef>
8#include <string> 8#include <string>
9 9
10namespace Log { 10namespace Common::Log {
11 11
12struct Entry; 12struct Entry;
13 13
@@ -17,4 +17,4 @@ std::string FormatLogMessage(const Entry& entry);
17void PrintMessage(const Entry& entry); 17void PrintMessage(const Entry& entry);
18/// Prints the same message as `PrintMessage`, but colored according to the severity level. 18/// Prints the same message as `PrintMessage`, but colored according to the severity level.
19void PrintColoredMessage(const Entry& entry); 19void PrintColoredMessage(const Entry& entry);
20} // namespace Log 20} // 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 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#pragma once
6
5namespace Common { 7namespace Common {
6 8
7/// Configure platform specific flags for Nvidia's driver 9/// 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 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <string_view>
6
7#include "common/assert.h"
8#include "common/file_util.h"
9#include "common/logging/log.h"
10#include "common/settings.h"
11
12namespace Settings {
13
14Values values = {};
15static bool configuring_global = true;
16
17std::string GetTimeZoneString() {
18 static constexpr std::array timezones{
19 "auto", "default", "CET", "CST6CDT", "Cuba", "EET", "Egypt", "Eire",
20 "EST", "EST5EDT", "GB", "GB-Eire", "GMT", "GMT+0", "GMT-0", "GMT0",
21 "Greenwich", "Hongkong", "HST", "Iceland", "Iran", "Israel", "Jamaica", "Japan",
22 "Kwajalein", "Libya", "MET", "MST", "MST7MDT", "Navajo", "NZ", "NZ-CHAT",
23 "Poland", "Portugal", "PRC", "PST8PDT", "ROC", "ROK", "Singapore", "Turkey",
24 "UCT", "Universal", "UTC", "W-SU", "WET", "Zulu",
25 };
26
27 const auto time_zone_index = static_cast<std::size_t>(values.time_zone_index.GetValue());
28 ASSERT(time_zone_index < timezones.size());
29 return timezones[time_zone_index];
30}
31
32void LogSettings() {
33 const auto log_setting = [](std::string_view name, const auto& value) {
34 LOG_INFO(Config, "{}: {}", name, value);
35 };
36
37 LOG_INFO(Config, "yuzu Configuration:");
38 log_setting("Controls_UseDockedMode", values.use_docked_mode.GetValue());
39 log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0));
40 log_setting("System_CurrentUser", values.current_user);
41 log_setting("System_LanguageIndex", values.language_index.GetValue());
42 log_setting("System_RegionIndex", values.region_index.GetValue());
43 log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue());
44 log_setting("Core_UseMultiCore", values.use_multi_core.GetValue());
45 log_setting("CPU_Accuracy", values.cpu_accuracy);
46 log_setting("Renderer_UseResolutionFactor", values.resolution_factor.GetValue());
47 log_setting("Renderer_UseFrameLimit", values.use_frame_limit.GetValue());
48 log_setting("Renderer_FrameLimit", values.frame_limit.GetValue());
49 log_setting("Renderer_UseDiskShaderCache", values.use_disk_shader_cache.GetValue());
50 log_setting("Renderer_GPUAccuracyLevel", values.gpu_accuracy.GetValue());
51 log_setting("Renderer_UseAsynchronousGpuEmulation",
52 values.use_asynchronous_gpu_emulation.GetValue());
53 log_setting("Renderer_UseNvdecEmulation", values.use_nvdec_emulation.GetValue());
54 log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
55 log_setting("Renderer_UseAssemblyShaders", values.use_assembly_shaders.GetValue());
56 log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
57 log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
58 log_setting("Audio_OutputEngine", values.sink_id);
59 log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
60 log_setting("Audio_OutputDevice", values.audio_device_id);
61 log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd);
62 log_setting("DataStorage_CacheDir", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir));
63 log_setting("DataStorage_ConfigDir", Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir));
64 log_setting("DataStorage_LoadDir", Common::FS::GetUserPath(Common::FS::UserPath::LoadDir));
65 log_setting("DataStorage_NandDir", Common::FS::GetUserPath(Common::FS::UserPath::NANDDir));
66 log_setting("DataStorage_SdmcDir", Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir));
67 log_setting("Debugging_ProgramArgs", values.program_args);
68 log_setting("Services_BCATBackend", values.bcat_backend);
69 log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local);
70}
71
72bool IsConfiguringGlobal() {
73 return configuring_global;
74}
75
76void SetConfiguringGlobal(bool is_global) {
77 configuring_global = is_global;
78}
79
80bool IsGPULevelExtreme() {
81 return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme;
82}
83
84bool IsGPULevelHigh() {
85 return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme ||
86 values.gpu_accuracy.GetValue() == GPUAccuracy::High;
87}
88
89float Volume() {
90 if (values.audio_muted) {
91 return 0.0f;
92 }
93 return values.volume.GetValue();
94}
95
96void RestoreGlobalState(bool is_powered_on) {
97 // If a game is running, DO NOT restore the global settings state
98 if (is_powered_on) {
99 return;
100 }
101
102 // Audio
103 values.enable_audio_stretching.SetGlobal(true);
104 values.volume.SetGlobal(true);
105
106 // Core
107 values.use_multi_core.SetGlobal(true);
108
109 // Renderer
110 values.renderer_backend.SetGlobal(true);
111 values.vulkan_device.SetGlobal(true);
112 values.aspect_ratio.SetGlobal(true);
113 values.max_anisotropy.SetGlobal(true);
114 values.use_frame_limit.SetGlobal(true);
115 values.frame_limit.SetGlobal(true);
116 values.use_disk_shader_cache.SetGlobal(true);
117 values.gpu_accuracy.SetGlobal(true);
118 values.use_asynchronous_gpu_emulation.SetGlobal(true);
119 values.use_nvdec_emulation.SetGlobal(true);
120 values.use_vsync.SetGlobal(true);
121 values.use_assembly_shaders.SetGlobal(true);
122 values.use_asynchronous_shaders.SetGlobal(true);
123 values.use_fast_gpu_time.SetGlobal(true);
124 values.bg_red.SetGlobal(true);
125 values.bg_green.SetGlobal(true);
126 values.bg_blue.SetGlobal(true);
127
128 // System
129 values.language_index.SetGlobal(true);
130 values.region_index.SetGlobal(true);
131 values.time_zone_index.SetGlobal(true);
132 values.rng_seed.SetGlobal(true);
133 values.custom_rtc.SetGlobal(true);
134 values.sound_index.SetGlobal(true);
135
136 // Controls
137 values.players.SetGlobal(true);
138 values.use_docked_mode.SetGlobal(true);
139 values.vibration_enabled.SetGlobal(true);
140 values.motion_enabled.SetGlobal(true);
141}
142
143} // 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 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <atomic>
9#include <chrono>
10#include <map>
11#include <optional>
12#include <string>
13#include <vector>
14
15#include "common/common_types.h"
16#include "common/settings_input.h"
17
18namespace Settings {
19
20enum class RendererBackend : u32 {
21 OpenGL = 0,
22 Vulkan = 1,
23};
24
25enum class GPUAccuracy : u32 {
26 Normal = 0,
27 High = 1,
28 Extreme = 2,
29};
30
31enum class CPUAccuracy : u32 {
32 Accurate = 0,
33 Unsafe = 1,
34 DebugMode = 2,
35};
36
37template <typename Type>
38class Setting final {
39public:
40 Setting() = default;
41 explicit Setting(Type val) : global{val} {}
42 ~Setting() = default;
43 void SetGlobal(bool to_global) {
44 use_global = to_global;
45 }
46 bool UsingGlobal() const {
47 return use_global;
48 }
49 Type GetValue(bool need_global = false) const {
50 if (use_global || need_global) {
51 return global;
52 }
53 return local;
54 }
55 void SetValue(const Type& value) {
56 if (use_global) {
57 global = value;
58 } else {
59 local = value;
60 }
61 }
62
63private:
64 bool use_global = true;
65 Type global{};
66 Type local{};
67};
68
69/**
70 * The InputSetting class allows for getting a reference to either the global or local members.
71 * This is required as we cannot easily modify the values of user-defined types within containers
72 * using the SetValue() member function found in the Setting class. The primary purpose of this
73 * class is to store an array of 10 PlayerInput structs for both the global and local (per-game)
74 * setting and allows for easily accessing and modifying both settings.
75 */
76template <typename Type>
77class InputSetting final {
78public:
79 InputSetting() = default;
80 explicit InputSetting(Type val) : global{val} {}
81 ~InputSetting() = default;
82 void SetGlobal(bool to_global) {
83 use_global = to_global;
84 }
85 bool UsingGlobal() const {
86 return use_global;
87 }
88 Type& GetValue(bool need_global = false) {
89 if (use_global || need_global) {
90 return global;
91 }
92 return local;
93 }
94
95private:
96 bool use_global = true;
97 Type global{};
98 Type local{};
99};
100
101struct TouchFromButtonMap {
102 std::string name;
103 std::vector<std::string> buttons;
104};
105
106struct Values {
107 // Audio
108 std::string audio_device_id;
109 std::string sink_id;
110 bool audio_muted;
111 Setting<bool> enable_audio_stretching;
112 Setting<float> volume;
113
114 // Core
115 Setting<bool> use_multi_core;
116
117 // Cpu
118 CPUAccuracy cpu_accuracy;
119
120 bool cpuopt_page_tables;
121 bool cpuopt_block_linking;
122 bool cpuopt_return_stack_buffer;
123 bool cpuopt_fast_dispatcher;
124 bool cpuopt_context_elimination;
125 bool cpuopt_const_prop;
126 bool cpuopt_misc_ir;
127 bool cpuopt_reduce_misalign_checks;
128
129 bool cpuopt_unsafe_unfuse_fma;
130 bool cpuopt_unsafe_reduce_fp_error;
131 bool cpuopt_unsafe_inaccurate_nan;
132
133 // Renderer
134 Setting<RendererBackend> renderer_backend;
135 bool renderer_debug;
136 Setting<int> vulkan_device;
137
138 Setting<u16> resolution_factor{1};
139 Setting<int> fullscreen_mode;
140 Setting<int> aspect_ratio;
141 Setting<int> max_anisotropy;
142 Setting<bool> use_frame_limit;
143 Setting<u16> frame_limit;
144 Setting<bool> use_disk_shader_cache;
145 Setting<GPUAccuracy> gpu_accuracy;
146 Setting<bool> use_asynchronous_gpu_emulation;
147 Setting<bool> use_nvdec_emulation;
148 Setting<bool> use_vsync;
149 Setting<bool> use_assembly_shaders;
150 Setting<bool> use_asynchronous_shaders;
151 Setting<bool> use_fast_gpu_time;
152
153 Setting<float> bg_red;
154 Setting<float> bg_green;
155 Setting<float> bg_blue;
156
157 // System
158 Setting<std::optional<u32>> rng_seed;
159 // Measured in seconds since epoch
160 Setting<std::optional<std::chrono::seconds>> custom_rtc;
161 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
162 std::chrono::seconds custom_rtc_differential;
163
164 s32 current_user;
165 Setting<s32> language_index;
166 Setting<s32> region_index;
167 Setting<s32> time_zone_index;
168 Setting<s32> sound_index;
169
170 // Controls
171 InputSetting<std::array<PlayerInput, 10>> players;
172
173 Setting<bool> use_docked_mode;
174
175 Setting<bool> vibration_enabled;
176 Setting<bool> enable_accurate_vibrations;
177
178 Setting<bool> motion_enabled;
179 std::string motion_device;
180 std::string udp_input_servers;
181
182 bool mouse_panning;
183 float mouse_panning_sensitivity;
184 bool mouse_enabled;
185 std::string mouse_device;
186 MouseButtonsRaw mouse_buttons;
187
188 bool emulate_analog_keyboard;
189 bool keyboard_enabled;
190 KeyboardKeysRaw keyboard_keys;
191 KeyboardModsRaw keyboard_mods;
192
193 bool debug_pad_enabled;
194 ButtonsRaw debug_pad_buttons;
195 AnalogsRaw debug_pad_analogs;
196
197 TouchscreenInput touchscreen;
198
199 bool use_touch_from_button;
200 std::string touch_device;
201 int touch_from_button_map_index;
202 std::vector<TouchFromButtonMap> touch_from_button_maps;
203
204 std::atomic_bool is_device_reload_pending{true};
205
206 // Data Storage
207 bool use_virtual_sd;
208 bool gamecard_inserted;
209 bool gamecard_current_game;
210 std::string gamecard_path;
211
212 // Debugging
213 bool record_frame_times;
214 bool use_gdbstub;
215 u16 gdbstub_port;
216 std::string program_args;
217 bool dump_exefs;
218 bool dump_nso;
219 bool reporting_services;
220 bool quest_flag;
221 bool disable_macro_jit;
222 bool extended_logging;
223 bool use_debug_asserts;
224 bool use_auto_stub;
225
226 // Miscellaneous
227 std::string log_filter;
228 bool use_dev_keys;
229
230 // Services
231 std::string bcat_backend;
232 bool bcat_boxcat_local;
233
234 // WebService
235 bool enable_telemetry;
236 std::string web_api_url;
237 std::string yuzu_username;
238 std::string yuzu_token;
239
240 // Add-Ons
241 std::map<u64, std::vector<std::string>> disabled_addons;
242};
243
244extern Values values;
245
246bool IsConfiguringGlobal();
247void SetConfiguringGlobal(bool is_global);
248
249bool IsGPULevelExtreme();
250bool IsGPULevelHigh();
251
252float Volume();
253
254std::string GetTimeZoneString();
255
256void LogSettings();
257
258// Restore the global state of all applicable settings in the Values struct
259void RestoreGlobalState(bool is_powered_on);
260
261} // 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 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/settings_input.h"
6
7namespace Settings {
8namespace NativeButton {
9const std::array<const char*, NumButtons> mapping = {{
10 "button_a", "button_b", "button_x", "button_y", "button_lstick",
11 "button_rstick", "button_l", "button_r", "button_zl", "button_zr",
12 "button_plus", "button_minus", "button_dleft", "button_dup", "button_dright",
13 "button_ddown", "button_sl", "button_sr", "button_home", "button_screenshot",
14}};
15}
16
17namespace NativeAnalog {
18const std::array<const char*, NumAnalogs> mapping = {{
19 "lstick",
20 "rstick",
21}};
22}
23
24namespace NativeVibration {
25const std::array<const char*, NumVibrations> mapping = {{
26 "left_vibration_device",
27 "right_vibration_device",
28}};
29}
30
31namespace NativeMotion {
32const std::array<const char*, NumMotions> mapping = {{
33 "motionleft",
34 "motionright",
35}};
36}
37
38namespace NativeMouseButton {
39const std::array<const char*, NumMouseButtons> mapping = {{
40 "left",
41 "right",
42 "middle",
43 "forward",
44 "back",
45}};
46}
47} // 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 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include <string>
9
10#include "common/common_types.h"
11
12namespace Settings {
13namespace NativeButton {
14enum Values : int {
15 A,
16 B,
17 X,
18 Y,
19 LStick,
20 RStick,
21 L,
22 R,
23 ZL,
24 ZR,
25 Plus,
26 Minus,
27
28 DLeft,
29 DUp,
30 DRight,
31 DDown,
32
33 SL,
34 SR,
35
36 Home,
37 Screenshot,
38
39 NumButtons,
40};
41
42constexpr int BUTTON_HID_BEGIN = A;
43constexpr int BUTTON_NS_BEGIN = Home;
44
45constexpr int BUTTON_HID_END = BUTTON_NS_BEGIN;
46constexpr int BUTTON_NS_END = NumButtons;
47
48constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
49constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
50
51extern const std::array<const char*, NumButtons> mapping;
52
53} // namespace NativeButton
54
55namespace NativeAnalog {
56enum Values : int {
57 LStick,
58 RStick,
59
60 NumAnalogs,
61};
62
63constexpr int STICK_HID_BEGIN = LStick;
64constexpr int STICK_HID_END = NumAnalogs;
65constexpr int NUM_STICKS_HID = NumAnalogs;
66
67extern const std::array<const char*, NumAnalogs> mapping;
68} // namespace NativeAnalog
69
70namespace NativeVibration {
71enum Values : int {
72 LeftVibrationDevice,
73 RightVibrationDevice,
74
75 NumVibrations,
76};
77
78constexpr int VIBRATION_HID_BEGIN = LeftVibrationDevice;
79constexpr int VIBRATION_HID_END = NumVibrations;
80constexpr int NUM_VIBRATIONS_HID = NumVibrations;
81
82extern const std::array<const char*, NumVibrations> mapping;
83}; // namespace NativeVibration
84
85namespace NativeMotion {
86enum Values : int {
87 MotionLeft,
88 MotionRight,
89
90 NumMotions,
91};
92
93constexpr int MOTION_HID_BEGIN = MotionLeft;
94constexpr int MOTION_HID_END = NumMotions;
95constexpr int NUM_MOTIONS_HID = NumMotions;
96
97extern const std::array<const char*, NumMotions> mapping;
98} // namespace NativeMotion
99
100namespace NativeMouseButton {
101enum Values {
102 Left,
103 Right,
104 Middle,
105 Forward,
106 Back,
107
108 NumMouseButtons,
109};
110
111constexpr int MOUSE_HID_BEGIN = Left;
112constexpr int MOUSE_HID_END = NumMouseButtons;
113constexpr int NUM_MOUSE_HID = NumMouseButtons;
114
115extern const std::array<const char*, NumMouseButtons> mapping;
116} // namespace NativeMouseButton
117
118namespace NativeKeyboard {
119enum Keys {
120 None,
121 Error,
122
123 A = 4,
124 B,
125 C,
126 D,
127 E,
128 F,
129 G,
130 H,
131 I,
132 J,
133 K,
134 L,
135 M,
136 N,
137 O,
138 P,
139 Q,
140 R,
141 S,
142 T,
143 U,
144 V,
145 W,
146 X,
147 Y,
148 Z,
149 N1,
150 N2,
151 N3,
152 N4,
153 N5,
154 N6,
155 N7,
156 N8,
157 N9,
158 N0,
159 Enter,
160 Escape,
161 Backspace,
162 Tab,
163 Space,
164 Minus,
165 Equal,
166 LeftBrace,
167 RightBrace,
168 Backslash,
169 Tilde,
170 Semicolon,
171 Apostrophe,
172 Grave,
173 Comma,
174 Dot,
175 Slash,
176 CapsLockKey,
177
178 F1,
179 F2,
180 F3,
181 F4,
182 F5,
183 F6,
184 F7,
185 F8,
186 F9,
187 F10,
188 F11,
189 F12,
190
191 SystemRequest,
192 ScrollLockKey,
193 Pause,
194 Insert,
195 Home,
196 PageUp,
197 Delete,
198 End,
199 PageDown,
200 Right,
201 Left,
202 Down,
203 Up,
204
205 NumLockKey,
206 KPSlash,
207 KPAsterisk,
208 KPMinus,
209 KPPlus,
210 KPEnter,
211 KP1,
212 KP2,
213 KP3,
214 KP4,
215 KP5,
216 KP6,
217 KP7,
218 KP8,
219 KP9,
220 KP0,
221 KPDot,
222
223 Key102,
224 Compose,
225 Power,
226 KPEqual,
227
228 F13,
229 F14,
230 F15,
231 F16,
232 F17,
233 F18,
234 F19,
235 F20,
236 F21,
237 F22,
238 F23,
239 F24,
240
241 Open,
242 Help,
243 Properties,
244 Front,
245 Stop,
246 Repeat,
247 Undo,
248 Cut,
249 Copy,
250 Paste,
251 Find,
252 Mute,
253 VolumeUp,
254 VolumeDown,
255 CapsLockActive,
256 NumLockActive,
257 ScrollLockActive,
258 KPComma,
259
260 KPLeftParenthesis,
261 KPRightParenthesis,
262
263 LeftControlKey = 0xE0,
264 LeftShiftKey,
265 LeftAltKey,
266 LeftMetaKey,
267 RightControlKey,
268 RightShiftKey,
269 RightAltKey,
270 RightMetaKey,
271
272 MediaPlayPause,
273 MediaStopCD,
274 MediaPrevious,
275 MediaNext,
276 MediaEject,
277 MediaVolumeUp,
278 MediaVolumeDown,
279 MediaMute,
280 MediaWebsite,
281 MediaBack,
282 MediaForward,
283 MediaStop,
284 MediaFind,
285 MediaScrollUp,
286 MediaScrollDown,
287 MediaEdit,
288 MediaSleep,
289 MediaCoffee,
290 MediaRefresh,
291 MediaCalculator,
292
293 NumKeyboardKeys,
294};
295
296static_assert(NumKeyboardKeys == 0xFC, "Incorrect number of keyboard keys.");
297
298enum Modifiers {
299 LeftControl,
300 LeftShift,
301 LeftAlt,
302 LeftMeta,
303 RightControl,
304 RightShift,
305 RightAlt,
306 RightMeta,
307 CapsLock,
308 ScrollLock,
309 NumLock,
310
311 NumKeyboardMods,
312};
313
314constexpr int KEYBOARD_KEYS_HID_BEGIN = None;
315constexpr int KEYBOARD_KEYS_HID_END = NumKeyboardKeys;
316constexpr int NUM_KEYBOARD_KEYS_HID = NumKeyboardKeys;
317
318constexpr int KEYBOARD_MODS_HID_BEGIN = LeftControl;
319constexpr int KEYBOARD_MODS_HID_END = NumKeyboardMods;
320constexpr int NUM_KEYBOARD_MODS_HID = NumKeyboardMods;
321
322} // namespace NativeKeyboard
323
324using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>;
325using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>;
326using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>;
327using VibrationsRaw = std::array<std::string, NativeVibration::NumVibrations>;
328
329using MouseButtonsRaw = std::array<std::string, NativeMouseButton::NumMouseButtons>;
330using KeyboardKeysRaw = std::array<std::string, NativeKeyboard::NumKeyboardKeys>;
331using KeyboardModsRaw = std::array<std::string, NativeKeyboard::NumKeyboardMods>;
332
333constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28;
334constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A;
335constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6;
336constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E;
337
338enum class ControllerType {
339 ProController,
340 DualJoyconDetached,
341 LeftJoycon,
342 RightJoycon,
343 Handheld,
344 GameCube,
345};
346
347struct PlayerInput {
348 bool connected;
349 ControllerType controller_type;
350 ButtonsRaw buttons;
351 AnalogsRaw analogs;
352 VibrationsRaw vibrations;
353 MotionsRaw motions;
354
355 bool vibration_enabled;
356 int vibration_strength;
357
358 u32 body_color_left;
359 u32 body_color_right;
360 u32 button_color_left;
361 u32 button_color_right;
362};
363
364struct TouchscreenInput {
365 bool enabled;
366 std::string device;
367
368 u32 finger;
369 u32 diameter_x;
370 u32 diameter_y;
371 u32 rotation_angle;
372};
373} // namespace Settings
diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h
index a4647314a..ad04df8ca 100644
--- a/src/common/threadsafe_queue.h
+++ b/src/common/threadsafe_queue.h
@@ -83,11 +83,15 @@ public:
83 return true; 83 return true;
84 } 84 }
85 85
86 T PopWait() { 86 void Wait() {
87 if (Empty()) { 87 if (Empty()) {
88 std::unique_lock lock{cv_mutex}; 88 std::unique_lock lock{cv_mutex};
89 cv.wait(lock, [this]() { return !Empty(); }); 89 cv.wait(lock, [this]() { return !Empty(); });
90 } 90 }
91 }
92
93 T PopWait() {
94 Wait();
91 T t; 95 T t;
92 Pop(t); 96 Pop(t);
93 return t; 97 return t;
@@ -156,6 +160,10 @@ public:
156 return spsc_queue.Pop(t); 160 return spsc_queue.Pop(t);
157 } 161 }
158 162
163 void Wait() {
164 spsc_queue.Wait();
165 }
166
159 T PopWait() { 167 T PopWait() {
160 return spsc_queue.PopWait(); 168 return spsc_queue.PopWait();
161 } 169 }