summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/string_util.cpp57
-rw-r--r--src/common/string_util.h33
-rw-r--r--src/core/hle/kernel/process.cpp6
-rw-r--r--src/core/hle/kernel/process.h11
-rw-r--r--src/core/hle/kernel/svc.cpp11
-rw-r--r--src/core/hle/service/acc/acc.cpp6
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp25
-rw-r--r--src/core/hle/service/acc/profile_manager.h13
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp1
-rw-r--r--src/core/hle/service/nfp/nfp.cpp2
-rw-r--r--src/core/hle/service/service.cpp4
-rw-r--r--src/core/settings.h2
-rw-r--r--src/video_core/rasterizer_cache.h35
-rw-r--r--src/yuzu/configuration/configure_system.cpp7
-rw-r--r--src/yuzu/configuration/configure_system.ui4
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>