diff options
Diffstat (limited to 'src')
33 files changed, 266 insertions, 242 deletions
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index ed1e93cc2..59b999935 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp | |||
| @@ -3,19 +3,20 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <array> | 6 | #include <atomic> |
| 7 | #include <chrono> | 7 | #include <chrono> |
| 8 | #include <climits> | 8 | #include <climits> |
| 9 | #include <condition_variable> | 9 | #include <condition_variable> |
| 10 | #include <memory> | 10 | #include <memory> |
| 11 | #include <mutex> | ||
| 11 | #include <thread> | 12 | #include <thread> |
| 13 | #include <vector> | ||
| 12 | #ifdef _WIN32 | 14 | #ifdef _WIN32 |
| 13 | #include <share.h> // For _SH_DENYWR | 15 | #include <share.h> // For _SH_DENYWR |
| 14 | #else | 16 | #else |
| 15 | #define _SH_DENYWR 0 | 17 | #define _SH_DENYWR 0 |
| 16 | #endif | 18 | #endif |
| 17 | #include "common/assert.h" | 19 | #include "common/assert.h" |
| 18 | #include "common/common_funcs.h" // snprintf compatibility define | ||
| 19 | #include "common/logging/backend.h" | 20 | #include "common/logging/backend.h" |
| 20 | #include "common/logging/log.h" | 21 | #include "common/logging/log.h" |
| 21 | #include "common/logging/text_formatter.h" | 22 | #include "common/logging/text_formatter.h" |
| @@ -48,11 +49,11 @@ public: | |||
| 48 | backends.push_back(std::move(backend)); | 49 | backends.push_back(std::move(backend)); |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | void RemoveBackend(const std::string& backend_name) { | 52 | void RemoveBackend(std::string_view backend_name) { |
| 52 | std::lock_guard<std::mutex> lock(writing_mutex); | 53 | std::lock_guard<std::mutex> lock(writing_mutex); |
| 53 | auto it = std::remove_if(backends.begin(), backends.end(), [&backend_name](const auto& i) { | 54 | const auto it = |
| 54 | return !strcmp(i->GetName(), backend_name.c_str()); | 55 | std::remove_if(backends.begin(), backends.end(), |
| 55 | }); | 56 | [&backend_name](const auto& i) { return backend_name == i->GetName(); }); |
| 56 | backends.erase(it, backends.end()); | 57 | backends.erase(it, backends.end()); |
| 57 | } | 58 | } |
| 58 | 59 | ||
| @@ -64,10 +65,10 @@ public: | |||
| 64 | filter = f; | 65 | filter = f; |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | Backend* GetBackend(const std::string& backend_name) { | 68 | Backend* GetBackend(std::string_view backend_name) { |
| 68 | auto it = std::find_if(backends.begin(), backends.end(), [&backend_name](const auto& i) { | 69 | const auto it = |
| 69 | return !strcmp(i->GetName(), backend_name.c_str()); | 70 | std::find_if(backends.begin(), backends.end(), |
| 70 | }); | 71 | [&backend_name](const auto& i) { return backend_name == i->GetName(); }); |
| 71 | if (it == backends.end()) | 72 | if (it == backends.end()) |
| 72 | return nullptr; | 73 | return nullptr; |
| 73 | return it->get(); | 74 | return it->get(); |
| @@ -265,11 +266,11 @@ void AddBackend(std::unique_ptr<Backend> backend) { | |||
| 265 | Impl::Instance().AddBackend(std::move(backend)); | 266 | Impl::Instance().AddBackend(std::move(backend)); |
| 266 | } | 267 | } |
| 267 | 268 | ||
| 268 | void RemoveBackend(const std::string& backend_name) { | 269 | void RemoveBackend(std::string_view backend_name) { |
| 269 | Impl::Instance().RemoveBackend(backend_name); | 270 | Impl::Instance().RemoveBackend(backend_name); |
| 270 | } | 271 | } |
| 271 | 272 | ||
| 272 | Backend* GetBackend(const std::string& backend_name) { | 273 | Backend* GetBackend(std::string_view backend_name) { |
| 273 | return Impl::Instance().GetBackend(backend_name); | 274 | return Impl::Instance().GetBackend(backend_name); |
| 274 | } | 275 | } |
| 275 | 276 | ||
diff --git a/src/common/logging/backend.h b/src/common/logging/backend.h index 57cdf6b2d..b3f4b9cef 100644 --- a/src/common/logging/backend.h +++ b/src/common/logging/backend.h | |||
| @@ -4,10 +4,9 @@ | |||
| 4 | #pragma once | 4 | #pragma once |
| 5 | 5 | ||
| 6 | #include <chrono> | 6 | #include <chrono> |
| 7 | #include <cstdarg> | ||
| 8 | #include <memory> | 7 | #include <memory> |
| 9 | #include <string> | 8 | #include <string> |
| 10 | #include <utility> | 9 | #include <string_view> |
| 11 | #include "common/file_util.h" | 10 | #include "common/file_util.h" |
| 12 | #include "common/logging/filter.h" | 11 | #include "common/logging/filter.h" |
| 13 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| @@ -106,9 +105,9 @@ private: | |||
| 106 | 105 | ||
| 107 | void AddBackend(std::unique_ptr<Backend> backend); | 106 | void AddBackend(std::unique_ptr<Backend> backend); |
| 108 | 107 | ||
| 109 | void RemoveBackend(const std::string& backend_name); | 108 | void RemoveBackend(std::string_view backend_name); |
| 110 | 109 | ||
| 111 | Backend* GetBackend(const std::string& backend_name); | 110 | Backend* GetBackend(std::string_view backend_name); |
| 112 | 111 | ||
| 113 | /** | 112 | /** |
| 114 | * Returns the name of the passed log class as a C-string. Subclasses are separated by periods | 113 | * Returns the name of the passed log class as a C-string. Subclasses are separated by periods |
diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 6ed087beb..2dd331152 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp | |||
| @@ -8,39 +8,9 @@ | |||
| 8 | #include "common/string_util.h" | 8 | #include "common/string_util.h" |
| 9 | 9 | ||
| 10 | namespace Log { | 10 | namespace Log { |
| 11 | 11 | namespace { | |
| 12 | Filter::Filter(Level default_level) { | ||
| 13 | ResetAll(default_level); | ||
| 14 | } | ||
| 15 | |||
| 16 | void Filter::ResetAll(Level level) { | ||
| 17 | class_levels.fill(level); | ||
| 18 | } | ||
| 19 | |||
| 20 | void Filter::SetClassLevel(Class log_class, Level level) { | ||
| 21 | class_levels[static_cast<size_t>(log_class)] = level; | ||
| 22 | } | ||
| 23 | |||
| 24 | void Filter::ParseFilterString(const std::string& filter_str) { | ||
| 25 | auto clause_begin = filter_str.cbegin(); | ||
| 26 | while (clause_begin != filter_str.cend()) { | ||
| 27 | auto clause_end = std::find(clause_begin, filter_str.cend(), ' '); | ||
| 28 | |||
| 29 | // If clause isn't empty | ||
| 30 | if (clause_end != clause_begin) { | ||
| 31 | ParseFilterRule(clause_begin, clause_end); | ||
| 32 | } | ||
| 33 | |||
| 34 | if (clause_end != filter_str.cend()) { | ||
| 35 | // Skip over the whitespace | ||
| 36 | ++clause_end; | ||
| 37 | } | ||
| 38 | clause_begin = clause_end; | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | template <typename It> | 12 | template <typename It> |
| 43 | static Level GetLevelByName(const It begin, const It end) { | 13 | Level GetLevelByName(const It begin, const It end) { |
| 44 | for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) { | 14 | for (u8 i = 0; i < static_cast<u8>(Level::Count); ++i) { |
| 45 | const char* level_name = GetLevelName(static_cast<Level>(i)); | 15 | const char* level_name = GetLevelName(static_cast<Level>(i)); |
| 46 | if (Common::ComparePartialString(begin, end, level_name)) { | 16 | if (Common::ComparePartialString(begin, end, level_name)) { |
| @@ -51,7 +21,7 @@ static Level GetLevelByName(const It begin, const It end) { | |||
| 51 | } | 21 | } |
| 52 | 22 | ||
| 53 | template <typename It> | 23 | template <typename It> |
| 54 | static Class GetClassByName(const It begin, const It end) { | 24 | Class GetClassByName(const It begin, const It end) { |
| 55 | for (ClassType i = 0; i < static_cast<ClassType>(Class::Count); ++i) { | 25 | for (ClassType i = 0; i < static_cast<ClassType>(Class::Count); ++i) { |
| 56 | const char* level_name = GetLogClassName(static_cast<Class>(i)); | 26 | const char* level_name = GetLogClassName(static_cast<Class>(i)); |
| 57 | if (Common::ComparePartialString(begin, end, level_name)) { | 27 | if (Common::ComparePartialString(begin, end, level_name)) { |
| @@ -61,8 +31,8 @@ static Class GetClassByName(const It begin, const It end) { | |||
| 61 | return Class::Count; | 31 | return Class::Count; |
| 62 | } | 32 | } |
| 63 | 33 | ||
| 64 | bool Filter::ParseFilterRule(const std::string::const_iterator begin, | 34 | template <typename Iterator> |
| 65 | const std::string::const_iterator end) { | 35 | bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { |
| 66 | auto level_separator = std::find(begin, end, ':'); | 36 | auto level_separator = std::find(begin, end, ':'); |
| 67 | if (level_separator == end) { | 37 | if (level_separator == end) { |
| 68 | LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: {}", | 38 | LOG_ERROR(Log, "Invalid log filter. Must specify a log level after `:`: {}", |
| @@ -77,7 +47,7 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin, | |||
| 77 | } | 47 | } |
| 78 | 48 | ||
| 79 | if (Common::ComparePartialString(begin, level_separator, "*")) { | 49 | if (Common::ComparePartialString(begin, level_separator, "*")) { |
| 80 | ResetAll(level); | 50 | instance.ResetAll(level); |
| 81 | return true; | 51 | return true; |
| 82 | } | 52 | } |
| 83 | 53 | ||
| @@ -87,9 +57,40 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin, | |||
| 87 | return false; | 57 | return false; |
| 88 | } | 58 | } |
| 89 | 59 | ||
| 90 | SetClassLevel(log_class, level); | 60 | instance.SetClassLevel(log_class, level); |
| 91 | return true; | 61 | return true; |
| 92 | } | 62 | } |
| 63 | } // Anonymous namespace | ||
| 64 | |||
| 65 | Filter::Filter(Level default_level) { | ||
| 66 | ResetAll(default_level); | ||
| 67 | } | ||
| 68 | |||
| 69 | void Filter::ResetAll(Level level) { | ||
| 70 | class_levels.fill(level); | ||
| 71 | } | ||
| 72 | |||
| 73 | void Filter::SetClassLevel(Class log_class, Level level) { | ||
| 74 | class_levels[static_cast<size_t>(log_class)] = level; | ||
| 75 | } | ||
| 76 | |||
| 77 | void Filter::ParseFilterString(std::string_view filter_view) { | ||
| 78 | auto clause_begin = filter_view.cbegin(); | ||
| 79 | while (clause_begin != filter_view.cend()) { | ||
| 80 | auto clause_end = std::find(clause_begin, filter_view.cend(), ' '); | ||
| 81 | |||
| 82 | // If clause isn't empty | ||
| 83 | if (clause_end != clause_begin) { | ||
| 84 | ParseFilterRule(*this, clause_begin, clause_end); | ||
| 85 | } | ||
| 86 | |||
| 87 | if (clause_end != filter_view.cend()) { | ||
| 88 | // Skip over the whitespace | ||
| 89 | ++clause_end; | ||
| 90 | } | ||
| 91 | clause_begin = clause_end; | ||
| 92 | } | ||
| 93 | } | ||
| 93 | 94 | ||
| 94 | bool Filter::CheckMessage(Class log_class, Level level) const { | 95 | bool Filter::CheckMessage(Class log_class, Level level) const { |
| 95 | return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]); | 96 | return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]); |
diff --git a/src/common/logging/filter.h b/src/common/logging/filter.h index 2a4f7c845..d5ffc5a58 100644 --- a/src/common/logging/filter.h +++ b/src/common/logging/filter.h | |||
| @@ -6,7 +6,7 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <cstddef> | 8 | #include <cstddef> |
| 9 | #include <string> | 9 | #include <string_view> |
| 10 | #include "common/logging/log.h" | 10 | #include "common/logging/log.h" |
| 11 | 11 | ||
| 12 | namespace Log { | 12 | namespace Log { |
| @@ -40,9 +40,7 @@ public: | |||
| 40 | * - `Service:Info` -- Sets the level of Service to Info. | 40 | * - `Service:Info` -- Sets the level of Service to Info. |
| 41 | * - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace. | 41 | * - `Service.FS:Trace` -- Sets the level of the Service.FS class to Trace. |
| 42 | */ | 42 | */ |
| 43 | void ParseFilterString(const std::string& filter_str); | 43 | void ParseFilterString(std::string_view filter_view); |
| 44 | bool ParseFilterRule(const std::string::const_iterator start, | ||
| 45 | const std::string::const_iterator end); | ||
| 46 | 44 | ||
| 47 | /// Matches class/level combination against the filter, returning true if it passed. | 45 | /// Matches class/level combination against the filter, returning true if it passed. |
| 48 | bool CheckMessage(Class log_class, Level level) const; | 46 | bool CheckMessage(Class log_class, Level level) const; |
diff --git a/src/common/param_package.cpp b/src/common/param_package.cpp index e0df430ab..9526ca0c6 100644 --- a/src/common/param_package.cpp +++ b/src/common/param_package.cpp | |||
| @@ -3,7 +3,9 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <array> | 5 | #include <array> |
| 6 | #include <utility> | ||
| 6 | #include <vector> | 7 | #include <vector> |
| 8 | |||
| 7 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 8 | #include "common/param_package.h" | 10 | #include "common/param_package.h" |
| 9 | #include "common/string_util.h" | 11 | #include "common/string_util.h" |
| @@ -12,10 +14,11 @@ namespace Common { | |||
| 12 | 14 | ||
| 13 | constexpr char KEY_VALUE_SEPARATOR = ':'; | 15 | constexpr char KEY_VALUE_SEPARATOR = ':'; |
| 14 | constexpr char PARAM_SEPARATOR = ','; | 16 | constexpr char PARAM_SEPARATOR = ','; |
| 17 | |||
| 15 | constexpr char ESCAPE_CHARACTER = '$'; | 18 | constexpr char ESCAPE_CHARACTER = '$'; |
| 16 | const std::string KEY_VALUE_SEPARATOR_ESCAPE{ESCAPE_CHARACTER, '0'}; | 19 | constexpr char KEY_VALUE_SEPARATOR_ESCAPE[] = "$0"; |
| 17 | const std::string PARAM_SEPARATOR_ESCAPE{ESCAPE_CHARACTER, '1'}; | 20 | constexpr char PARAM_SEPARATOR_ESCAPE[] = "$1"; |
| 18 | const std::string ESCAPE_CHARACTER_ESCAPE{ESCAPE_CHARACTER, '2'}; | 21 | constexpr char ESCAPE_CHARACTER_ESCAPE[] = "$2"; |
| 19 | 22 | ||
| 20 | ParamPackage::ParamPackage(const std::string& serialized) { | 23 | ParamPackage::ParamPackage(const std::string& serialized) { |
| 21 | std::vector<std::string> pairs; | 24 | std::vector<std::string> pairs; |
| @@ -35,7 +38,7 @@ ParamPackage::ParamPackage(const std::string& serialized) { | |||
| 35 | part = Common::ReplaceAll(part, ESCAPE_CHARACTER_ESCAPE, {ESCAPE_CHARACTER}); | 38 | part = Common::ReplaceAll(part, ESCAPE_CHARACTER_ESCAPE, {ESCAPE_CHARACTER}); |
| 36 | } | 39 | } |
| 37 | 40 | ||
| 38 | Set(key_value[0], key_value[1]); | 41 | Set(key_value[0], std::move(key_value[1])); |
| 39 | } | 42 | } |
| 40 | } | 43 | } |
| 41 | 44 | ||
| @@ -101,16 +104,16 @@ float ParamPackage::Get(const std::string& key, float default_value) const { | |||
| 101 | } | 104 | } |
| 102 | } | 105 | } |
| 103 | 106 | ||
| 104 | void ParamPackage::Set(const std::string& key, const std::string& value) { | 107 | void ParamPackage::Set(const std::string& key, std::string value) { |
| 105 | data[key] = value; | 108 | data.insert_or_assign(key, std::move(value)); |
| 106 | } | 109 | } |
| 107 | 110 | ||
| 108 | void ParamPackage::Set(const std::string& key, int value) { | 111 | void ParamPackage::Set(const std::string& key, int value) { |
| 109 | data[key] = std::to_string(value); | 112 | data.insert_or_assign(key, std::to_string(value)); |
| 110 | } | 113 | } |
| 111 | 114 | ||
| 112 | void ParamPackage::Set(const std::string& key, float value) { | 115 | void ParamPackage::Set(const std::string& key, float value) { |
| 113 | data[key] = std::to_string(value); | 116 | data.insert_or_assign(key, std::to_string(value)); |
| 114 | } | 117 | } |
| 115 | 118 | ||
| 116 | bool ParamPackage::Has(const std::string& key) const { | 119 | bool ParamPackage::Has(const std::string& key) const { |
diff --git a/src/common/param_package.h b/src/common/param_package.h index c4c11b221..7842cd4ef 100644 --- a/src/common/param_package.h +++ b/src/common/param_package.h | |||
| @@ -28,7 +28,7 @@ public: | |||
| 28 | std::string Get(const std::string& key, const std::string& default_value) const; | 28 | std::string Get(const std::string& key, const std::string& default_value) const; |
| 29 | int Get(const std::string& key, int default_value) const; | 29 | int Get(const std::string& key, int default_value) const; |
| 30 | float Get(const std::string& key, float default_value) const; | 30 | float Get(const std::string& key, float default_value) const; |
| 31 | void Set(const std::string& key, const std::string& value); | 31 | void Set(const std::string& key, std::string value); |
| 32 | void Set(const std::string& key, int value); | 32 | void Set(const std::string& key, int value); |
| 33 | void Set(const std::string& key, float value); | 33 | void Set(const std::string& key, float value); |
| 34 | bool Has(const std::string& key) const; | 34 | bool Has(const std::string& key) const; |
diff --git a/src/core/file_sys/partition_filesystem.cpp b/src/core/file_sys/partition_filesystem.cpp index d4097a510..7ccca1089 100644 --- a/src/core/file_sys/partition_filesystem.cpp +++ b/src/core/file_sys/partition_filesystem.cpp | |||
| @@ -76,7 +76,7 @@ std::vector<std::shared_ptr<VfsFile>> PartitionFilesystem::GetFiles() const { | |||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | std::vector<std::shared_ptr<VfsDirectory>> PartitionFilesystem::GetSubdirectories() const { | 78 | std::vector<std::shared_ptr<VfsDirectory>> PartitionFilesystem::GetSubdirectories() const { |
| 79 | return {}; | 79 | return pfs_dirs; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | std::string PartitionFilesystem::GetName() const { | 82 | std::string PartitionFilesystem::GetName() const { |
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp index 16c8ad90b..3f690f12a 100644 --- a/src/core/file_sys/vfs.cpp +++ b/src/core/file_sys/vfs.cpp | |||
| @@ -42,7 +42,7 @@ bool VfsFile::WriteByte(u8 data, size_t offset) { | |||
| 42 | return Write(&data, 1, offset) == 1; | 42 | return Write(&data, 1, offset) == 1; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | size_t VfsFile::WriteBytes(std::vector<u8> data, size_t offset) { | 45 | size_t VfsFile::WriteBytes(const std::vector<u8>& data, size_t offset) { |
| 46 | return Write(data.data(), data.size(), offset); | 46 | return Write(data.data(), data.size(), offset); |
| 47 | } | 47 | } |
| 48 | 48 | ||
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h index a5213e0cc..db3c77eac 100644 --- a/src/core/file_sys/vfs.h +++ b/src/core/file_sys/vfs.h | |||
| @@ -59,8 +59,7 @@ struct VfsFile : NonCopyable { | |||
| 59 | // Returns the number of bytes (sizeof(T)*number_elements) read successfully. | 59 | // Returns the number of bytes (sizeof(T)*number_elements) read successfully. |
| 60 | template <typename T> | 60 | template <typename T> |
| 61 | size_t ReadArray(T* data, size_t number_elements, size_t offset = 0) const { | 61 | size_t ReadArray(T* data, size_t number_elements, size_t offset = 0) const { |
| 62 | static_assert(std::is_trivially_copyable<T>::value, | 62 | static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); |
| 63 | "Data type must be trivially copyable."); | ||
| 64 | 63 | ||
| 65 | return Read(reinterpret_cast<u8*>(data), number_elements * sizeof(T), offset); | 64 | return Read(reinterpret_cast<u8*>(data), number_elements * sizeof(T), offset); |
| 66 | } | 65 | } |
| @@ -69,8 +68,7 @@ struct VfsFile : NonCopyable { | |||
| 69 | // Returns the number of bytes read successfully. | 68 | // Returns the number of bytes read successfully. |
| 70 | template <typename T> | 69 | template <typename T> |
| 71 | size_t ReadBytes(T* data, size_t size, size_t offset = 0) const { | 70 | size_t ReadBytes(T* data, size_t size, size_t offset = 0) const { |
| 72 | static_assert(std::is_trivially_copyable<T>::value, | 71 | static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); |
| 73 | "Data type must be trivially copyable."); | ||
| 74 | return Read(reinterpret_cast<u8*>(data), size, offset); | 72 | return Read(reinterpret_cast<u8*>(data), size, offset); |
| 75 | } | 73 | } |
| 76 | 74 | ||
| @@ -78,8 +76,7 @@ struct VfsFile : NonCopyable { | |||
| 78 | // Returns the number of bytes read successfully (sizeof(T)). | 76 | // Returns the number of bytes read successfully (sizeof(T)). |
| 79 | template <typename T> | 77 | template <typename T> |
| 80 | size_t ReadObject(T* data, size_t offset = 0) const { | 78 | size_t ReadObject(T* data, size_t offset = 0) const { |
| 81 | static_assert(std::is_trivially_copyable<T>::value, | 79 | static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); |
| 82 | "Data type must be trivially copyable."); | ||
| 83 | return Read(reinterpret_cast<u8*>(data), sizeof(T), offset); | 80 | return Read(reinterpret_cast<u8*>(data), sizeof(T), offset); |
| 84 | } | 81 | } |
| 85 | 82 | ||
| @@ -88,33 +85,29 @@ struct VfsFile : NonCopyable { | |||
| 88 | virtual bool WriteByte(u8 data, size_t offset = 0); | 85 | virtual bool WriteByte(u8 data, size_t offset = 0); |
| 89 | // Writes a vector of bytes to offset in file and returns the number of bytes successfully | 86 | // Writes a vector of bytes to offset in file and returns the number of bytes successfully |
| 90 | // written. | 87 | // written. |
| 91 | virtual size_t WriteBytes(std::vector<u8> data, size_t offset = 0); | 88 | virtual size_t WriteBytes(const std::vector<u8>& data, size_t offset = 0); |
| 92 | 89 | ||
| 93 | // Writes an array of type T, size number_elements to offset in file. | 90 | // Writes an array of type T, size number_elements to offset in file. |
| 94 | // Returns the number of bytes (sizeof(T)*number_elements) written successfully. | 91 | // Returns the number of bytes (sizeof(T)*number_elements) written successfully. |
| 95 | template <typename T> | 92 | template <typename T> |
| 96 | size_t WriteArray(T* data, size_t number_elements, size_t offset = 0) { | 93 | size_t WriteArray(const T* data, size_t number_elements, size_t offset = 0) { |
| 97 | static_assert(std::is_trivially_copyable<T>::value, | 94 | static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); |
| 98 | "Data type must be trivially copyable."); | ||
| 99 | |||
| 100 | return Write(data, number_elements * sizeof(T), offset); | 95 | return Write(data, number_elements * sizeof(T), offset); |
| 101 | } | 96 | } |
| 102 | 97 | ||
| 103 | // Writes size bytes starting at memory location data to offset in file. | 98 | // Writes size bytes starting at memory location data to offset in file. |
| 104 | // Returns the number of bytes written successfully. | 99 | // Returns the number of bytes written successfully. |
| 105 | template <typename T> | 100 | template <typename T> |
| 106 | size_t WriteBytes(T* data, size_t size, size_t offset = 0) { | 101 | size_t WriteBytes(const T* data, size_t size, size_t offset = 0) { |
| 107 | static_assert(std::is_trivially_copyable<T>::value, | 102 | static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); |
| 108 | "Data type must be trivially copyable."); | 103 | return Write(reinterpret_cast<const u8*>(data), size, offset); |
| 109 | return Write(reinterpret_cast<u8*>(data), size, offset); | ||
| 110 | } | 104 | } |
| 111 | 105 | ||
| 112 | // Writes one object of type T to offset in file. | 106 | // Writes one object of type T to offset in file. |
| 113 | // Returns the number of bytes written successfully (sizeof(T)). | 107 | // Returns the number of bytes written successfully (sizeof(T)). |
| 114 | template <typename T> | 108 | template <typename T> |
| 115 | size_t WriteObject(const T& data, size_t offset = 0) { | 109 | size_t WriteObject(const T& data, size_t offset = 0) { |
| 116 | static_assert(std::is_trivially_copyable<T>::value, | 110 | static_assert(std::is_trivially_copyable_v<T>, "Data type must be trivially copyable."); |
| 117 | "Data type must be trivially copyable."); | ||
| 118 | return Write(&data, sizeof(T), offset); | 111 | return Write(&data, sizeof(T), offset); |
| 119 | } | 112 | } |
| 120 | 113 | ||
diff --git a/src/core/file_sys/vfs_offset.cpp b/src/core/file_sys/vfs_offset.cpp index 288499cb5..217e02235 100644 --- a/src/core/file_sys/vfs_offset.cpp +++ b/src/core/file_sys/vfs_offset.cpp | |||
| @@ -2,13 +2,16 @@ | |||
| 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 | #include <algorithm> | ||
| 6 | #include <utility> | ||
| 7 | |||
| 5 | #include "core/file_sys/vfs_offset.h" | 8 | #include "core/file_sys/vfs_offset.h" |
| 6 | 9 | ||
| 7 | namespace FileSys { | 10 | namespace FileSys { |
| 8 | 11 | ||
| 9 | OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, size_t size_, size_t offset_, | 12 | OffsetVfsFile::OffsetVfsFile(std::shared_ptr<VfsFile> file_, size_t size_, size_t offset_, |
| 10 | const std::string& name_) | 13 | std::string name_) |
| 11 | : file(file_), offset(offset_), size(size_), name(name_) {} | 14 | : file(std::move(file_)), offset(offset_), size(size_), name(std::move(name_)) {} |
| 12 | 15 | ||
| 13 | std::string OffsetVfsFile::GetName() const { | 16 | std::string OffsetVfsFile::GetName() const { |
| 14 | return name.empty() ? file->GetName() : name; | 17 | return name.empty() ? file->GetName() : name; |
| @@ -73,7 +76,7 @@ bool OffsetVfsFile::WriteByte(u8 data, size_t r_offset) { | |||
| 73 | return false; | 76 | return false; |
| 74 | } | 77 | } |
| 75 | 78 | ||
| 76 | size_t OffsetVfsFile::WriteBytes(std::vector<u8> data, size_t r_offset) { | 79 | size_t OffsetVfsFile::WriteBytes(const std::vector<u8>& data, size_t r_offset) { |
| 77 | return file->Write(data.data(), TrimToFit(data.size(), r_offset), offset + r_offset); | 80 | return file->Write(data.data(), TrimToFit(data.size(), r_offset), offset + r_offset); |
| 78 | } | 81 | } |
| 79 | 82 | ||
| @@ -86,7 +89,7 @@ size_t OffsetVfsFile::GetOffset() const { | |||
| 86 | } | 89 | } |
| 87 | 90 | ||
| 88 | size_t OffsetVfsFile::TrimToFit(size_t r_size, size_t r_offset) const { | 91 | size_t OffsetVfsFile::TrimToFit(size_t r_size, size_t r_offset) const { |
| 89 | return std::max<size_t>(std::min<size_t>(size - r_offset, r_size), 0); | 92 | return std::clamp(r_size, size_t{0}, size - r_offset); |
| 90 | } | 93 | } |
| 91 | 94 | ||
| 92 | } // namespace FileSys | 95 | } // namespace FileSys |
diff --git a/src/core/file_sys/vfs_offset.h b/src/core/file_sys/vfs_offset.h index adc615b38..ded4827f5 100644 --- a/src/core/file_sys/vfs_offset.h +++ b/src/core/file_sys/vfs_offset.h | |||
| @@ -14,7 +14,7 @@ namespace FileSys { | |||
| 14 | // the size of this wrapper. | 14 | // the size of this wrapper. |
| 15 | struct OffsetVfsFile : public VfsFile { | 15 | struct OffsetVfsFile : public VfsFile { |
| 16 | OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0, | 16 | OffsetVfsFile(std::shared_ptr<VfsFile> file, size_t size, size_t offset = 0, |
| 17 | const std::string& new_name = ""); | 17 | std::string new_name = ""); |
| 18 | 18 | ||
| 19 | std::string GetName() const override; | 19 | std::string GetName() const override; |
| 20 | size_t GetSize() const override; | 20 | size_t GetSize() const override; |
| @@ -28,7 +28,7 @@ struct OffsetVfsFile : public VfsFile { | |||
| 28 | std::vector<u8> ReadBytes(size_t size, size_t offset) const override; | 28 | std::vector<u8> ReadBytes(size_t size, size_t offset) const override; |
| 29 | std::vector<u8> ReadAllBytes() const override; | 29 | std::vector<u8> ReadAllBytes() const override; |
| 30 | bool WriteByte(u8 data, size_t offset) override; | 30 | bool WriteByte(u8 data, size_t offset) override; |
| 31 | size_t WriteBytes(std::vector<u8> data, size_t offset) override; | 31 | size_t WriteBytes(const std::vector<u8>& data, size_t offset) override; |
| 32 | 32 | ||
| 33 | bool Rename(const std::string& name) override; | 33 | bool Rename(const std::string& name) override; |
| 34 | 34 | ||
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 24605a273..8b5b06f31 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h | |||
| @@ -175,6 +175,25 @@ public: | |||
| 175 | void Push(const First& first_value, const Other&... other_values); | 175 | void Push(const First& first_value, const Other&... other_values); |
| 176 | 176 | ||
| 177 | /** | 177 | /** |
| 178 | * Helper function for pushing strongly-typed enumeration values. | ||
| 179 | * | ||
| 180 | * @tparam Enum The enumeration type to be pushed | ||
| 181 | * | ||
| 182 | * @param value The value to push. | ||
| 183 | * | ||
| 184 | * @note The underlying size of the enumeration type is the size of the | ||
| 185 | * data that gets pushed. e.g. "enum class SomeEnum : u16" will | ||
| 186 | * push a u16-sized amount of data. | ||
| 187 | */ | ||
| 188 | template <typename Enum> | ||
| 189 | void PushEnum(Enum value) { | ||
| 190 | static_assert(std::is_enum_v<Enum>, "T must be an enum type within a PushEnum call."); | ||
| 191 | static_assert(!std::is_convertible_v<Enum, int>, | ||
| 192 | "enum type in PushEnum must be a strongly typed enum."); | ||
| 193 | Push(static_cast<std::underlying_type_t<Enum>>(value)); | ||
| 194 | } | ||
| 195 | |||
| 196 | /** | ||
| 178 | * @brief Copies the content of the given trivially copyable class to the buffer as a normal | 197 | * @brief Copies the content of the given trivially copyable class to the buffer as a normal |
| 179 | * param | 198 | * param |
| 180 | * @note: The input class must be correctly packed/padded to fit hardware layout. | 199 | * @note: The input class must be correctly packed/padded to fit hardware layout. |
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index dcc68aabf..233fdab25 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -20,7 +20,7 @@ namespace AddressArbiter { | |||
| 20 | static ResultCode WaitForAddress(VAddr address, s64 timeout) { | 20 | static ResultCode WaitForAddress(VAddr address, s64 timeout) { |
| 21 | SharedPtr<Thread> current_thread = GetCurrentThread(); | 21 | SharedPtr<Thread> current_thread = GetCurrentThread(); |
| 22 | current_thread->arb_wait_address = address; | 22 | current_thread->arb_wait_address = address; |
| 23 | current_thread->status = THREADSTATUS_WAIT_ARB; | 23 | current_thread->status = ThreadStatus::WaitArb; |
| 24 | current_thread->wakeup_callback = nullptr; | 24 | current_thread->wakeup_callback = nullptr; |
| 25 | 25 | ||
| 26 | current_thread->WakeAfterDelay(timeout); | 26 | current_thread->WakeAfterDelay(timeout); |
| @@ -65,7 +65,7 @@ static void WakeThreads(std::vector<SharedPtr<Thread>>& waiting_threads, s32 num | |||
| 65 | 65 | ||
| 66 | // Signal the waiting threads. | 66 | // Signal the waiting threads. |
| 67 | for (size_t i = 0; i < last; i++) { | 67 | for (size_t i = 0; i < last; i++) { |
| 68 | ASSERT(waiting_threads[i]->status == THREADSTATUS_WAIT_ARB); | 68 | ASSERT(waiting_threads[i]->status == ThreadStatus::WaitArb); |
| 69 | waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); | 69 | waiting_threads[i]->SetWaitSynchronizationResult(RESULT_SUCCESS); |
| 70 | waiting_threads[i]->arb_wait_address = 0; | 70 | waiting_threads[i]->arb_wait_address = 0; |
| 71 | waiting_threads[i]->ResumeFromWait(); | 71 | waiting_threads[i]->ResumeFromWait(); |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 8f40bdd5a..f24392520 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -38,7 +38,7 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, | |||
| 38 | thread->wakeup_callback = | 38 | thread->wakeup_callback = |
| 39 | [context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread, | 39 | [context = *this, callback](ThreadWakeupReason reason, SharedPtr<Thread> thread, |
| 40 | SharedPtr<WaitObject> object, size_t index) mutable -> bool { | 40 | SharedPtr<WaitObject> object, size_t index) mutable -> bool { |
| 41 | ASSERT(thread->status == THREADSTATUS_WAIT_HLE_EVENT); | 41 | ASSERT(thread->status == ThreadStatus::WaitHLEEvent); |
| 42 | callback(thread, context, reason); | 42 | callback(thread, context, reason); |
| 43 | context.WriteToOutgoingCommandBuffer(*thread); | 43 | context.WriteToOutgoingCommandBuffer(*thread); |
| 44 | return true; | 44 | return true; |
| @@ -50,7 +50,7 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | event->Clear(); | 52 | event->Clear(); |
| 53 | thread->status = THREADSTATUS_WAIT_HLE_EVENT; | 53 | thread->status = ThreadStatus::WaitHLEEvent; |
| 54 | thread->wait_objects = {event}; | 54 | thread->wait_objects = {event}; |
| 55 | event->AddWaitingThread(thread); | 55 | event->AddWaitingThread(thread); |
| 56 | 56 | ||
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 65560226d..3f1de3258 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -28,7 +28,7 @@ static std::pair<SharedPtr<Thread>, u32> GetHighestPriorityMutexWaitingThread( | |||
| 28 | if (thread->mutex_wait_address != mutex_addr) | 28 | if (thread->mutex_wait_address != mutex_addr) |
| 29 | continue; | 29 | continue; |
| 30 | 30 | ||
| 31 | ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); | 31 | ASSERT(thread->status == ThreadStatus::WaitMutex); |
| 32 | 32 | ||
| 33 | ++num_waiters; | 33 | ++num_waiters; |
| 34 | if (highest_priority_thread == nullptr || | 34 | if (highest_priority_thread == nullptr || |
| @@ -83,7 +83,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, | |||
| 83 | GetCurrentThread()->mutex_wait_address = address; | 83 | GetCurrentThread()->mutex_wait_address = address; |
| 84 | GetCurrentThread()->wait_handle = requesting_thread_handle; | 84 | GetCurrentThread()->wait_handle = requesting_thread_handle; |
| 85 | 85 | ||
| 86 | GetCurrentThread()->status = THREADSTATUS_WAIT_MUTEX; | 86 | GetCurrentThread()->status = ThreadStatus::WaitMutex; |
| 87 | GetCurrentThread()->wakeup_callback = nullptr; | 87 | GetCurrentThread()->wakeup_callback = nullptr; |
| 88 | 88 | ||
| 89 | // Update the lock holder thread's priority to prevent priority inversion. | 89 | // Update the lock holder thread's priority to prevent priority inversion. |
| @@ -121,7 +121,7 @@ ResultCode Mutex::Release(VAddr address) { | |||
| 121 | // Grant the mutex to the next waiting thread and resume it. | 121 | // Grant the mutex to the next waiting thread and resume it. |
| 122 | Memory::Write32(address, mutex_value); | 122 | Memory::Write32(address, mutex_value); |
| 123 | 123 | ||
| 124 | ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); | 124 | ASSERT(thread->status == ThreadStatus::WaitMutex); |
| 125 | thread->ResumeFromWait(); | 125 | thread->ResumeFromWait(); |
| 126 | 126 | ||
| 127 | thread->lock_owner = nullptr; | 127 | thread->lock_owner = nullptr; |
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 82829f6bb..e307eec98 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -34,7 +34,7 @@ Thread* Scheduler::PopNextReadyThread() { | |||
| 34 | Thread* next = nullptr; | 34 | Thread* next = nullptr; |
| 35 | Thread* thread = GetCurrentThread(); | 35 | Thread* thread = GetCurrentThread(); |
| 36 | 36 | ||
| 37 | if (thread && thread->status == THREADSTATUS_RUNNING) { | 37 | if (thread && thread->status == ThreadStatus::Running) { |
| 38 | // We have to do better than the current thread. | 38 | // We have to do better than the current thread. |
| 39 | // This call returns null when that's not possible. | 39 | // This call returns null when that's not possible. |
| 40 | next = ready_queue.pop_first_better(thread->current_priority); | 40 | next = ready_queue.pop_first_better(thread->current_priority); |
| @@ -59,17 +59,17 @@ void Scheduler::SwitchContext(Thread* new_thread) { | |||
| 59 | // Save the TPIDR_EL0 system register in case it was modified. | 59 | // Save the TPIDR_EL0 system register in case it was modified. |
| 60 | previous_thread->tpidr_el0 = cpu_core->GetTPIDR_EL0(); | 60 | previous_thread->tpidr_el0 = cpu_core->GetTPIDR_EL0(); |
| 61 | 61 | ||
| 62 | if (previous_thread->status == THREADSTATUS_RUNNING) { | 62 | if (previous_thread->status == ThreadStatus::Running) { |
| 63 | // This is only the case when a reschedule is triggered without the current thread | 63 | // This is only the case when a reschedule is triggered without the current thread |
| 64 | // yielding execution (i.e. an event triggered, system core time-sliced, etc) | 64 | // yielding execution (i.e. an event triggered, system core time-sliced, etc) |
| 65 | ready_queue.push_front(previous_thread->current_priority, previous_thread); | 65 | ready_queue.push_front(previous_thread->current_priority, previous_thread); |
| 66 | previous_thread->status = THREADSTATUS_READY; | 66 | previous_thread->status = ThreadStatus::Ready; |
| 67 | } | 67 | } |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | // Load context of new thread | 70 | // Load context of new thread |
| 71 | if (new_thread) { | 71 | if (new_thread) { |
| 72 | ASSERT_MSG(new_thread->status == THREADSTATUS_READY, | 72 | ASSERT_MSG(new_thread->status == ThreadStatus::Ready, |
| 73 | "Thread must be ready to become running."); | 73 | "Thread must be ready to become running."); |
| 74 | 74 | ||
| 75 | // Cancel any outstanding wakeup events for this thread | 75 | // Cancel any outstanding wakeup events for this thread |
| @@ -80,7 +80,7 @@ void Scheduler::SwitchContext(Thread* new_thread) { | |||
| 80 | current_thread = new_thread; | 80 | current_thread = new_thread; |
| 81 | 81 | ||
| 82 | ready_queue.remove(new_thread->current_priority, new_thread); | 82 | ready_queue.remove(new_thread->current_priority, new_thread); |
| 83 | new_thread->status = THREADSTATUS_RUNNING; | 83 | new_thread->status = ThreadStatus::Running; |
| 84 | 84 | ||
| 85 | if (previous_process != current_thread->owner_process) { | 85 | if (previous_process != current_thread->owner_process) { |
| 86 | Core::CurrentProcess() = current_thread->owner_process; | 86 | Core::CurrentProcess() = current_thread->owner_process; |
| @@ -132,14 +132,14 @@ void Scheduler::RemoveThread(Thread* thread) { | |||
| 132 | void Scheduler::ScheduleThread(Thread* thread, u32 priority) { | 132 | void Scheduler::ScheduleThread(Thread* thread, u32 priority) { |
| 133 | std::lock_guard<std::mutex> lock(scheduler_mutex); | 133 | std::lock_guard<std::mutex> lock(scheduler_mutex); |
| 134 | 134 | ||
| 135 | ASSERT(thread->status == THREADSTATUS_READY); | 135 | ASSERT(thread->status == ThreadStatus::Ready); |
| 136 | ready_queue.push_back(priority, thread); | 136 | ready_queue.push_back(priority, thread); |
| 137 | } | 137 | } |
| 138 | 138 | ||
| 139 | void Scheduler::UnscheduleThread(Thread* thread, u32 priority) { | 139 | void Scheduler::UnscheduleThread(Thread* thread, u32 priority) { |
| 140 | std::lock_guard<std::mutex> lock(scheduler_mutex); | 140 | std::lock_guard<std::mutex> lock(scheduler_mutex); |
| 141 | 141 | ||
| 142 | ASSERT(thread->status == THREADSTATUS_READY); | 142 | ASSERT(thread->status == ThreadStatus::Ready); |
| 143 | ready_queue.remove(priority, thread); | 143 | ready_queue.remove(priority, thread); |
| 144 | } | 144 | } |
| 145 | 145 | ||
| @@ -147,7 +147,7 @@ void Scheduler::SetThreadPriority(Thread* thread, u32 priority) { | |||
| 147 | std::lock_guard<std::mutex> lock(scheduler_mutex); | 147 | std::lock_guard<std::mutex> lock(scheduler_mutex); |
| 148 | 148 | ||
| 149 | // If thread was ready, adjust queues | 149 | // If thread was ready, adjust queues |
| 150 | if (thread->status == THREADSTATUS_READY) | 150 | if (thread->status == ThreadStatus::Ready) |
| 151 | ready_queue.move(thread, thread->current_priority, priority); | 151 | ready_queue.move(thread, thread->current_priority, priority); |
| 152 | else | 152 | else |
| 153 | ready_queue.prepare(priority); | 153 | ready_queue.prepare(priority); |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 19d17af4f..29b163528 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -110,10 +110,10 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) { | |||
| 110 | result = hle_handler->HandleSyncRequest(context); | 110 | result = hle_handler->HandleSyncRequest(context); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | if (thread->status == THREADSTATUS_RUNNING) { | 113 | if (thread->status == ThreadStatus::Running) { |
| 114 | // Put the thread to sleep until the server replies, it will be awoken in | 114 | // Put the thread to sleep until the server replies, it will be awoken in |
| 115 | // svcReplyAndReceive for LLE servers. | 115 | // svcReplyAndReceive for LLE servers. |
| 116 | thread->status = THREADSTATUS_WAIT_IPC; | 116 | thread->status = ThreadStatus::WaitIPC; |
| 117 | 117 | ||
| 118 | if (hle_handler != nullptr) { | 118 | if (hle_handler != nullptr) { |
| 119 | // For HLE services, we put the request threads to sleep for a short duration to | 119 | // For HLE services, we put the request threads to sleep for a short duration to |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index c6b0bb442..6b2995fe2 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -133,7 +133,7 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { | |||
| 133 | /// Default thread wakeup callback for WaitSynchronization | 133 | /// Default thread wakeup callback for WaitSynchronization |
| 134 | static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, | 134 | static bool DefaultThreadWakeupCallback(ThreadWakeupReason reason, SharedPtr<Thread> thread, |
| 135 | SharedPtr<WaitObject> object, size_t index) { | 135 | SharedPtr<WaitObject> object, size_t index) { |
| 136 | ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); | 136 | ASSERT(thread->status == ThreadStatus::WaitSynchAny); |
| 137 | 137 | ||
| 138 | if (reason == ThreadWakeupReason::Timeout) { | 138 | if (reason == ThreadWakeupReason::Timeout) { |
| 139 | thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); | 139 | thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); |
| @@ -197,7 +197,7 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64 | |||
| 197 | object->AddWaitingThread(thread); | 197 | object->AddWaitingThread(thread); |
| 198 | 198 | ||
| 199 | thread->wait_objects = std::move(objects); | 199 | thread->wait_objects = std::move(objects); |
| 200 | thread->status = THREADSTATUS_WAIT_SYNCH_ANY; | 200 | thread->status = ThreadStatus::WaitSynchAny; |
| 201 | 201 | ||
| 202 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 202 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 203 | thread->WakeAfterDelay(nano_seconds); | 203 | thread->WakeAfterDelay(nano_seconds); |
| @@ -217,7 +217,7 @@ static ResultCode CancelSynchronization(Handle thread_handle) { | |||
| 217 | return ERR_INVALID_HANDLE; | 217 | return ERR_INVALID_HANDLE; |
| 218 | } | 218 | } |
| 219 | 219 | ||
| 220 | ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); | 220 | ASSERT(thread->status == ThreadStatus::WaitSynchAny); |
| 221 | thread->SetWaitSynchronizationResult( | 221 | thread->SetWaitSynchronizationResult( |
| 222 | ResultCode(ErrorModule::Kernel, ErrCodes::SynchronizationCanceled)); | 222 | ResultCode(ErrorModule::Kernel, ErrCodes::SynchronizationCanceled)); |
| 223 | thread->ResumeFromWait(); | 223 | thread->ResumeFromWait(); |
| @@ -468,8 +468,8 @@ static void ExitProcess() { | |||
| 468 | continue; | 468 | continue; |
| 469 | 469 | ||
| 470 | // TODO(Subv): When are the other running/ready threads terminated? | 470 | // TODO(Subv): When are the other running/ready threads terminated? |
| 471 | ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY || | 471 | ASSERT_MSG(thread->status == ThreadStatus::WaitSynchAny || |
| 472 | thread->status == THREADSTATUS_WAIT_SYNCH_ALL, | 472 | thread->status == ThreadStatus::WaitSynchAll, |
| 473 | "Exiting processes with non-waiting threads is currently unimplemented"); | 473 | "Exiting processes with non-waiting threads is currently unimplemented"); |
| 474 | 474 | ||
| 475 | thread->Stop(); | 475 | thread->Stop(); |
| @@ -545,7 +545,7 @@ static ResultCode StartThread(Handle thread_handle) { | |||
| 545 | return ERR_INVALID_HANDLE; | 545 | return ERR_INVALID_HANDLE; |
| 546 | } | 546 | } |
| 547 | 547 | ||
| 548 | ASSERT(thread->status == THREADSTATUS_DORMANT); | 548 | ASSERT(thread->status == ThreadStatus::Dormant); |
| 549 | 549 | ||
| 550 | thread->ResumeFromWait(); | 550 | thread->ResumeFromWait(); |
| 551 | Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule(); | 551 | Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule(); |
| @@ -596,7 +596,7 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var | |||
| 596 | current_thread->condvar_wait_address = condition_variable_addr; | 596 | current_thread->condvar_wait_address = condition_variable_addr; |
| 597 | current_thread->mutex_wait_address = mutex_addr; | 597 | current_thread->mutex_wait_address = mutex_addr; |
| 598 | current_thread->wait_handle = thread_handle; | 598 | current_thread->wait_handle = thread_handle; |
| 599 | current_thread->status = THREADSTATUS_WAIT_MUTEX; | 599 | current_thread->status = ThreadStatus::WaitMutex; |
| 600 | current_thread->wakeup_callback = nullptr; | 600 | current_thread->wakeup_callback = nullptr; |
| 601 | 601 | ||
| 602 | current_thread->WakeAfterDelay(nano_seconds); | 602 | current_thread->WakeAfterDelay(nano_seconds); |
| @@ -656,7 +656,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target | |||
| 656 | if (mutex_val == 0) { | 656 | if (mutex_val == 0) { |
| 657 | // We were able to acquire the mutex, resume this thread. | 657 | // We were able to acquire the mutex, resume this thread. |
| 658 | Memory::Write32(thread->mutex_wait_address, thread->wait_handle); | 658 | Memory::Write32(thread->mutex_wait_address, thread->wait_handle); |
| 659 | ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); | 659 | ASSERT(thread->status == ThreadStatus::WaitMutex); |
| 660 | thread->ResumeFromWait(); | 660 | thread->ResumeFromWait(); |
| 661 | 661 | ||
| 662 | auto lock_owner = thread->lock_owner; | 662 | auto lock_owner = thread->lock_owner; |
| @@ -672,8 +672,8 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target | |||
| 672 | Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); | 672 | Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); |
| 673 | auto owner = g_handle_table.Get<Thread>(owner_handle); | 673 | auto owner = g_handle_table.Get<Thread>(owner_handle); |
| 674 | ASSERT(owner); | 674 | ASSERT(owner); |
| 675 | ASSERT(thread->status != THREADSTATUS_RUNNING); | 675 | ASSERT(thread->status != ThreadStatus::Running); |
| 676 | thread->status = THREADSTATUS_WAIT_MUTEX; | 676 | thread->status = ThreadStatus::WaitMutex; |
| 677 | thread->wakeup_callback = nullptr; | 677 | thread->wakeup_callback = nullptr; |
| 678 | 678 | ||
| 679 | // Signal that the mutex now has a waiting thread. | 679 | // Signal that the mutex now has a waiting thread. |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 7f1e18831..cd85c4b7c 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -30,7 +30,7 @@ namespace Kernel { | |||
| 30 | static CoreTiming::EventType* ThreadWakeupEventType = nullptr; | 30 | static CoreTiming::EventType* ThreadWakeupEventType = nullptr; |
| 31 | 31 | ||
| 32 | bool Thread::ShouldWait(Thread* thread) const { | 32 | bool Thread::ShouldWait(Thread* thread) const { |
| 33 | return status != THREADSTATUS_DEAD; | 33 | return status != ThreadStatus::Dead; |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void Thread::Acquire(Thread* thread) { | 36 | void Thread::Acquire(Thread* thread) { |
| @@ -63,11 +63,11 @@ void Thread::Stop() { | |||
| 63 | 63 | ||
| 64 | // Clean up thread from ready queue | 64 | // Clean up thread from ready queue |
| 65 | // This is only needed when the thread is termintated forcefully (SVC TerminateProcess) | 65 | // This is only needed when the thread is termintated forcefully (SVC TerminateProcess) |
| 66 | if (status == THREADSTATUS_READY) { | 66 | if (status == ThreadStatus::Ready) { |
| 67 | scheduler->UnscheduleThread(this, current_priority); | 67 | scheduler->UnscheduleThread(this, current_priority); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | status = THREADSTATUS_DEAD; | 70 | status = ThreadStatus::Dead; |
| 71 | 71 | ||
| 72 | WakeupAllWaitingThreads(); | 72 | WakeupAllWaitingThreads(); |
| 73 | 73 | ||
| @@ -86,7 +86,7 @@ void Thread::Stop() { | |||
| 86 | 86 | ||
| 87 | void WaitCurrentThread_Sleep() { | 87 | void WaitCurrentThread_Sleep() { |
| 88 | Thread* thread = GetCurrentThread(); | 88 | Thread* thread = GetCurrentThread(); |
| 89 | thread->status = THREADSTATUS_WAIT_SLEEP; | 89 | thread->status = ThreadStatus::WaitSleep; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | void ExitCurrentThread() { | 92 | void ExitCurrentThread() { |
| @@ -110,10 +110,9 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | |||
| 110 | 110 | ||
| 111 | bool resume = true; | 111 | bool resume = true; |
| 112 | 112 | ||
| 113 | if (thread->status == THREADSTATUS_WAIT_SYNCH_ANY || | 113 | if (thread->status == ThreadStatus::WaitSynchAny || |
| 114 | thread->status == THREADSTATUS_WAIT_SYNCH_ALL || | 114 | thread->status == ThreadStatus::WaitSynchAll || |
| 115 | thread->status == THREADSTATUS_WAIT_HLE_EVENT) { | 115 | thread->status == ThreadStatus::WaitHLEEvent) { |
| 116 | |||
| 117 | // Remove the thread from each of its waiting objects' waitlists | 116 | // Remove the thread from each of its waiting objects' waitlists |
| 118 | for (auto& object : thread->wait_objects) | 117 | for (auto& object : thread->wait_objects) |
| 119 | object->RemoveWaitingThread(thread.get()); | 118 | object->RemoveWaitingThread(thread.get()); |
| @@ -126,7 +125,7 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | |||
| 126 | 125 | ||
| 127 | if (thread->mutex_wait_address != 0 || thread->condvar_wait_address != 0 || | 126 | if (thread->mutex_wait_address != 0 || thread->condvar_wait_address != 0 || |
| 128 | thread->wait_handle) { | 127 | thread->wait_handle) { |
| 129 | ASSERT(thread->status == THREADSTATUS_WAIT_MUTEX); | 128 | ASSERT(thread->status == ThreadStatus::WaitMutex); |
| 130 | thread->mutex_wait_address = 0; | 129 | thread->mutex_wait_address = 0; |
| 131 | thread->condvar_wait_address = 0; | 130 | thread->condvar_wait_address = 0; |
| 132 | thread->wait_handle = 0; | 131 | thread->wait_handle = 0; |
| @@ -141,7 +140,7 @@ static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { | |||
| 141 | } | 140 | } |
| 142 | 141 | ||
| 143 | if (thread->arb_wait_address != 0) { | 142 | if (thread->arb_wait_address != 0) { |
| 144 | ASSERT(thread->status == THREADSTATUS_WAIT_ARB); | 143 | ASSERT(thread->status == ThreadStatus::WaitArb); |
| 145 | thread->arb_wait_address = 0; | 144 | thread->arb_wait_address = 0; |
| 146 | } | 145 | } |
| 147 | 146 | ||
| @@ -178,28 +177,28 @@ void Thread::ResumeFromWait() { | |||
| 178 | ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); | 177 | ASSERT_MSG(wait_objects.empty(), "Thread is waking up while waiting for objects"); |
| 179 | 178 | ||
| 180 | switch (status) { | 179 | switch (status) { |
| 181 | case THREADSTATUS_WAIT_SYNCH_ALL: | 180 | case ThreadStatus::WaitSynchAll: |
| 182 | case THREADSTATUS_WAIT_SYNCH_ANY: | 181 | case ThreadStatus::WaitSynchAny: |
| 183 | case THREADSTATUS_WAIT_HLE_EVENT: | 182 | case ThreadStatus::WaitHLEEvent: |
| 184 | case THREADSTATUS_WAIT_SLEEP: | 183 | case ThreadStatus::WaitSleep: |
| 185 | case THREADSTATUS_WAIT_IPC: | 184 | case ThreadStatus::WaitIPC: |
| 186 | case THREADSTATUS_WAIT_MUTEX: | 185 | case ThreadStatus::WaitMutex: |
| 187 | case THREADSTATUS_WAIT_ARB: | 186 | case ThreadStatus::WaitArb: |
| 188 | break; | 187 | break; |
| 189 | 188 | ||
| 190 | case THREADSTATUS_READY: | 189 | case ThreadStatus::Ready: |
| 191 | // The thread's wakeup callback must have already been cleared when the thread was first | 190 | // The thread's wakeup callback must have already been cleared when the thread was first |
| 192 | // awoken. | 191 | // awoken. |
| 193 | ASSERT(wakeup_callback == nullptr); | 192 | ASSERT(wakeup_callback == nullptr); |
| 194 | // If the thread is waiting on multiple wait objects, it might be awoken more than once | 193 | // If the thread is waiting on multiple wait objects, it might be awoken more than once |
| 195 | // before actually resuming. We can ignore subsequent wakeups if the thread status has | 194 | // before actually resuming. We can ignore subsequent wakeups if the thread status has |
| 196 | // already been set to THREADSTATUS_READY. | 195 | // already been set to ThreadStatus::Ready. |
| 197 | return; | 196 | return; |
| 198 | 197 | ||
| 199 | case THREADSTATUS_RUNNING: | 198 | case ThreadStatus::Running: |
| 200 | DEBUG_ASSERT_MSG(false, "Thread with object id {} has already resumed.", GetObjectId()); | 199 | DEBUG_ASSERT_MSG(false, "Thread with object id {} has already resumed.", GetObjectId()); |
| 201 | return; | 200 | return; |
| 202 | case THREADSTATUS_DEAD: | 201 | case ThreadStatus::Dead: |
| 203 | // This should never happen, as threads must complete before being stopped. | 202 | // This should never happen, as threads must complete before being stopped. |
| 204 | DEBUG_ASSERT_MSG(false, "Thread with object id {} cannot be resumed because it's DEAD.", | 203 | DEBUG_ASSERT_MSG(false, "Thread with object id {} cannot be resumed because it's DEAD.", |
| 205 | GetObjectId()); | 204 | GetObjectId()); |
| @@ -208,7 +207,7 @@ void Thread::ResumeFromWait() { | |||
| 208 | 207 | ||
| 209 | wakeup_callback = nullptr; | 208 | wakeup_callback = nullptr; |
| 210 | 209 | ||
| 211 | status = THREADSTATUS_READY; | 210 | status = ThreadStatus::Ready; |
| 212 | 211 | ||
| 213 | boost::optional<s32> new_processor_id = GetNextProcessorId(affinity_mask); | 212 | boost::optional<s32> new_processor_id = GetNextProcessorId(affinity_mask); |
| 214 | if (!new_processor_id) { | 213 | if (!new_processor_id) { |
| @@ -310,7 +309,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 310 | SharedPtr<Thread> thread(new Thread); | 309 | SharedPtr<Thread> thread(new Thread); |
| 311 | 310 | ||
| 312 | thread->thread_id = NewThreadId(); | 311 | thread->thread_id = NewThreadId(); |
| 313 | thread->status = THREADSTATUS_DORMANT; | 312 | thread->status = ThreadStatus::Dormant; |
| 314 | thread->entry_point = entry_point; | 313 | thread->entry_point = entry_point; |
| 315 | thread->stack_top = stack_top; | 314 | thread->stack_top = stack_top; |
| 316 | thread->tpidr_el0 = 0; | 315 | thread->tpidr_el0 = 0; |
| @@ -472,7 +471,7 @@ void Thread::ChangeCore(u32 core, u64 mask) { | |||
| 472 | ideal_core = core; | 471 | ideal_core = core; |
| 473 | affinity_mask = mask; | 472 | affinity_mask = mask; |
| 474 | 473 | ||
| 475 | if (status != THREADSTATUS_READY) { | 474 | if (status != ThreadStatus::Ready) { |
| 476 | return; | 475 | return; |
| 477 | } | 476 | } |
| 478 | 477 | ||
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 5fe72c55c..6218960d2 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -36,18 +36,18 @@ enum ThreadProcessorId : s32 { | |||
| 36 | (1 << THREADPROCESSORID_2) | (1 << THREADPROCESSORID_3) | 36 | (1 << THREADPROCESSORID_2) | (1 << THREADPROCESSORID_3) |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | enum ThreadStatus { | 39 | enum class ThreadStatus { |
| 40 | THREADSTATUS_RUNNING, ///< Currently running | 40 | Running, ///< Currently running |
| 41 | THREADSTATUS_READY, ///< Ready to run | 41 | Ready, ///< Ready to run |
| 42 | THREADSTATUS_WAIT_HLE_EVENT, ///< Waiting for hle event to finish | 42 | WaitHLEEvent, ///< Waiting for hle event to finish |
| 43 | THREADSTATUS_WAIT_SLEEP, ///< Waiting due to a SleepThread SVC | 43 | WaitSleep, ///< Waiting due to a SleepThread SVC |
| 44 | THREADSTATUS_WAIT_IPC, ///< Waiting for the reply from an IPC request | 44 | WaitIPC, ///< Waiting for the reply from an IPC request |
| 45 | THREADSTATUS_WAIT_SYNCH_ANY, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false | 45 | WaitSynchAny, ///< Waiting due to WaitSynch1 or WaitSynchN with wait_all = false |
| 46 | THREADSTATUS_WAIT_SYNCH_ALL, ///< Waiting due to WaitSynchronizationN with wait_all = true | 46 | WaitSynchAll, ///< Waiting due to WaitSynchronizationN with wait_all = true |
| 47 | THREADSTATUS_WAIT_MUTEX, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc | 47 | WaitMutex, ///< Waiting due to an ArbitrateLock/WaitProcessWideKey svc |
| 48 | THREADSTATUS_WAIT_ARB, ///< Waiting due to a SignalToAddress/WaitForAddress svc | 48 | WaitArb, ///< Waiting due to a SignalToAddress/WaitForAddress svc |
| 49 | THREADSTATUS_DORMANT, ///< Created but not yet made ready | 49 | Dormant, ///< Created but not yet made ready |
| 50 | THREADSTATUS_DEAD ///< Run to completion, or forcefully terminated | 50 | Dead ///< Run to completion, or forcefully terminated |
| 51 | }; | 51 | }; |
| 52 | 52 | ||
| 53 | enum class ThreadWakeupReason { | 53 | enum class ThreadWakeupReason { |
| @@ -202,14 +202,14 @@ public: | |||
| 202 | * with wait_all = true. | 202 | * with wait_all = true. |
| 203 | */ | 203 | */ |
| 204 | bool IsSleepingOnWaitAll() const { | 204 | bool IsSleepingOnWaitAll() const { |
| 205 | return status == THREADSTATUS_WAIT_SYNCH_ALL; | 205 | return status == ThreadStatus::WaitSynchAll; |
| 206 | } | 206 | } |
| 207 | 207 | ||
| 208 | ARM_Interface::ThreadContext context; | 208 | ARM_Interface::ThreadContext context; |
| 209 | 209 | ||
| 210 | u32 thread_id; | 210 | u32 thread_id; |
| 211 | 211 | ||
| 212 | u32 status; | 212 | ThreadStatus status; |
| 213 | VAddr entry_point; | 213 | VAddr entry_point; |
| 214 | VAddr stack_top; | 214 | VAddr stack_top; |
| 215 | 215 | ||
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp index b08ac72c1..eb3c92e66 100644 --- a/src/core/hle/kernel/wait_object.cpp +++ b/src/core/hle/kernel/wait_object.cpp | |||
| @@ -38,9 +38,9 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | |||
| 38 | 38 | ||
| 39 | for (const auto& thread : waiting_threads) { | 39 | for (const auto& thread : waiting_threads) { |
| 40 | // The list of waiting threads must not contain threads that are not waiting to be awakened. | 40 | // The list of waiting threads must not contain threads that are not waiting to be awakened. |
| 41 | ASSERT_MSG(thread->status == THREADSTATUS_WAIT_SYNCH_ANY || | 41 | ASSERT_MSG(thread->status == ThreadStatus::WaitSynchAny || |
| 42 | thread->status == THREADSTATUS_WAIT_SYNCH_ALL || | 42 | thread->status == ThreadStatus::WaitSynchAll || |
| 43 | thread->status == THREADSTATUS_WAIT_HLE_EVENT, | 43 | thread->status == ThreadStatus::WaitHLEEvent, |
| 44 | "Inconsistent thread statuses in waiting_threads"); | 44 | "Inconsistent thread statuses in waiting_threads"); |
| 45 | 45 | ||
| 46 | if (thread->current_priority >= candidate_priority) | 46 | if (thread->current_priority >= candidate_priority) |
| @@ -49,10 +49,10 @@ SharedPtr<Thread> WaitObject::GetHighestPriorityReadyThread() { | |||
| 49 | if (ShouldWait(thread.get())) | 49 | if (ShouldWait(thread.get())) |
| 50 | continue; | 50 | continue; |
| 51 | 51 | ||
| 52 | // A thread is ready to run if it's either in THREADSTATUS_WAIT_SYNCH_ANY or | 52 | // A thread is ready to run if it's either in ThreadStatus::WaitSynchAny or |
| 53 | // in THREADSTATUS_WAIT_SYNCH_ALL and the rest of the objects it is waiting on are ready. | 53 | // in ThreadStatus::WaitSynchAll and the rest of the objects it is waiting on are ready. |
| 54 | bool ready_to_run = true; | 54 | bool ready_to_run = true; |
| 55 | if (thread->status == THREADSTATUS_WAIT_SYNCH_ALL) { | 55 | if (thread->status == ThreadStatus::WaitSynchAll) { |
| 56 | ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(), | 56 | ready_to_run = std::none_of(thread->wait_objects.begin(), thread->wait_objects.end(), |
| 57 | [&thread](const SharedPtr<WaitObject>& object) { | 57 | [&thread](const SharedPtr<WaitObject>& object) { |
| 58 | return object->ShouldWait(thread.get()); | 58 | return object->ShouldWait(thread.get()); |
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 8ee39b54c..3e1c2c0a0 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp | |||
| @@ -82,14 +82,16 @@ private: | |||
| 82 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 82 | LOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 83 | IPC::ResponseBuilder rb{ctx, 3}; | 83 | IPC::ResponseBuilder rb{ctx, 3}; |
| 84 | rb.Push(RESULT_SUCCESS); | 84 | rb.Push(RESULT_SUCCESS); |
| 85 | rb.Push(true); // TODO: Check when this is supposed to return true and when not | 85 | rb.Push(false); // TODO: Check when this is supposed to return true and when not |
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | void GetAccountId(Kernel::HLERequestContext& ctx) { | 88 | void GetAccountId(Kernel::HLERequestContext& ctx) { |
| 89 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 89 | LOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 90 | IPC::ResponseBuilder rb{ctx, 4}; | 90 | // TODO(Subv): Find out what this actually does and implement it. Stub it as an error for |
| 91 | rb.Push(RESULT_SUCCESS); | 91 | // now since we do not implement NNID. Returning a bogus id here will cause games to send |
| 92 | rb.Push<u64>(0x12345678ABCDEF); | 92 | // invalid IPC requests after ListOpenUsers is called. |
| 93 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 94 | rb.Push(ResultCode(-1)); | ||
| 93 | } | 95 | } |
| 94 | }; | 96 | }; |
| 95 | 97 | ||
| @@ -104,7 +106,7 @@ void Module::Interface::ListAllUsers(Kernel::HLERequestContext& ctx) { | |||
| 104 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 106 | LOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 105 | // TODO(Subv): There is only one user for now. | 107 | // TODO(Subv): There is only one user for now. |
| 106 | const std::vector<u128> user_ids = {DEFAULT_USER_ID}; | 108 | const std::vector<u128> user_ids = {DEFAULT_USER_ID}; |
| 107 | ctx.WriteBuffer(user_ids.data(), user_ids.size() * sizeof(u128)); | 109 | ctx.WriteBuffer(user_ids); |
| 108 | IPC::ResponseBuilder rb{ctx, 2}; | 110 | IPC::ResponseBuilder rb{ctx, 2}; |
| 109 | rb.Push(RESULT_SUCCESS); | 111 | rb.Push(RESULT_SUCCESS); |
| 110 | } | 112 | } |
| @@ -113,7 +115,7 @@ void Module::Interface::ListOpenUsers(Kernel::HLERequestContext& ctx) { | |||
| 113 | LOG_WARNING(Service_ACC, "(STUBBED) called"); | 115 | LOG_WARNING(Service_ACC, "(STUBBED) called"); |
| 114 | // TODO(Subv): There is only one user for now. | 116 | // TODO(Subv): There is only one user for now. |
| 115 | const std::vector<u128> user_ids = {DEFAULT_USER_ID}; | 117 | const std::vector<u128> user_ids = {DEFAULT_USER_ID}; |
| 116 | ctx.WriteBuffer(user_ids.data(), user_ids.size() * sizeof(u128)); | 118 | ctx.WriteBuffer(user_ids); |
| 117 | IPC::ResponseBuilder rb{ctx, 2}; | 119 | IPC::ResponseBuilder rb{ctx, 2}; |
| 118 | rb.Push(RESULT_SUCCESS); | 120 | rb.Push(RESULT_SUCCESS); |
| 119 | } | 121 | } |
diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index 751d73f8d..ce943d829 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp | |||
| @@ -20,6 +20,21 @@ public: | |||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | private: | 22 | private: |
| 23 | enum class PerformanceConfiguration : u32 { | ||
| 24 | Config1 = 0x00010000, | ||
| 25 | Config2 = 0x00010001, | ||
| 26 | Config3 = 0x00010002, | ||
| 27 | Config4 = 0x00020000, | ||
| 28 | Config5 = 0x00020001, | ||
| 29 | Config6 = 0x00020002, | ||
| 30 | Config7 = 0x00020003, | ||
| 31 | Config8 = 0x00020004, | ||
| 32 | Config9 = 0x00020005, | ||
| 33 | Config10 = 0x00020006, | ||
| 34 | Config11 = 0x92220007, | ||
| 35 | Config12 = 0x92220008, | ||
| 36 | }; | ||
| 37 | |||
| 23 | void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { | 38 | void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) { |
| 24 | IPC::RequestParser rp{ctx}; | 39 | IPC::RequestParser rp{ctx}; |
| 25 | 40 | ||
| @@ -40,7 +55,7 @@ private: | |||
| 40 | 55 | ||
| 41 | IPC::ResponseBuilder rb{ctx, 3}; | 56 | IPC::ResponseBuilder rb{ctx, 3}; |
| 42 | rb.Push(RESULT_SUCCESS); | 57 | rb.Push(RESULT_SUCCESS); |
| 43 | rb.Push<u32>(0); // Performance configuration | 58 | rb.Push<u32>(static_cast<u32>(PerformanceConfiguration::Config1)); |
| 44 | 59 | ||
| 45 | LOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode)); | 60 | LOG_WARNING(Service_APM, "(STUBBED) called mode={}", static_cast<u32>(mode)); |
| 46 | } | 61 | } |
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 4217ea4fb..154bc12da 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 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 | #include <array> | ||
| 5 | #include <vector> | 6 | #include <vector> |
| 6 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 7 | #include "core/core_timing.h" | 8 | #include "core/core_timing.h" |
| @@ -167,7 +168,7 @@ void AudOutU::ListAudioOutsImpl(Kernel::HLERequestContext& ctx) { | |||
| 167 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 168 | LOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 168 | IPC::RequestParser rp{ctx}; | 169 | IPC::RequestParser rp{ctx}; |
| 169 | 170 | ||
| 170 | const std::string audio_interface = "AudioInterface"; | 171 | constexpr std::array<char, 15> audio_interface{{"AudioInterface"}}; |
| 171 | ctx.WriteBuffer(audio_interface); | 172 | ctx.WriteBuffer(audio_interface); |
| 172 | 173 | ||
| 173 | IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); | 174 | IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); |
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 6903f52d6..e623f4f8e 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -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 | #include <array> | ||
| 6 | |||
| 5 | #include "common/alignment.h" | 7 | #include "common/alignment.h" |
| 6 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 7 | #include "core/core_timing.h" | 9 | #include "core/core_timing.h" |
| @@ -298,7 +300,7 @@ private: | |||
| 298 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 300 | LOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 299 | IPC::RequestParser rp{ctx}; | 301 | IPC::RequestParser rp{ctx}; |
| 300 | 302 | ||
| 301 | const std::string audio_interface = "AudioInterface"; | 303 | constexpr std::array<char, 15> audio_interface{{"AudioInterface"}}; |
| 302 | ctx.WriteBuffer(audio_interface); | 304 | ctx.WriteBuffer(audio_interface); |
| 303 | 305 | ||
| 304 | IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); | 306 | IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); |
| @@ -323,7 +325,7 @@ private: | |||
| 323 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 325 | LOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 324 | IPC::RequestParser rp{ctx}; | 326 | IPC::RequestParser rp{ctx}; |
| 325 | 327 | ||
| 326 | const std::string audio_interface = "AudioDevice"; | 328 | constexpr std::array<char, 12> audio_interface{{"AudioDevice"}}; |
| 327 | ctx.WriteBuffer(audio_interface); | 329 | ctx.WriteBuffer(audio_interface); |
| 328 | 330 | ||
| 329 | IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); | 331 | IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0); |
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 19b8667ba..394963a69 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp | |||
| @@ -83,16 +83,13 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load( | |||
| 83 | VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR}; | 83 | VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR}; |
| 84 | for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", | 84 | for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3", |
| 85 | "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { | 85 | "subsdk4", "subsdk5", "subsdk6", "subsdk7", "sdk"}) { |
| 86 | const VAddr load_addr = next_load_addr; | ||
| 87 | const FileSys::VirtualFile module_file = dir->GetFile(module); | 86 | const FileSys::VirtualFile module_file = dir->GetFile(module); |
| 88 | if (module_file != nullptr) | 87 | if (module_file != nullptr) { |
| 88 | const VAddr load_addr = next_load_addr; | ||
| 89 | next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr); | 89 | next_load_addr = AppLoader_NSO::LoadModule(module_file, load_addr); |
| 90 | if (next_load_addr) { | ||
| 91 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); | 90 | LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", module, load_addr); |
| 92 | // Register module with GDBStub | 91 | // Register module with GDBStub |
| 93 | GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); | 92 | GDBStub::RegisterModule(module, load_addr, next_load_addr - 1, false); |
| 94 | } else { | ||
| 95 | next_load_addr = load_addr; | ||
| 96 | } | 93 | } |
| 97 | } | 94 | } |
| 98 | 95 | ||
diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index e73b253b2..c80df23be 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 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 | #include <utility> | ||
| 5 | #include <vector> | 6 | #include <vector> |
| 6 | 7 | ||
| 7 | #include "common/file_util.h" | 8 | #include "common/file_util.h" |
| @@ -21,7 +22,7 @@ | |||
| 21 | 22 | ||
| 22 | namespace Loader { | 23 | namespace Loader { |
| 23 | 24 | ||
| 24 | AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(file) {} | 25 | AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} |
| 25 | 26 | ||
| 26 | FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { | 27 | FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { |
| 27 | // TODO(DarkLordZach): Assuming everything is decrypted. Add crypto support. | 28 | // TODO(DarkLordZach): Assuming everything is decrypted. Add crypto support. |
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 465b827bb..c020399f2 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp | |||
| @@ -2,6 +2,7 @@ | |||
| 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 | #include <utility> | ||
| 5 | #include <vector> | 6 | #include <vector> |
| 6 | 7 | ||
| 7 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| @@ -48,7 +49,7 @@ struct ModHeader { | |||
| 48 | }; | 49 | }; |
| 49 | static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size."); | 50 | static_assert(sizeof(ModHeader) == 0x1c, "ModHeader has incorrect size."); |
| 50 | 51 | ||
| 51 | AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file) : AppLoader(file) {} | 52 | AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} |
| 52 | 53 | ||
| 53 | FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& file) { | 54 | FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& file) { |
| 54 | // Read NSO header | 55 | // Read NSO header |
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index c66561bf4..06b1b33f4 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp | |||
| @@ -69,29 +69,18 @@ FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& file) { | |||
| 69 | static std::vector<u8> DecompressSegment(const std::vector<u8>& compressed_data, | 69 | static std::vector<u8> DecompressSegment(const std::vector<u8>& compressed_data, |
| 70 | const NsoSegmentHeader& header) { | 70 | const NsoSegmentHeader& header) { |
| 71 | std::vector<u8> uncompressed_data(header.size); | 71 | std::vector<u8> uncompressed_data(header.size); |
| 72 | const int bytes_uncompressed = LZ4_decompress_safe( | 72 | const int bytes_uncompressed = |
| 73 | reinterpret_cast<const char*>(compressed_data.data()), | 73 | LZ4_decompress_safe(reinterpret_cast<const char*>(compressed_data.data()), |
| 74 | reinterpret_cast<char*>(uncompressed_data.data()), compressed_data.size(), header.size); | 74 | reinterpret_cast<char*>(uncompressed_data.data()), |
| 75 | static_cast<int>(compressed_data.size()), header.size); | ||
| 75 | 76 | ||
| 76 | ASSERT_MSG(bytes_uncompressed == header.size && bytes_uncompressed == uncompressed_data.size(), | 77 | ASSERT_MSG(bytes_uncompressed == static_cast<int>(header.size) && |
| 78 | bytes_uncompressed == static_cast<int>(uncompressed_data.size()), | ||
| 77 | "{} != {} != {}", bytes_uncompressed, header.size, uncompressed_data.size()); | 79 | "{} != {} != {}", bytes_uncompressed, header.size, uncompressed_data.size()); |
| 78 | 80 | ||
| 79 | return uncompressed_data; | 81 | return uncompressed_data; |
| 80 | } | 82 | } |
| 81 | 83 | ||
| 82 | static std::vector<u8> ReadSegment(FileUtil::IOFile& file, const NsoSegmentHeader& header, | ||
| 83 | size_t compressed_size) { | ||
| 84 | std::vector<u8> compressed_data(compressed_size); | ||
| 85 | |||
| 86 | file.Seek(header.offset, SEEK_SET); | ||
| 87 | if (compressed_size != file.ReadBytes(compressed_data.data(), compressed_size)) { | ||
| 88 | LOG_CRITICAL(Loader, "Failed to read {} NSO LZ4 compressed bytes", compressed_size); | ||
| 89 | return {}; | ||
| 90 | } | ||
| 91 | |||
| 92 | return DecompressSegment(compressed_data, header); | ||
| 93 | } | ||
| 94 | |||
| 95 | static constexpr u32 PageAlignSize(u32 size) { | 84 | static constexpr u32 PageAlignSize(u32 size) { |
| 96 | return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; | 85 | return (size + Memory::PAGE_MASK) & ~Memory::PAGE_MASK; |
| 97 | } | 86 | } |
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index dfbf80abd..d7328ff39 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -317,8 +317,6 @@ std::vector<Texture::FullTextureInfo> Maxwell3D::GetStageTextures(Regs::ShaderSt | |||
| 317 | auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; | 317 | auto& tex_info_buffer = fragment_shader.const_buffers[regs.tex_cb_index]; |
| 318 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); | 318 | ASSERT(tex_info_buffer.enabled && tex_info_buffer.address != 0); |
| 319 | 319 | ||
| 320 | GPUVAddr tic_base_address = regs.tic.TICAddress(); | ||
| 321 | |||
| 322 | GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; | 320 | GPUVAddr tex_info_buffer_end = tex_info_buffer.address + tex_info_buffer.size; |
| 323 | 321 | ||
| 324 | // Offset into the texture constbuffer where the texture info begins. | 322 | // Offset into the texture constbuffer where the texture info begins. |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 9b308b923..a1ac18a71 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -1405,7 +1405,7 @@ private: | |||
| 1405 | 1405 | ||
| 1406 | // TEXS has two destination registers. RG goes into gpr0+0 and gpr0+1, and BA | 1406 | // TEXS has two destination registers. RG goes into gpr0+0 and gpr0+1, and BA |
| 1407 | // goes into gpr28+0 and gpr28+1 | 1407 | // goes into gpr28+0 and gpr28+1 |
| 1408 | size_t offset{}; | 1408 | size_t texs_offset{}; |
| 1409 | 1409 | ||
| 1410 | for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { | 1410 | for (const auto& dest : {instr.gpr0.Value(), instr.gpr28.Value()}) { |
| 1411 | for (unsigned elem = 0; elem < 2; ++elem) { | 1411 | for (unsigned elem = 0; elem < 2; ++elem) { |
| @@ -1413,7 +1413,8 @@ private: | |||
| 1413 | // Skip disabled components | 1413 | // Skip disabled components |
| 1414 | continue; | 1414 | continue; |
| 1415 | } | 1415 | } |
| 1416 | regs.SetRegisterToFloat(dest, elem + offset, texture, 1, 4, false, elem); | 1416 | regs.SetRegisterToFloat(dest, elem + texs_offset, texture, 1, 4, false, |
| 1417 | elem); | ||
| 1417 | } | 1418 | } |
| 1418 | 1419 | ||
| 1419 | if (!instr.texs.HasTwoDestinations()) { | 1420 | if (!instr.texs.HasTwoDestinations()) { |
| @@ -1421,7 +1422,7 @@ private: | |||
| 1421 | break; | 1422 | break; |
| 1422 | } | 1423 | } |
| 1423 | 1424 | ||
| 1424 | offset += 2; | 1425 | texs_offset += 2; |
| 1425 | } | 1426 | } |
| 1426 | --shader.scope; | 1427 | --shader.scope; |
| 1427 | shader.AddLine("}"); | 1428 | shader.AddLine("}"); |
| @@ -1463,7 +1464,6 @@ private: | |||
| 1463 | op_b = "abs(" + op_b + ')'; | 1464 | op_b = "abs(" + op_b + ')'; |
| 1464 | } | 1465 | } |
| 1465 | 1466 | ||
| 1466 | using Tegra::Shader::Pred; | ||
| 1467 | // We can't use the constant predicate as destination. | 1467 | // We can't use the constant predicate as destination. |
| 1468 | ASSERT(instr.fsetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | 1468 | ASSERT(instr.fsetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); |
| 1469 | 1469 | ||
| @@ -1500,7 +1500,6 @@ private: | |||
| 1500 | } | 1500 | } |
| 1501 | } | 1501 | } |
| 1502 | 1502 | ||
| 1503 | using Tegra::Shader::Pred; | ||
| 1504 | // We can't use the constant predicate as destination. | 1503 | // We can't use the constant predicate as destination. |
| 1505 | ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | 1504 | ASSERT(instr.isetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); |
| 1506 | 1505 | ||
| @@ -1528,7 +1527,6 @@ private: | |||
| 1528 | std::string op_b = | 1527 | std::string op_b = |
| 1529 | GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0); | 1528 | GetPredicateCondition(instr.psetp.pred29, instr.psetp.neg_pred29 != 0); |
| 1530 | 1529 | ||
| 1531 | using Tegra::Shader::Pred; | ||
| 1532 | // We can't use the constant predicate as destination. | 1530 | // We can't use the constant predicate as destination. |
| 1533 | ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); | 1531 | ASSERT(instr.psetp.pred3 != static_cast<u64>(Pred::UnusedIndex)); |
| 1534 | 1532 | ||
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp index 2e8a422a8..68bacd4c5 100644 --- a/src/video_core/renderer_opengl/gl_state.cpp +++ b/src/video_core/renderer_opengl/gl_state.cpp | |||
| @@ -181,30 +181,34 @@ void OpenGLState::Apply() const { | |||
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | // Textures | 183 | // Textures |
| 184 | for (int i = 0; i < std::size(texture_units); ++i) { | 184 | for (std::size_t i = 0; i < std::size(texture_units); ++i) { |
| 185 | if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) { | 185 | const auto& texture_unit = texture_units[i]; |
| 186 | glActiveTexture(TextureUnits::MaxwellTexture(i).Enum()); | 186 | const auto& cur_state_texture_unit = cur_state.texture_units[i]; |
| 187 | glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d); | 187 | |
| 188 | if (texture_unit.texture_2d != cur_state_texture_unit.texture_2d) { | ||
| 189 | glActiveTexture(TextureUnits::MaxwellTexture(static_cast<int>(i)).Enum()); | ||
| 190 | glBindTexture(GL_TEXTURE_2D, texture_unit.texture_2d); | ||
| 188 | } | 191 | } |
| 189 | if (texture_units[i].sampler != cur_state.texture_units[i].sampler) { | 192 | if (texture_unit.sampler != cur_state_texture_unit.sampler) { |
| 190 | glBindSampler(static_cast<GLuint>(i), texture_units[i].sampler); | 193 | glBindSampler(static_cast<GLuint>(i), texture_unit.sampler); |
| 191 | } | 194 | } |
| 192 | // Update the texture swizzle | 195 | // Update the texture swizzle |
| 193 | if (texture_units[i].swizzle.r != cur_state.texture_units[i].swizzle.r || | 196 | if (texture_unit.swizzle.r != cur_state_texture_unit.swizzle.r || |
| 194 | texture_units[i].swizzle.g != cur_state.texture_units[i].swizzle.g || | 197 | texture_unit.swizzle.g != cur_state_texture_unit.swizzle.g || |
| 195 | texture_units[i].swizzle.b != cur_state.texture_units[i].swizzle.b || | 198 | texture_unit.swizzle.b != cur_state_texture_unit.swizzle.b || |
| 196 | texture_units[i].swizzle.a != cur_state.texture_units[i].swizzle.a) { | 199 | texture_unit.swizzle.a != cur_state_texture_unit.swizzle.a) { |
| 197 | std::array<GLint, 4> mask = {texture_units[i].swizzle.r, texture_units[i].swizzle.g, | 200 | std::array<GLint, 4> mask = {texture_unit.swizzle.r, texture_unit.swizzle.g, |
| 198 | texture_units[i].swizzle.b, texture_units[i].swizzle.a}; | 201 | texture_unit.swizzle.b, texture_unit.swizzle.a}; |
| 199 | glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask.data()); | 202 | glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, mask.data()); |
| 200 | } | 203 | } |
| 201 | } | 204 | } |
| 202 | 205 | ||
| 203 | // Constbuffers | 206 | // Constbuffers |
| 204 | for (u32 stage = 0; stage < draw.const_buffers.size(); ++stage) { | 207 | for (std::size_t stage = 0; stage < draw.const_buffers.size(); ++stage) { |
| 205 | for (u32 buffer_id = 0; buffer_id < draw.const_buffers[stage].size(); ++buffer_id) { | 208 | for (std::size_t buffer_id = 0; buffer_id < draw.const_buffers[stage].size(); ++buffer_id) { |
| 206 | auto& current = cur_state.draw.const_buffers[stage][buffer_id]; | 209 | const auto& current = cur_state.draw.const_buffers[stage][buffer_id]; |
| 207 | auto& new_state = draw.const_buffers[stage][buffer_id]; | 210 | const auto& new_state = draw.const_buffers[stage][buffer_id]; |
| 211 | |||
| 208 | if (current.enabled != new_state.enabled || current.bindpoint != new_state.bindpoint || | 212 | if (current.enabled != new_state.enabled || current.bindpoint != new_state.bindpoint || |
| 209 | current.ssbo != new_state.ssbo) { | 213 | current.ssbo != new_state.ssbo) { |
| 210 | if (new_state.enabled) { | 214 | if (new_state.enabled) { |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 7101b381e..8f24586ce 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -194,32 +194,32 @@ QString WaitTreeThread::GetText() const { | |||
| 194 | const auto& thread = static_cast<const Kernel::Thread&>(object); | 194 | const auto& thread = static_cast<const Kernel::Thread&>(object); |
| 195 | QString status; | 195 | QString status; |
| 196 | switch (thread.status) { | 196 | switch (thread.status) { |
| 197 | case THREADSTATUS_RUNNING: | 197 | case ThreadStatus::Running: |
| 198 | status = tr("running"); | 198 | status = tr("running"); |
| 199 | break; | 199 | break; |
| 200 | case THREADSTATUS_READY: | 200 | case ThreadStatus::Ready: |
| 201 | status = tr("ready"); | 201 | status = tr("ready"); |
| 202 | break; | 202 | break; |
| 203 | case THREADSTATUS_WAIT_HLE_EVENT: | 203 | case ThreadStatus::WaitHLEEvent: |
| 204 | status = tr("waiting for HLE return"); | 204 | status = tr("waiting for HLE return"); |
| 205 | break; | 205 | break; |
| 206 | case THREADSTATUS_WAIT_SLEEP: | 206 | case ThreadStatus::WaitSleep: |
| 207 | status = tr("sleeping"); | 207 | status = tr("sleeping"); |
| 208 | break; | 208 | break; |
| 209 | case THREADSTATUS_WAIT_SYNCH_ALL: | 209 | case ThreadStatus::WaitSynchAll: |
| 210 | case THREADSTATUS_WAIT_SYNCH_ANY: | 210 | case ThreadStatus::WaitSynchAny: |
| 211 | status = tr("waiting for objects"); | 211 | status = tr("waiting for objects"); |
| 212 | break; | 212 | break; |
| 213 | case THREADSTATUS_WAIT_MUTEX: | 213 | case ThreadStatus::WaitMutex: |
| 214 | status = tr("waiting for mutex"); | 214 | status = tr("waiting for mutex"); |
| 215 | break; | 215 | break; |
| 216 | case THREADSTATUS_WAIT_ARB: | 216 | case ThreadStatus::WaitArb: |
| 217 | status = tr("waiting for address arbiter"); | 217 | status = tr("waiting for address arbiter"); |
| 218 | break; | 218 | break; |
| 219 | case THREADSTATUS_DORMANT: | 219 | case ThreadStatus::Dormant: |
| 220 | status = tr("dormant"); | 220 | status = tr("dormant"); |
| 221 | break; | 221 | break; |
| 222 | case THREADSTATUS_DEAD: | 222 | case ThreadStatus::Dead: |
| 223 | status = tr("dead"); | 223 | status = tr("dead"); |
| 224 | break; | 224 | break; |
| 225 | } | 225 | } |
| @@ -232,22 +232,22 @@ QString WaitTreeThread::GetText() const { | |||
| 232 | QColor WaitTreeThread::GetColor() const { | 232 | QColor WaitTreeThread::GetColor() const { |
| 233 | const auto& thread = static_cast<const Kernel::Thread&>(object); | 233 | const auto& thread = static_cast<const Kernel::Thread&>(object); |
| 234 | switch (thread.status) { | 234 | switch (thread.status) { |
| 235 | case THREADSTATUS_RUNNING: | 235 | case ThreadStatus::Running: |
| 236 | return QColor(Qt::GlobalColor::darkGreen); | 236 | return QColor(Qt::GlobalColor::darkGreen); |
| 237 | case THREADSTATUS_READY: | 237 | case ThreadStatus::Ready: |
| 238 | return QColor(Qt::GlobalColor::darkBlue); | 238 | return QColor(Qt::GlobalColor::darkBlue); |
| 239 | case THREADSTATUS_WAIT_HLE_EVENT: | 239 | case ThreadStatus::WaitHLEEvent: |
| 240 | return QColor(Qt::GlobalColor::darkRed); | 240 | return QColor(Qt::GlobalColor::darkRed); |
| 241 | case THREADSTATUS_WAIT_SLEEP: | 241 | case ThreadStatus::WaitSleep: |
| 242 | return QColor(Qt::GlobalColor::darkYellow); | 242 | return QColor(Qt::GlobalColor::darkYellow); |
| 243 | case THREADSTATUS_WAIT_SYNCH_ALL: | 243 | case ThreadStatus::WaitSynchAll: |
| 244 | case THREADSTATUS_WAIT_SYNCH_ANY: | 244 | case ThreadStatus::WaitSynchAny: |
| 245 | case THREADSTATUS_WAIT_MUTEX: | 245 | case ThreadStatus::WaitMutex: |
| 246 | case THREADSTATUS_WAIT_ARB: | 246 | case ThreadStatus::WaitArb: |
| 247 | return QColor(Qt::GlobalColor::red); | 247 | return QColor(Qt::GlobalColor::red); |
| 248 | case THREADSTATUS_DORMANT: | 248 | case ThreadStatus::Dormant: |
| 249 | return QColor(Qt::GlobalColor::darkCyan); | 249 | return QColor(Qt::GlobalColor::darkCyan); |
| 250 | case THREADSTATUS_DEAD: | 250 | case ThreadStatus::Dead: |
| 251 | return QColor(Qt::GlobalColor::gray); | 251 | return QColor(Qt::GlobalColor::gray); |
| 252 | default: | 252 | default: |
| 253 | return WaitTreeItem::GetColor(); | 253 | return WaitTreeItem::GetColor(); |
| @@ -291,8 +291,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
| 291 | else | 291 | else |
| 292 | list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); | 292 | list.push_back(std::make_unique<WaitTreeText>(tr("not waiting for mutex"))); |
| 293 | 293 | ||
| 294 | if (thread.status == THREADSTATUS_WAIT_SYNCH_ANY || | 294 | if (thread.status == ThreadStatus::WaitSynchAny || |
| 295 | thread.status == THREADSTATUS_WAIT_SYNCH_ALL) { | 295 | thread.status == ThreadStatus::WaitSynchAll) { |
| 296 | list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects, | 296 | list.push_back(std::make_unique<WaitTreeObjectList>(thread.wait_objects, |
| 297 | thread.IsSleepingOnWaitAll())); | 297 | thread.IsSleepingOnWaitAll())); |
| 298 | } | 298 | } |