diff options
Diffstat (limited to '')
| -rw-r--r-- | src/android/app/src/main/jni/config.cpp | 2 | ||||
| -rw-r--r-- | src/common/settings_common.h | 10 | ||||
| -rw-r--r-- | src/common/settings_setting.h | 33 | ||||
| -rw-r--r-- | src/core/crypto/key_manager.cpp | 8 | ||||
| -rw-r--r-- | src/core/file_sys/ips_layer.cpp | 4 | ||||
| -rw-r--r-- | src/core/memory/cheat_engine.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_ui.cpp | 7 | ||||
| -rw-r--r-- | src/yuzu/configuration/shared_widget.cpp | 171 | ||||
| -rw-r--r-- | src/yuzu/configuration/shared_widget.h | 21 | ||||
| -rw-r--r-- | src/yuzu_cmd/config.cpp | 2 | ||||
| -rw-r--r-- | src/yuzu_cmd/yuzu.cpp | 5 |
11 files changed, 200 insertions, 65 deletions
diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp index 34b425cb4..81120ab0f 100644 --- a/src/android/app/src/main/jni/config.cpp +++ b/src/android/app/src/main/jni/config.cpp | |||
| @@ -282,7 +282,7 @@ void Config::ReadValues() { | |||
| 282 | std::stringstream ss(title_list); | 282 | std::stringstream ss(title_list); |
| 283 | std::string line; | 283 | std::string line; |
| 284 | while (std::getline(ss, line, '|')) { | 284 | while (std::getline(ss, line, '|')) { |
| 285 | const auto title_id = std::stoul(line, nullptr, 16); | 285 | const auto title_id = std::strtoul(line.c_str(), nullptr, 16); |
| 286 | const auto disabled_list = config->Get("AddOns", "disabled_" + line, ""); | 286 | const auto disabled_list = config->Get("AddOns", "disabled_" + line, ""); |
| 287 | 287 | ||
| 288 | std::stringstream inner_ss(disabled_list); | 288 | std::stringstream inner_ss(disabled_list); |
diff --git a/src/common/settings_common.h b/src/common/settings_common.h index 5b170dfd5..1800ab10d 100644 --- a/src/common/settings_common.h +++ b/src/common/settings_common.h | |||
| @@ -225,6 +225,16 @@ public: | |||
| 225 | */ | 225 | */ |
| 226 | [[nodiscard]] virtual constexpr u32 EnumIndex() const = 0; | 226 | [[nodiscard]] virtual constexpr u32 EnumIndex() const = 0; |
| 227 | 227 | ||
| 228 | /** | ||
| 229 | * @returns True if the underlying type is a floating point storage | ||
| 230 | */ | ||
| 231 | [[nodiscard]] virtual constexpr bool IsFloatingPoint() const = 0; | ||
| 232 | |||
| 233 | /** | ||
| 234 | * @returns True if the underlying type is an integer storage | ||
| 235 | */ | ||
| 236 | [[nodiscard]] virtual constexpr bool IsIntegral() const = 0; | ||
| 237 | |||
| 228 | /* | 238 | /* |
| 229 | * Switchable settings | 239 | * Switchable settings |
| 230 | */ | 240 | */ |
diff --git a/src/common/settings_setting.h b/src/common/settings_setting.h index e10843c73..7be6f26f7 100644 --- a/src/common/settings_setting.h +++ b/src/common/settings_setting.h | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <string> | 10 | #include <string> |
| 11 | #include <typeindex> | 11 | #include <typeindex> |
| 12 | #include <typeinfo> | 12 | #include <typeinfo> |
| 13 | #include <fmt/core.h> | ||
| 13 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 14 | #include "common/settings_common.h" | 15 | #include "common/settings_common.h" |
| 15 | #include "common/settings_enums.h" | 16 | #include "common/settings_enums.h" |
| @@ -115,8 +116,12 @@ protected: | |||
| 115 | } else if constexpr (std::is_same_v<Type, AudioEngine>) { | 116 | } else if constexpr (std::is_same_v<Type, AudioEngine>) { |
| 116 | // Compatibility with old AudioEngine setting being a string | 117 | // Compatibility with old AudioEngine setting being a string |
| 117 | return CanonicalizeEnum(value_); | 118 | return CanonicalizeEnum(value_); |
| 119 | } else if constexpr (std::is_floating_point_v<Type>) { | ||
| 120 | return fmt::format("{:f}", value_); | ||
| 121 | } else if constexpr (std::is_enum_v<Type>) { | ||
| 122 | return std::to_string(static_cast<u32>(value_)); | ||
| 118 | } else { | 123 | } else { |
| 119 | return std::to_string(static_cast<u64>(value_)); | 124 | return std::to_string(value_); |
| 120 | } | 125 | } |
| 121 | } | 126 | } |
| 122 | 127 | ||
| @@ -180,13 +185,15 @@ public: | |||
| 180 | this->SetValue(static_cast<u32>(std::stoul(input))); | 185 | this->SetValue(static_cast<u32>(std::stoul(input))); |
| 181 | } else if constexpr (std::is_same_v<Type, bool>) { | 186 | } else if constexpr (std::is_same_v<Type, bool>) { |
| 182 | this->SetValue(input == "true"); | 187 | this->SetValue(input == "true"); |
| 183 | } else if constexpr (std::is_same_v<Type, AudioEngine>) { | 188 | } else if constexpr (std::is_same_v<Type, float>) { |
| 184 | this->SetValue(ToEnum<Type>(input)); | 189 | this->SetValue(std::stof(input)); |
| 185 | } else { | 190 | } else { |
| 186 | this->SetValue(static_cast<Type>(std::stoll(input))); | 191 | this->SetValue(static_cast<Type>(std::stoll(input))); |
| 187 | } | 192 | } |
| 188 | } catch (std::invalid_argument&) { | 193 | } catch (std::invalid_argument&) { |
| 189 | this->SetValue(this->GetDefault()); | 194 | this->SetValue(this->GetDefault()); |
| 195 | } catch (std::out_of_range&) { | ||
| 196 | this->SetValue(this->GetDefault()); | ||
| 190 | } | 197 | } |
| 191 | } | 198 | } |
| 192 | 199 | ||
| @@ -215,11 +222,27 @@ public: | |||
| 215 | } | 222 | } |
| 216 | } | 223 | } |
| 217 | 224 | ||
| 225 | [[nodiscard]] constexpr bool IsFloatingPoint() const final { | ||
| 226 | return std::is_floating_point_v<Type>; | ||
| 227 | } | ||
| 228 | |||
| 229 | [[nodiscard]] constexpr bool IsIntegral() const final { | ||
| 230 | return std::is_integral_v<Type>; | ||
| 231 | } | ||
| 232 | |||
| 218 | [[nodiscard]] std::string MinVal() const override final { | 233 | [[nodiscard]] std::string MinVal() const override final { |
| 219 | return this->ToString(minimum); | 234 | if constexpr (std::is_arithmetic_v<Type> && !ranged) { |
| 235 | return this->ToString(std::numeric_limits<Type>::min()); | ||
| 236 | } else { | ||
| 237 | return this->ToString(minimum); | ||
| 238 | } | ||
| 220 | } | 239 | } |
| 221 | [[nodiscard]] std::string MaxVal() const override final { | 240 | [[nodiscard]] std::string MaxVal() const override final { |
| 222 | return this->ToString(maximum); | 241 | if constexpr (std::is_arithmetic_v<Type> && !ranged) { |
| 242 | return this->ToString(std::numeric_limits<Type>::max()); | ||
| 243 | } else { | ||
| 244 | return this->ToString(maximum); | ||
| 245 | } | ||
| 223 | } | 246 | } |
| 224 | 247 | ||
| 225 | [[nodiscard]] constexpr bool Ranged() const override { | 248 | [[nodiscard]] constexpr bool Ranged() const override { |
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index e13c5cdc7..43a3c5ffd 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -724,14 +724,14 @@ void KeyManager::LoadFromFile(const std::filesystem::path& file_path, bool is_ti | |||
| 724 | continue; | 724 | continue; |
| 725 | } | 725 | } |
| 726 | 726 | ||
| 727 | const auto index = std::stoul(out[0].substr(8, 2), nullptr, 16); | 727 | const auto index = std::strtoul(out[0].substr(8, 2).c_str(), nullptr, 16); |
| 728 | keyblobs[index] = Common::HexStringToArray<0x90>(out[1]); | 728 | keyblobs[index] = Common::HexStringToArray<0x90>(out[1]); |
| 729 | } else if (out[0].compare(0, 18, "encrypted_keyblob_") == 0) { | 729 | } else if (out[0].compare(0, 18, "encrypted_keyblob_") == 0) { |
| 730 | if (!ValidCryptoRevisionString(out[0], 18, 2)) { | 730 | if (!ValidCryptoRevisionString(out[0], 18, 2)) { |
| 731 | continue; | 731 | continue; |
| 732 | } | 732 | } |
| 733 | 733 | ||
| 734 | const auto index = std::stoul(out[0].substr(18, 2), nullptr, 16); | 734 | const auto index = std::strtoul(out[0].substr(18, 2).c_str(), nullptr, 16); |
| 735 | encrypted_keyblobs[index] = Common::HexStringToArray<0xB0>(out[1]); | 735 | encrypted_keyblobs[index] = Common::HexStringToArray<0xB0>(out[1]); |
| 736 | } else if (out[0].compare(0, 20, "eticket_extended_kek") == 0) { | 736 | } else if (out[0].compare(0, 20, "eticket_extended_kek") == 0) { |
| 737 | eticket_extended_kek = Common::HexStringToArray<576>(out[1]); | 737 | eticket_extended_kek = Common::HexStringToArray<576>(out[1]); |
| @@ -750,7 +750,7 @@ void KeyManager::LoadFromFile(const std::filesystem::path& file_path, bool is_ti | |||
| 750 | } | 750 | } |
| 751 | if (out[0].compare(0, kv.second.size(), kv.second) == 0) { | 751 | if (out[0].compare(0, kv.second.size(), kv.second) == 0) { |
| 752 | const auto index = | 752 | const auto index = |
| 753 | std::stoul(out[0].substr(kv.second.size(), 2), nullptr, 16); | 753 | std::strtoul(out[0].substr(kv.second.size(), 2).c_str(), nullptr, 16); |
| 754 | const auto sub = kv.first.second; | 754 | const auto sub = kv.first.second; |
| 755 | if (sub == 0) { | 755 | if (sub == 0) { |
| 756 | s128_keys[{kv.first.first, index, 0}] = | 756 | s128_keys[{kv.first.first, index, 0}] = |
| @@ -770,7 +770,7 @@ void KeyManager::LoadFromFile(const std::filesystem::path& file_path, bool is_ti | |||
| 770 | const auto& match = kak_names[j]; | 770 | const auto& match = kak_names[j]; |
| 771 | if (out[0].compare(0, std::strlen(match), match) == 0) { | 771 | if (out[0].compare(0, std::strlen(match), match) == 0) { |
| 772 | const auto index = | 772 | const auto index = |
| 773 | std::stoul(out[0].substr(std::strlen(match), 2), nullptr, 16); | 773 | std::strtoul(out[0].substr(std::strlen(match), 2).c_str(), nullptr, 16); |
| 774 | s128_keys[{S128KeyType::KeyArea, index, j}] = | 774 | s128_keys[{S128KeyType::KeyArea, index, j}] = |
| 775 | Common::HexStringToArray<16>(out[1]); | 775 | Common::HexStringToArray<16>(out[1]); |
| 776 | } | 776 | } |
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp index efdf18cee..7be1322cc 100644 --- a/src/core/file_sys/ips_layer.cpp +++ b/src/core/file_sys/ips_layer.cpp | |||
| @@ -165,7 +165,7 @@ static std::string EscapeStringSequences(std::string in) { | |||
| 165 | void IPSwitchCompiler::ParseFlag(const std::string& line) { | 165 | void IPSwitchCompiler::ParseFlag(const std::string& line) { |
| 166 | if (StartsWith(line, "@flag offset_shift ")) { | 166 | if (StartsWith(line, "@flag offset_shift ")) { |
| 167 | // Offset Shift Flag | 167 | // Offset Shift Flag |
| 168 | offset_shift = std::stoll(line.substr(19), nullptr, 0); | 168 | offset_shift = std::strtoll(line.substr(19).c_str(), nullptr, 0); |
| 169 | } else if (StartsWith(line, "@little-endian")) { | 169 | } else if (StartsWith(line, "@little-endian")) { |
| 170 | // Set values to read as little endian | 170 | // Set values to read as little endian |
| 171 | is_little_endian = true; | 171 | is_little_endian = true; |
| @@ -263,7 +263,7 @@ void IPSwitchCompiler::Parse() { | |||
| 263 | // 11 - 8 hex digit offset + space + minimum two digit overwrite val | 263 | // 11 - 8 hex digit offset + space + minimum two digit overwrite val |
| 264 | if (patch_line.length() < 11) | 264 | if (patch_line.length() < 11) |
| 265 | break; | 265 | break; |
| 266 | auto offset = std::stoul(patch_line.substr(0, 8), nullptr, 16); | 266 | auto offset = std::strtoul(patch_line.substr(0, 8).c_str(), nullptr, 16); |
| 267 | offset += static_cast<unsigned long>(offset_shift); | 267 | offset += static_cast<unsigned long>(offset_shift); |
| 268 | 268 | ||
| 269 | std::vector<u8> replace; | 269 | std::vector<u8> replace; |
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index 7b52f61a7..a06e99166 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp | |||
| @@ -154,7 +154,7 @@ std::vector<CheatEntry> TextCheatParser::Parse(std::string_view data) const { | |||
| 154 | return {}; | 154 | return {}; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | const auto value = static_cast<u32>(std::stoul(hex, nullptr, 0x10)); | 157 | const auto value = static_cast<u32>(std::strtoul(hex.c_str(), nullptr, 0x10)); |
| 158 | out[*current_entry].definition.opcodes[out[*current_entry].definition.num_opcodes++] = | 158 | out[*current_entry].definition.opcodes[out[*current_entry].definition.num_opcodes++] = |
| 159 | value; | 159 | value; |
| 160 | 160 | ||
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp index 34ab01617..a9fde9f4f 100644 --- a/src/yuzu/configuration/configure_ui.cpp +++ b/src/yuzu/configuration/configure_ui.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include "yuzu/configuration/configure_ui.h" | 4 | #include "yuzu/configuration/configure_ui.h" |
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <cstdlib> | ||
| 7 | #include <set> | 8 | #include <set> |
| 8 | #include <stdexcept> | 9 | #include <stdexcept> |
| 9 | #include <string> | 10 | #include <string> |
| @@ -94,11 +95,7 @@ static void PopulateResolutionComboBox(QComboBox* screenshot_height, QWidget* pa | |||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | static u32 ScreenshotDimensionToInt(const QString& height) { | 97 | static u32 ScreenshotDimensionToInt(const QString& height) { |
| 97 | try { | 98 | return std::strtoul(height.toUtf8(), nullptr, 0); |
| 98 | return std::stoi(height.toStdString()); | ||
| 99 | } catch (std::invalid_argument&) { | ||
| 100 | return 0; | ||
| 101 | } | ||
| 102 | } | 99 | } |
| 103 | 100 | ||
| 104 | ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) | 101 | ConfigureUi::ConfigureUi(Core::System& system_, QWidget* parent) |
diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp index d63093985..ea8d7add4 100644 --- a/src/yuzu/configuration/shared_widget.cpp +++ b/src/yuzu/configuration/shared_widget.cpp | |||
| @@ -63,7 +63,7 @@ static QString DefaultSuffix(QWidget* parent, Settings::BasicSetting& setting) { | |||
| 63 | return tr("%", context.c_str()); | 63 | return tr("%", context.c_str()); |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | return QStringLiteral(""); | 66 | return default_suffix; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* parent) { | 69 | QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* parent) { |
| @@ -71,7 +71,7 @@ QPushButton* Widget::CreateRestoreGlobalButton(bool using_global, QWidget* paren | |||
| 71 | 71 | ||
| 72 | QStyle* style = parent->style(); | 72 | QStyle* style = parent->style(); |
| 73 | QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_LineEditClearButton)); | 73 | QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_LineEditClearButton)); |
| 74 | QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent); | 74 | QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(), parent); |
| 75 | restore_button->setObjectName(QStringLiteral("RestoreButton%1").arg(restore_button_count)); | 75 | restore_button->setObjectName(QStringLiteral("RestoreButton%1").arg(restore_button_count)); |
| 76 | restore_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); | 76 | restore_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); |
| 77 | 77 | ||
| @@ -151,7 +151,7 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer, | |||
| 151 | return -1; | 151 | return -1; |
| 152 | }; | 152 | }; |
| 153 | 153 | ||
| 154 | const u32 setting_value = std::stoi(setting.ToString()); | 154 | const u32 setting_value = std::strtoul(setting.ToString().c_str(), nullptr, 0); |
| 155 | combobox->setCurrentIndex(find_index(setting_value)); | 155 | combobox->setCurrentIndex(find_index(setting_value)); |
| 156 | 156 | ||
| 157 | serializer = [this, enumeration]() { | 157 | serializer = [this, enumeration]() { |
| @@ -160,7 +160,7 @@ QWidget* Widget::CreateCombobox(std::function<std::string()>& serializer, | |||
| 160 | }; | 160 | }; |
| 161 | 161 | ||
| 162 | restore_func = [this, find_index]() { | 162 | restore_func = [this, find_index]() { |
| 163 | const u32 global_value = std::stoi(RelevantDefault(setting)); | 163 | const u32 global_value = std::strtoul(RelevantDefault(setting).c_str(), nullptr, 0); |
| 164 | combobox->setCurrentIndex(find_index(global_value)); | 164 | combobox->setCurrentIndex(find_index(global_value)); |
| 165 | }; | 165 | }; |
| 166 | 166 | ||
| @@ -209,7 +209,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer, | |||
| 209 | } | 209 | } |
| 210 | }; | 210 | }; |
| 211 | 211 | ||
| 212 | const u32 setting_value = std::stoi(setting.ToString()); | 212 | const u32 setting_value = std::strtoul(setting.ToString().c_str(), nullptr, 0); |
| 213 | set_index(setting_value); | 213 | set_index(setting_value); |
| 214 | 214 | ||
| 215 | serializer = [get_selected]() { | 215 | serializer = [get_selected]() { |
| @@ -218,7 +218,7 @@ QWidget* Widget::CreateRadioGroup(std::function<std::string()>& serializer, | |||
| 218 | }; | 218 | }; |
| 219 | 219 | ||
| 220 | restore_func = [this, set_index]() { | 220 | restore_func = [this, set_index]() { |
| 221 | const u32 global_value = std::stoi(RelevantDefault(setting)); | 221 | const u32 global_value = std::strtoul(RelevantDefault(setting).c_str(), nullptr, 0); |
| 222 | set_index(global_value); | 222 | set_index(global_value); |
| 223 | }; | 223 | }; |
| 224 | 224 | ||
| @@ -255,6 +255,59 @@ QWidget* Widget::CreateLineEdit(std::function<std::string()>& serializer, | |||
| 255 | return line_edit; | 255 | return line_edit; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | static void CreateIntSlider(Settings::BasicSetting& setting, bool reversed, float multiplier, | ||
| 259 | QLabel* feedback, const QString& use_format, QSlider* slider, | ||
| 260 | std::function<std::string()>& serializer, | ||
| 261 | std::function<void()>& restore_func) { | ||
| 262 | const int max_val = std::strtol(setting.MaxVal().c_str(), nullptr, 0); | ||
| 263 | |||
| 264 | const auto update_feedback = [=](int value) { | ||
| 265 | int present = (reversed ? max_val - value : value) * multiplier + 0.5f; | ||
| 266 | feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); | ||
| 267 | }; | ||
| 268 | |||
| 269 | QObject::connect(slider, &QAbstractSlider::valueChanged, update_feedback); | ||
| 270 | update_feedback(std::strtol(setting.ToString().c_str(), nullptr, 0)); | ||
| 271 | |||
| 272 | slider->setMinimum(std::strtol(setting.MinVal().c_str(), nullptr, 0)); | ||
| 273 | slider->setMaximum(max_val); | ||
| 274 | slider->setValue(std::strtol(setting.ToString().c_str(), nullptr, 0)); | ||
| 275 | |||
| 276 | serializer = [slider]() { return std::to_string(slider->value()); }; | ||
| 277 | restore_func = [slider, &setting]() { | ||
| 278 | slider->setValue(std::strtol(RelevantDefault(setting).c_str(), nullptr, 0)); | ||
| 279 | }; | ||
| 280 | } | ||
| 281 | |||
| 282 | static void CreateFloatSlider(Settings::BasicSetting& setting, bool reversed, float multiplier, | ||
| 283 | QLabel* feedback, const QString& use_format, QSlider* slider, | ||
| 284 | std::function<std::string()>& serializer, | ||
| 285 | std::function<void()>& restore_func) { | ||
| 286 | const float max_val = std::strtof(setting.MaxVal().c_str(), nullptr); | ||
| 287 | const float min_val = std::strtof(setting.MinVal().c_str(), nullptr); | ||
| 288 | const float use_multiplier = | ||
| 289 | multiplier == default_multiplier ? default_float_multiplier : multiplier; | ||
| 290 | |||
| 291 | const auto update_feedback = [=](float value) { | ||
| 292 | int present = (reversed ? max_val - value : value) + 0.5f; | ||
| 293 | feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); | ||
| 294 | }; | ||
| 295 | |||
| 296 | QObject::connect(slider, &QAbstractSlider::valueChanged, update_feedback); | ||
| 297 | update_feedback(std::strtof(setting.ToString().c_str(), nullptr)); | ||
| 298 | |||
| 299 | slider->setMinimum(min_val * use_multiplier); | ||
| 300 | slider->setMaximum(max_val * use_multiplier); | ||
| 301 | slider->setValue(std::strtof(setting.ToString().c_str(), nullptr) * use_multiplier); | ||
| 302 | |||
| 303 | serializer = [slider, use_multiplier]() { | ||
| 304 | return std::to_string(slider->value() / use_multiplier); | ||
| 305 | }; | ||
| 306 | restore_func = [slider, &setting, use_multiplier]() { | ||
| 307 | slider->setValue(std::strtof(RelevantDefault(setting).c_str(), nullptr) * use_multiplier); | ||
| 308 | }; | ||
| 309 | } | ||
| 310 | |||
| 258 | QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix, | 311 | QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& given_suffix, |
| 259 | std::function<std::string()>& serializer, | 312 | std::function<std::string()>& serializer, |
| 260 | std::function<void()>& restore_func, | 313 | std::function<void()>& restore_func, |
| @@ -278,27 +331,19 @@ QWidget* Widget::CreateSlider(bool reversed, float multiplier, const QString& gi | |||
| 278 | 331 | ||
| 279 | layout->setContentsMargins(0, 0, 0, 0); | 332 | layout->setContentsMargins(0, 0, 0, 0); |
| 280 | 333 | ||
| 281 | int max_val = std::stoi(setting.MaxVal()); | 334 | QString suffix = given_suffix == default_suffix ? DefaultSuffix(this, setting) : given_suffix; |
| 282 | |||
| 283 | QString suffix = | ||
| 284 | given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; | ||
| 285 | 335 | ||
| 286 | const QString use_format = QStringLiteral("%1").append(suffix); | 336 | const QString use_format = QStringLiteral("%1").append(suffix); |
| 287 | 337 | ||
| 288 | QObject::connect(slider, &QAbstractSlider::valueChanged, [=](int value) { | 338 | if (setting.IsIntegral()) { |
| 289 | int present = (reversed ? max_val - value : value) * multiplier + 0.5f; | 339 | CreateIntSlider(setting, reversed, multiplier, feedback, use_format, slider, serializer, |
| 290 | feedback->setText(use_format.arg(QVariant::fromValue(present).value<QString>())); | 340 | restore_func); |
| 291 | }); | 341 | } else { |
| 292 | 342 | CreateFloatSlider(setting, reversed, multiplier, feedback, use_format, slider, serializer, | |
| 293 | slider->setMinimum(std::stoi(setting.MinVal())); | 343 | restore_func); |
| 294 | slider->setMaximum(max_val); | 344 | } |
| 295 | slider->setValue(std::stoi(setting.ToString())); | ||
| 296 | 345 | ||
| 297 | slider->setInvertedAppearance(reversed); | 346 | slider->setInvertedAppearance(reversed); |
| 298 | slider->setInvertedControls(reversed); | ||
| 299 | |||
| 300 | serializer = [this]() { return std::to_string(slider->value()); }; | ||
| 301 | restore_func = [this]() { slider->setValue(std::stoi(RelevantDefault(setting))); }; | ||
| 302 | 347 | ||
| 303 | if (!Settings::IsConfiguringGlobal()) { | 348 | if (!Settings::IsConfiguringGlobal()) { |
| 304 | QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); }); | 349 | QObject::connect(slider, &QAbstractSlider::actionTriggered, [touch]() { touch(); }); |
| @@ -311,14 +356,11 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix, | |||
| 311 | std::function<std::string()>& serializer, | 356 | std::function<std::string()>& serializer, |
| 312 | std::function<void()>& restore_func, | 357 | std::function<void()>& restore_func, |
| 313 | const std::function<void()>& touch) { | 358 | const std::function<void()>& touch) { |
| 314 | const int min_val = | 359 | const auto min_val = std::strtol(setting.MinVal().c_str(), nullptr, 0); |
| 315 | setting.Ranged() ? std::stoi(setting.MinVal()) : std::numeric_limits<int>::min(); | 360 | const auto max_val = std::strtol(setting.MaxVal().c_str(), nullptr, 0); |
| 316 | const int max_val = | 361 | const auto default_val = std::strtol(setting.ToString().c_str(), nullptr, 0); |
| 317 | setting.Ranged() ? std::stoi(setting.MaxVal()) : std::numeric_limits<int>::max(); | ||
| 318 | const int default_val = std::stoi(setting.ToString()); | ||
| 319 | 362 | ||
| 320 | QString suffix = | 363 | QString suffix = given_suffix == default_suffix ? DefaultSuffix(this, setting) : given_suffix; |
| 321 | given_suffix == QStringLiteral("") ? DefaultSuffix(this, setting) : given_suffix; | ||
| 322 | 364 | ||
| 323 | spinbox = new QSpinBox(this); | 365 | spinbox = new QSpinBox(this); |
| 324 | spinbox->setRange(min_val, max_val); | 366 | spinbox->setRange(min_val, max_val); |
| @@ -329,13 +371,13 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix, | |||
| 329 | serializer = [this]() { return std::to_string(spinbox->value()); }; | 371 | serializer = [this]() { return std::to_string(spinbox->value()); }; |
| 330 | 372 | ||
| 331 | restore_func = [this]() { | 373 | restore_func = [this]() { |
| 332 | auto value{std::stol(RelevantDefault(setting))}; | 374 | auto value{std::strtol(RelevantDefault(setting).c_str(), nullptr, 0)}; |
| 333 | spinbox->setValue(value); | 375 | spinbox->setValue(value); |
| 334 | }; | 376 | }; |
| 335 | 377 | ||
| 336 | if (!Settings::IsConfiguringGlobal()) { | 378 | if (!Settings::IsConfiguringGlobal()) { |
| 337 | QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() { | 379 | QObject::connect(spinbox, QOverload<int>::of(&QSpinBox::valueChanged), [this, touch]() { |
| 338 | if (spinbox->value() != std::stoi(setting.ToStringGlobal())) { | 380 | if (spinbox->value() != std::strtol(setting.ToStringGlobal().c_str(), nullptr, 0)) { |
| 339 | touch(); | 381 | touch(); |
| 340 | } | 382 | } |
| 341 | }); | 383 | }); |
| @@ -344,6 +386,42 @@ QWidget* Widget::CreateSpinBox(const QString& given_suffix, | |||
| 344 | return spinbox; | 386 | return spinbox; |
| 345 | } | 387 | } |
| 346 | 388 | ||
| 389 | QWidget* Widget::CreateDoubleSpinBox(const QString& given_suffix, | ||
| 390 | std::function<std::string()>& serializer, | ||
| 391 | std::function<void()>& restore_func, | ||
| 392 | const std::function<void()>& touch) { | ||
| 393 | const auto min_val = std::strtod(setting.MinVal().c_str(), nullptr); | ||
| 394 | const auto max_val = std::strtod(setting.MaxVal().c_str(), nullptr); | ||
| 395 | const auto default_val = std::strtod(setting.ToString().c_str(), nullptr); | ||
| 396 | |||
| 397 | QString suffix = given_suffix == default_suffix ? DefaultSuffix(this, setting) : given_suffix; | ||
| 398 | |||
| 399 | double_spinbox = new QDoubleSpinBox(this); | ||
| 400 | double_spinbox->setRange(min_val, max_val); | ||
| 401 | double_spinbox->setValue(default_val); | ||
| 402 | double_spinbox->setSuffix(suffix); | ||
| 403 | double_spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); | ||
| 404 | |||
| 405 | serializer = [this]() { return fmt::format("{:f}", double_spinbox->value()); }; | ||
| 406 | |||
| 407 | restore_func = [this]() { | ||
| 408 | auto value{std::strtod(RelevantDefault(setting).c_str(), nullptr)}; | ||
| 409 | double_spinbox->setValue(value); | ||
| 410 | }; | ||
| 411 | |||
| 412 | if (!Settings::IsConfiguringGlobal()) { | ||
| 413 | QObject::connect(double_spinbox, QOverload<double>::of(&QDoubleSpinBox::valueChanged), | ||
| 414 | [this, touch]() { | ||
| 415 | if (double_spinbox->value() != | ||
| 416 | std::strtod(setting.ToStringGlobal().c_str(), nullptr)) { | ||
| 417 | touch(); | ||
| 418 | } | ||
| 419 | }); | ||
| 420 | } | ||
| 421 | |||
| 422 | return double_spinbox; | ||
| 423 | } | ||
| 424 | |||
| 347 | QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | 425 | QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, |
| 348 | std::function<void()>& restore_func, | 426 | std::function<void()>& restore_func, |
| 349 | const std::function<void()>& touch) { | 427 | const std::function<void()>& touch) { |
| @@ -353,7 +431,8 @@ QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | |||
| 353 | } | 431 | } |
| 354 | 432 | ||
| 355 | auto to_hex = [=](const std::string& input) { | 433 | auto to_hex = [=](const std::string& input) { |
| 356 | return QString::fromStdString(fmt::format("{:08x}", std::stoul(input))); | 434 | return QString::fromStdString( |
| 435 | fmt::format("{:08x}", std::strtoul(input.c_str(), nullptr, 0))); | ||
| 357 | }; | 436 | }; |
| 358 | 437 | ||
| 359 | QRegularExpressionValidator* regex = new QRegularExpressionValidator( | 438 | QRegularExpressionValidator* regex = new QRegularExpressionValidator( |
| @@ -366,7 +445,7 @@ QWidget* Widget::CreateHexEdit(std::function<std::string()>& serializer, | |||
| 366 | line_edit->setValidator(regex); | 445 | line_edit->setValidator(regex); |
| 367 | 446 | ||
| 368 | auto hex_to_dec = [this]() -> std::string { | 447 | auto hex_to_dec = [this]() -> std::string { |
| 369 | return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16)); | 448 | return std::to_string(std::strtoul(line_edit->text().toStdString().c_str(), nullptr, 16)); |
| 370 | }; | 449 | }; |
| 371 | 450 | ||
| 372 | serializer = [hex_to_dec]() { return hex_to_dec(); }; | 451 | serializer = [hex_to_dec]() { return hex_to_dec(); }; |
| @@ -386,7 +465,8 @@ QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict, | |||
| 386 | std::function<void()>& restore_func, | 465 | std::function<void()>& restore_func, |
| 387 | const std::function<void()>& touch) { | 466 | const std::function<void()>& touch) { |
| 388 | const long long current_time = QDateTime::currentSecsSinceEpoch(); | 467 | const long long current_time = QDateTime::currentSecsSinceEpoch(); |
| 389 | const s64 the_time = disabled ? current_time : std::stoll(setting.ToString()); | 468 | const s64 the_time = |
| 469 | disabled ? current_time : std::strtoll(setting.ToString().c_str(), nullptr, 0); | ||
| 390 | const auto default_val = QDateTime::fromSecsSinceEpoch(the_time); | 470 | const auto default_val = QDateTime::fromSecsSinceEpoch(the_time); |
| 391 | 471 | ||
| 392 | date_time_edit = new QDateTimeEdit(this); | 472 | date_time_edit = new QDateTimeEdit(this); |
| @@ -399,7 +479,7 @@ QWidget* Widget::CreateDateTimeEdit(bool disabled, bool restrict, | |||
| 399 | auto get_clear_val = [this, restrict, current_time]() { | 479 | auto get_clear_val = [this, restrict, current_time]() { |
| 400 | return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() { | 480 | return QDateTime::fromSecsSinceEpoch([this, restrict, current_time]() { |
| 401 | if (restrict && checkbox->checkState() == Qt::Checked) { | 481 | if (restrict && checkbox->checkState() == Qt::Checked) { |
| 402 | return std::stoll(RelevantDefault(setting)); | 482 | return std::strtoll(RelevantDefault(setting).c_str(), nullptr, 0); |
| 403 | } | 483 | } |
| 404 | return current_time; | 484 | return current_time; |
| 405 | }()); | 485 | }()); |
| @@ -506,8 +586,7 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu | |||
| 506 | } else { | 586 | } else { |
| 507 | data_component = CreateCombobox(serializer, restore_func, touch); | 587 | data_component = CreateCombobox(serializer, restore_func, touch); |
| 508 | } | 588 | } |
| 509 | } else if (type == typeid(u32) || type == typeid(int) || type == typeid(u16) || | 589 | } else if (setting.IsIntegral()) { |
| 510 | type == typeid(s64) || type == typeid(u8)) { | ||
| 511 | switch (request) { | 590 | switch (request) { |
| 512 | case RequestType::Slider: | 591 | case RequestType::Slider: |
| 513 | case RequestType::ReverseSlider: | 592 | case RequestType::ReverseSlider: |
| @@ -534,6 +613,20 @@ void Widget::SetupComponent(const QString& label, std::function<void()>& load_fu | |||
| 534 | default: | 613 | default: |
| 535 | UNIMPLEMENTED(); | 614 | UNIMPLEMENTED(); |
| 536 | } | 615 | } |
| 616 | } else if (setting.IsFloatingPoint()) { | ||
| 617 | switch (request) { | ||
| 618 | case RequestType::Default: | ||
| 619 | case RequestType::SpinBox: | ||
| 620 | data_component = CreateDoubleSpinBox(suffix, serializer, restore_func, touch); | ||
| 621 | break; | ||
| 622 | case RequestType::Slider: | ||
| 623 | case RequestType::ReverseSlider: | ||
| 624 | data_component = CreateSlider(request == RequestType::ReverseSlider, multiplier, suffix, | ||
| 625 | serializer, restore_func, touch); | ||
| 626 | break; | ||
| 627 | default: | ||
| 628 | UNIMPLEMENTED(); | ||
| 629 | } | ||
| 537 | } else if (type == typeid(std::string)) { | 630 | } else if (type == typeid(std::string)) { |
| 538 | switch (request) { | 631 | switch (request) { |
| 539 | case RequestType::Default: | 632 | case RequestType::Default: |
| @@ -638,10 +731,10 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati | |||
| 638 | return std::pair{translations.at(id).first, translations.at(id).second}; | 731 | return std::pair{translations.at(id).first, translations.at(id).second}; |
| 639 | } | 732 | } |
| 640 | LOG_WARNING(Frontend, "Translation table lacks entry for \"{}\"", setting_label); | 733 | LOG_WARNING(Frontend, "Translation table lacks entry for \"{}\"", setting_label); |
| 641 | return std::pair{QString::fromStdString(setting_label), QStringLiteral("")}; | 734 | return std::pair{QString::fromStdString(setting_label), QStringLiteral()}; |
| 642 | }(); | 735 | }(); |
| 643 | 736 | ||
| 644 | if (label == QStringLiteral("")) { | 737 | if (label == QStringLiteral()) { |
| 645 | LOG_DEBUG(Frontend, "Translation table has empty entry for \"{}\", skipping...", | 738 | LOG_DEBUG(Frontend, "Translation table has empty entry for \"{}\", skipping...", |
| 646 | setting.GetLabel()); | 739 | setting.GetLabel()); |
| 647 | return; | 740 | return; |
diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h index 5303dd898..226284cf3 100644 --- a/src/yuzu/configuration/shared_widget.h +++ b/src/yuzu/configuration/shared_widget.h | |||
| @@ -22,6 +22,7 @@ class QObject; | |||
| 22 | class QPushButton; | 22 | class QPushButton; |
| 23 | class QSlider; | 23 | class QSlider; |
| 24 | class QSpinBox; | 24 | class QSpinBox; |
| 25 | class QDoubleSpinBox; | ||
| 25 | class QRadioButton; | 26 | class QRadioButton; |
| 26 | 27 | ||
| 27 | namespace Settings { | 28 | namespace Settings { |
| @@ -43,6 +44,10 @@ enum class RequestType { | |||
| 43 | MaxEnum, | 44 | MaxEnum, |
| 44 | }; | 45 | }; |
| 45 | 46 | ||
| 47 | constexpr float default_multiplier{1.f}; | ||
| 48 | constexpr float default_float_multiplier{100.f}; | ||
| 49 | static const QString default_suffix = QStringLiteral(); | ||
| 50 | |||
| 46 | class Widget : public QWidget { | 51 | class Widget : public QWidget { |
| 47 | Q_OBJECT | 52 | Q_OBJECT |
| 48 | 53 | ||
| @@ -66,8 +71,9 @@ public: | |||
| 66 | const ComboboxTranslationMap& combobox_translations, QWidget* parent, | 71 | const ComboboxTranslationMap& combobox_translations, QWidget* parent, |
| 67 | bool runtime_lock, std::vector<std::function<void(bool)>>& apply_funcs_, | 72 | bool runtime_lock, std::vector<std::function<void(bool)>>& apply_funcs_, |
| 68 | RequestType request = RequestType::Default, bool managed = true, | 73 | RequestType request = RequestType::Default, bool managed = true, |
| 69 | float multiplier = 1.0f, Settings::BasicSetting* other_setting = nullptr, | 74 | float multiplier = default_multiplier, |
| 70 | const QString& suffix = QStringLiteral("")); | 75 | Settings::BasicSetting* other_setting = nullptr, |
| 76 | const QString& suffix = default_suffix); | ||
| 71 | virtual ~Widget(); | 77 | virtual ~Widget(); |
| 72 | 78 | ||
| 73 | /** | 79 | /** |
| @@ -89,6 +95,7 @@ public: | |||
| 89 | QPushButton* restore_button{}; ///< Restore button for custom configurations | 95 | QPushButton* restore_button{}; ///< Restore button for custom configurations |
| 90 | QLineEdit* line_edit{}; ///< QLineEdit, used for LineEdit and HexEdit | 96 | QLineEdit* line_edit{}; ///< QLineEdit, used for LineEdit and HexEdit |
| 91 | QSpinBox* spinbox{}; | 97 | QSpinBox* spinbox{}; |
| 98 | QDoubleSpinBox* double_spinbox{}; | ||
| 92 | QCheckBox* checkbox{}; | 99 | QCheckBox* checkbox{}; |
| 93 | QSlider* slider{}; | 100 | QSlider* slider{}; |
| 94 | QComboBox* combobox{}; | 101 | QComboBox* combobox{}; |
| @@ -126,6 +133,9 @@ private: | |||
| 126 | const std::function<void()>& touch); | 133 | const std::function<void()>& touch); |
| 127 | QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer, | 134 | QWidget* CreateSpinBox(const QString& suffix, std::function<std::string()>& serializer, |
| 128 | std::function<void()>& restore_func, const std::function<void()>& touch); | 135 | std::function<void()>& restore_func, const std::function<void()>& touch); |
| 136 | QWidget* CreateDoubleSpinBox(const QString& suffix, std::function<std::string()>& serializer, | ||
| 137 | std::function<void()>& restore_func, | ||
| 138 | const std::function<void()>& touch); | ||
| 129 | 139 | ||
| 130 | QWidget* parent; | 140 | QWidget* parent; |
| 131 | const TranslationMap& translations; | 141 | const TranslationMap& translations; |
| @@ -145,14 +155,15 @@ public: | |||
| 145 | Widget* BuildWidget(Settings::BasicSetting* setting, | 155 | Widget* BuildWidget(Settings::BasicSetting* setting, |
| 146 | std::vector<std::function<void(bool)>>& apply_funcs, | 156 | std::vector<std::function<void(bool)>>& apply_funcs, |
| 147 | RequestType request = RequestType::Default, bool managed = true, | 157 | RequestType request = RequestType::Default, bool managed = true, |
| 148 | float multiplier = 1.0f, Settings::BasicSetting* other_setting = nullptr, | 158 | float multiplier = default_multiplier, |
| 149 | const QString& suffix = QStringLiteral("")) const; | 159 | Settings::BasicSetting* other_setting = nullptr, |
| 160 | const QString& suffix = default_suffix) const; | ||
| 150 | 161 | ||
| 151 | Widget* BuildWidget(Settings::BasicSetting* setting, | 162 | Widget* BuildWidget(Settings::BasicSetting* setting, |
| 152 | std::vector<std::function<void(bool)>>& apply_funcs, | 163 | std::vector<std::function<void(bool)>>& apply_funcs, |
| 153 | Settings::BasicSetting* other_setting, | 164 | Settings::BasicSetting* other_setting, |
| 154 | RequestType request = RequestType::Default, | 165 | RequestType request = RequestType::Default, |
| 155 | const QString& suffix = QStringLiteral("")) const; | 166 | const QString& suffix = default_suffix) const; |
| 156 | 167 | ||
| 157 | const ComboboxTranslationMap& ComboboxTranslations() const; | 168 | const ComboboxTranslationMap& ComboboxTranslations() const; |
| 158 | 169 | ||
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index c42d98709..0d25ff400 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -259,7 +259,7 @@ void Config::ReadValues() { | |||
| 259 | std::stringstream ss(title_list); | 259 | std::stringstream ss(title_list); |
| 260 | std::string line; | 260 | std::string line; |
| 261 | while (std::getline(ss, line, '|')) { | 261 | while (std::getline(ss, line, '|')) { |
| 262 | const auto title_id = std::stoul(line, nullptr, 16); | 262 | const auto title_id = std::strtoul(line.c_str(), nullptr, 16); |
| 263 | const auto disabled_list = sdl2_config->Get("AddOns", "disabled_" + line, ""); | 263 | const auto disabled_list = sdl2_config->Get("AddOns", "disabled_" + line, ""); |
| 264 | 264 | ||
| 265 | std::stringstream inner_ss(disabled_list); | 265 | std::stringstream inner_ss(disabled_list); |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 55d0938f7..087cfaa26 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -264,8 +264,9 @@ int main(int argc, char** argv) { | |||
| 264 | nickname = match[1]; | 264 | nickname = match[1]; |
| 265 | password = match[2]; | 265 | password = match[2]; |
| 266 | address = match[3]; | 266 | address = match[3]; |
| 267 | if (!match[4].str().empty()) | 267 | if (!match[4].str().empty()) { |
| 268 | port = static_cast<u16>(std::stoi(match[4])); | 268 | port = static_cast<u16>(std::strtoul(match[4].str().c_str(), nullptr, 0)); |
| 269 | } | ||
| 269 | std::regex nickname_re("^[a-zA-Z0-9._\\- ]+$"); | 270 | std::regex nickname_re("^[a-zA-Z0-9._\\- ]+$"); |
| 270 | if (!std::regex_match(nickname, nickname_re)) { | 271 | if (!std::regex_match(nickname, nickname_re)) { |
| 271 | std::cout | 272 | std::cout |