diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/string_util.cpp | 57 | ||||
-rw-r--r-- | src/common/string_util.h | 33 | ||||
-rw-r--r-- | src/core/hle/kernel/process.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/process.h | 11 | ||||
-rw-r--r-- | src/core/hle/kernel/svc.cpp | 11 | ||||
-rw-r--r-- | src/core/hle/service/acc/acc.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/service/acc/profile_manager.cpp | 25 | ||||
-rw-r--r-- | src/core/hle/service/acc/profile_manager.h | 13 | ||||
-rw-r--r-- | src/core/hle/service/hid/controllers/npad.cpp | 1 | ||||
-rw-r--r-- | src/core/hle/service/nfp/nfp.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/service/service.cpp | 4 | ||||
-rw-r--r-- | src/core/settings.h | 2 | ||||
-rw-r--r-- | src/video_core/rasterizer_cache.h | 35 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_system.cpp | 7 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_system.ui | 4 |
15 files changed, 83 insertions, 134 deletions
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 731d1db34..14f7037d8 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -4,11 +4,10 @@ #include <algorithm> #include <cctype> -#include <cerrno> #include <codecvt> -#include <cstdio> #include <cstdlib> -#include <cstring> +#include <locale> +#include <sstream> #include "common/common_paths.h" #include "common/logging/log.h" #include "common/string_util.h" @@ -33,24 +32,6 @@ std::string ToUpper(std::string str) { return str; } -// For Debugging. Read out an u8 array. -std::string ArrayToString(const u8* data, std::size_t size, int line_len, bool spaces) { - std::ostringstream oss; - oss << std::setfill('0') << std::hex; - - for (int line = 0; size; ++data, --size) { - oss << std::setw(2) << (int)*data; - - if (line_len == ++line) { - oss << '\n'; - line = 0; - } else if (spaces) - oss << ' '; - } - - return oss.str(); -} - std::string StringFromBuffer(const std::vector<u8>& data) { return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); } @@ -75,40 +56,6 @@ std::string StripQuotes(const std::string& s) { return s; } -bool TryParse(const std::string& str, u32* const output) { - char* endptr = nullptr; - - // Reset errno to a value other than ERANGE - errno = 0; - - unsigned long value = strtoul(str.c_str(), &endptr, 0); - - if (!endptr || *endptr) - return false; - - if (errno == ERANGE) - return false; - -#if ULONG_MAX > UINT_MAX - if (value >= 0x100000000ull && value <= 0xFFFFFFFF00000000ull) - return false; -#endif - - *output = static_cast<u32>(value); - return true; -} - -bool TryParse(const std::string& str, bool* const output) { - if ("1" == str || "true" == ToLower(str)) - *output = true; - else if ("0" == str || "false" == ToLower(str)) - *output = false; - else - return false; - - return true; -} - std::string StringFromBool(bool value) { return value ? "True" : "False"; } diff --git a/src/common/string_util.h b/src/common/string_util.h index 32bf6a19c..08f96533b 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h @@ -5,8 +5,6 @@ #pragma once #include <cstddef> -#include <iomanip> -#include <sstream> #include <string> #include <vector> #include "common/common_types.h" @@ -19,44 +17,13 @@ std::string ToLower(std::string str); /// Make a string uppercase std::string ToUpper(std::string str); -std::string ArrayToString(const u8* data, std::size_t size, int line_len = 20, bool spaces = true); - std::string StringFromBuffer(const std::vector<u8>& data); std::string StripSpaces(const std::string& s); std::string StripQuotes(const std::string& s); -// Thousand separator. Turns 12345678 into 12,345,678 -template <typename I> -std::string ThousandSeparate(I value, int spaces = 0) { - std::ostringstream oss; - -// std::locale("") seems to be broken on many platforms -#if defined _WIN32 || (defined __linux__ && !defined __clang__) - oss.imbue(std::locale("")); -#endif - oss << std::setw(spaces) << value; - - return oss.str(); -} - std::string StringFromBool(bool value); -bool TryParse(const std::string& str, bool* output); -bool TryParse(const std::string& str, u32* output); - -template <typename N> -static bool TryParse(const std::string& str, N* const output) { - std::istringstream iss(str); - - N tmp = 0; - if (iss >> tmp) { - *output = tmp; - return true; - } else - return false; -} - std::string TabsToSpaces(int tab_size, std::string in); void SplitString(const std::string& str, char delim, std::vector<std::string>& output); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index e78e3a950..f06b6bb55 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -15,6 +15,7 @@ #include "core/hle/kernel/thread.h" #include "core/hle/kernel/vm_manager.h" #include "core/memory.h" +#include "core/settings.h" namespace Kernel { @@ -33,6 +34,11 @@ SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) { process->process_id = kernel.CreateNewProcessID(); process->svc_access_mask.set(); + std::mt19937 rng(Settings::values.rng_seed.value_or(0)); + std::uniform_int_distribution<u64> distribution; + std::generate(process->random_entropy.begin(), process->random_entropy.end(), + [&] { return distribution(rng); }); + kernel.AppendNewProcess(process); return process; } diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index f79f6d7a5..cf48787ce 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -8,6 +8,7 @@ #include <bitset> #include <cstddef> #include <memory> +#include <random> #include <string> #include <vector> #include <boost/container/static_vector.hpp> @@ -119,6 +120,8 @@ struct CodeSet final { class Process final : public Object { public: + static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; + static SharedPtr<Process> Create(KernelCore& kernel, std::string&& name); std::string GetTypeName() const override { @@ -212,6 +215,11 @@ public: total_process_running_time_ticks += ticks; } + /// Gets 8 bytes of random data for svcGetInfo RandomEntropy + u64 GetRandomEntropy(std::size_t index) const { + return random_entropy.at(index); + } + /** * Loads process-specifics configuration info with metadata provided * by an executable. @@ -310,6 +318,9 @@ private: /// Per-process handle table for storing created object handles in. HandleTable handle_table; + /// Random values for svcGetInfo RandomEntropy + std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy; + std::string name; }; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 0bfe1e3be..b0b6508d9 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -559,7 +559,16 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id) *result = 0; break; case GetInfoType::RandomEntropy: - *result = Settings::values.rng_seed.value_or(0); + if (handle != 0) { + return ERR_INVALID_HANDLE; + } + + if (info_sub_id >= Process::RANDOM_ENTROPY_SIZE) { + return ERR_INVALID_COMBINATION_KERNEL; + } + + *result = current_process->GetRandomEntropy(info_sub_id); + return RESULT_SUCCESS; break; case GetInfoType::ASLRRegionBaseAddr: *result = vm_manager.GetASLRRegionBaseAddress(); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 8318eff5f..c629f9357 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -252,8 +252,10 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex rb.PushRaw<u128>(INVALID_UUID); return; } - auto user_list = profile_manager->GetAllUsers(); - if (user_list.empty()) { + + const auto user_list = profile_manager->GetAllUsers(); + if (std::all_of(user_list.begin(), user_list.end(), + [](const auto& user) { return user.uuid == INVALID_UUID; })) { rb.Push(ResultCode(-1)); // TODO(ogniK): Find the correct error code rb.PushRaw<u128>(INVALID_UUID); return; diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index c08394e4c..968263846 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -2,8 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <cstring> #include <random> +#include <fmt/format.h> + #include "common/file_util.h" #include "core/hle/service/acc/profile_manager.h" #include "core/settings.h" @@ -39,6 +42,19 @@ UUID UUID::Generate() { return UUID{distribution(gen), distribution(gen)}; } +std::string UUID::Format() const { + return fmt::format("0x{:016X}{:016X}", uuid[1], uuid[0]); +} + +std::string UUID::FormatSwitch() const { + std::array<u8, 16> s{}; + std::memcpy(s.data(), uuid.data(), sizeof(u128)); + return fmt::format("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{" + ":02x}{:02x}{:02x}{:02x}{:02x}", + s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9], s[10], s[11], + s[12], s[13], s[14], s[15]); +} + ProfileManager::ProfileManager() { ParseUserSaveFile(); @@ -325,11 +341,12 @@ void ProfileManager::ParseUserSaveFile() { return; } - for (std::size_t i = 0; i < MAX_USERS; ++i) { - const auto& user = data.users[i]; + for (const auto& user : data.users) { + if (user.uuid == UUID(INVALID_UUID)) { + continue; + } - if (user.uuid != UUID(INVALID_UUID)) - AddUser({user.uuid, user.username, user.timestamp, {}, false}); + AddUser({user.uuid, user.username, user.timestamp, {}, false}); } std::stable_partition(profiles.begin(), profiles.end(), diff --git a/src/core/hle/service/acc/profile_manager.h b/src/core/hle/service/acc/profile_manager.h index 747c46c20..d2d8e6c6b 100644 --- a/src/core/hle/service/acc/profile_manager.h +++ b/src/core/hle/service/acc/profile_manager.h @@ -42,18 +42,9 @@ struct UUID { void Invalidate() { uuid = INVALID_UUID; } - std::string Format() const { - return fmt::format("0x{:016X}{:016X}", uuid[1], uuid[0]); - } - std::string FormatSwitch() const { - std::array<u8, 16> s{}; - std::memcpy(s.data(), uuid.data(), sizeof(u128)); - return fmt::format("{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{" - ":02x}{:02x}{:02x}{:02x}{:02x}", - s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9], s[10], s[11], - s[12], s[13], s[14], s[15]); - } + std::string Format() const; + std::string FormatSwitch() const; }; static_assert(sizeof(UUID) == 16, "UUID is an invalid size!"); diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index ff9b64be4..56c415e4e 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -310,6 +310,7 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) { dual_entry.pad_states.raw = pad_state.raw; dual_entry.l_stick = lstick_entry; dual_entry.r_stick = rstick_entry; + break; case NPadControllerType::JoyLeft: left_entry.connection_status.raw = 0; diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index c1af878fe..1d6e7756f 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp @@ -212,7 +212,7 @@ private: IPC::ResponseBuilder rb{ctx, 2}; auto amiibo = nfp_interface.GetAmiiboBuffer(); TagInfo tag_info{}; - std::memcpy(tag_info.uuid.data(), amiibo.uuid.data(), sizeof(tag_info.uuid.size())); + tag_info.uuid = amiibo.uuid; tag_info.uuid_length = static_cast<u8>(tag_info.uuid.size()); tag_info.protocol = 1; // TODO(ogniK): Figure out actual values diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index a4cf45267..1ec340466 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -80,8 +80,8 @@ namespace Service { * Creates a function string for logging, complete with the name (or header code, depending * on what's passed in) the port name, and all the cmd_buff arguments. */ -static std::string MakeFunctionString(const char* name, const char* port_name, - const u32* cmd_buff) { +[[maybe_unused]] static std::string MakeFunctionString(const char* name, const char* port_name, + const u32* cmd_buff) { // Number of params == bits 0-5 + bits 6-11 int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); diff --git a/src/core/settings.h b/src/core/settings.h index 83a1a7069..84dc5050b 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -115,7 +115,7 @@ struct Values { // System bool use_docked_mode; bool enable_nfc; - std::optional<u64> rng_seed; + std::optional<u32> rng_seed; s32 current_user; s32 language_index; diff --git a/src/video_core/rasterizer_cache.h b/src/video_core/rasterizer_cache.h index 6d41321fa..bcf0c15a4 100644 --- a/src/video_core/rasterizer_cache.h +++ b/src/video_core/rasterizer_cache.h @@ -5,6 +5,7 @@ #pragma once #include <set> +#include <unordered_map> #include <boost/icl/interval_map.hpp> #include <boost/range/iterator_range_core.hpp> @@ -88,29 +89,25 @@ public: /// Invalidates everything in the cache void InvalidateAll() { - while (object_cache.begin() != object_cache.end()) { - Unregister(*object_cache.begin()->second.begin()); + while (interval_cache.begin() != interval_cache.end()) { + Unregister(*interval_cache.begin()->second.begin()); } } protected: /// Tries to get an object from the cache with the specified address T TryGet(VAddr addr) const { - const ObjectInterval interval{addr}; - for (auto& pair : boost::make_iterator_range(object_cache.equal_range(interval))) { - for (auto& cached_object : pair.second) { - if (cached_object->GetAddr() == addr) { - return cached_object; - } - } - } + const auto iter = map_cache.find(addr); + if (iter != map_cache.end()) + return iter->second; return nullptr; } /// Register an object into the cache void Register(const T& object) { object->SetIsRegistered(true); - object_cache.add({GetInterval(object), ObjectSet{object}}); + interval_cache.add({GetInterval(object), ObjectSet{object}}); + map_cache.insert({object->GetAddr(), object}); rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), 1); } @@ -118,13 +115,13 @@ protected: void Unregister(const T& object) { object->SetIsRegistered(false); rasterizer.UpdatePagesCachedCount(object->GetAddr(), object->GetSizeInBytes(), -1); - // Only flush if use_accurate_gpu_emulation is enabled, as it incurs a performance hit if (Settings::values.use_accurate_gpu_emulation) { FlushObject(object); } - object_cache.subtract({GetInterval(object), ObjectSet{object}}); + interval_cache.subtract({GetInterval(object), ObjectSet{object}}); + map_cache.erase(object->GetAddr()); } /// Returns a ticks counter used for tracking when cached objects were last modified @@ -141,7 +138,7 @@ private: std::vector<T> objects; const ObjectInterval interval{addr, addr + size}; - for (auto& pair : boost::make_iterator_range(object_cache.equal_range(interval))) { + for (auto& pair : boost::make_iterator_range(interval_cache.equal_range(interval))) { for (auto& cached_object : pair.second) { if (!cached_object) { continue; @@ -167,15 +164,17 @@ private: } using ObjectSet = std::set<T>; - using ObjectCache = boost::icl::interval_map<VAddr, ObjectSet>; - using ObjectInterval = typename ObjectCache::interval_type; + using ObjectCache = std::unordered_map<VAddr, T>; + using IntervalCache = boost::icl::interval_map<VAddr, ObjectSet>; + using ObjectInterval = typename IntervalCache::interval_type; static auto GetInterval(const T& object) { return ObjectInterval::right_open(object->GetAddr(), object->GetAddr() + object->GetSizeInBytes()); } - ObjectCache object_cache; ///< Cache of objects - u64 modified_ticks{}; ///< Counter of cache state ticks, used for in-order flushing + ObjectCache map_cache; + IntervalCache interval_cache; ///< Cache of objects + u64 modified_ticks{}; ///< Counter of cache state ticks, used for in-order flushing VideoCore::RasterizerInterface& rasterizer; }; diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 67f07ecb1..ab5d46492 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -140,7 +140,7 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](bool checked) { ui->rng_seed_edit->setEnabled(checked); if (!checked) - ui->rng_seed_edit->setText(QStringLiteral("0000000000000000")); + ui->rng_seed_edit->setText(QStringLiteral("00000000")); }); scene = new QGraphicsScene; @@ -165,9 +165,8 @@ void ConfigureSystem::setConfiguration() { ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.has_value()); ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.has_value()); - const auto rng_seed = QString("%1") - .arg(Settings::values.rng_seed.value_or(0), 16, 16, QLatin1Char{'0'}) - .toUpper(); + const auto rng_seed = + QString("%1").arg(Settings::values.rng_seed.value_or(0), 8, 16, QLatin1Char{'0'}).toUpper(); ui->rng_seed_edit->setText(rng_seed); } diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui index d0fcd0163..a91580893 100644 --- a/src/yuzu/configuration/configure_system.ui +++ b/src/yuzu/configuration/configure_system.ui @@ -269,10 +269,10 @@ </font> </property> <property name="inputMask"> - <string>HHHHHHHHHHHHHHHH</string> + <string notr="true">HHHHHHHH</string> </property> <property name="maxLength"> - <number>16</number> + <number>8</number> </property> </widget> </item> |