summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/swap.h46
-rw-r--r--src/core/CMakeLists.txt8
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp30
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp34
-rw-r--r--src/core/constants.h1
-rw-r--r--src/core/cpu_manager.h10
-rw-r--r--src/core/file_sys/bis_factory.cpp23
-rw-r--r--src/core/file_sys/registered_cache.cpp98
-rw-r--r--src/core/file_sys/registered_cache.h4
-rw-r--r--src/core/file_sys/sdmc_factory.cpp4
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp1
-rw-r--r--src/core/hle/kernel/handle_table.cpp8
-rw-r--r--src/core/hle/kernel/handle_table.h7
-rw-r--r--src/core/hle/kernel/kernel.cpp16
-rw-r--r--src/core/hle/kernel/kernel.h1
-rw-r--r--src/core/hle/kernel/memory/address_space_info.cpp67
-rw-r--r--src/core/hle/kernel/memory/address_space_info.h29
-rw-r--r--src/core/hle/kernel/memory/memory_layout.h2
-rw-r--r--src/core/hle/kernel/process.cpp2
-rw-r--r--src/core/hle/kernel/process.h12
-rw-r--r--src/core/hle/kernel/scheduler.cpp2
-rw-r--r--src/core/hle/kernel/svc.cpp7
-rw-r--r--src/core/hle/kernel/synchronization.cpp1
-rw-r--r--src/core/hle/kernel/thread.cpp24
-rw-r--r--src/core/hle/kernel/thread.h7
-rw-r--r--src/core/hle/service/mii/manager.cpp483
-rw-r--r--src/core/hle/service/mii/manager.h331
-rw-r--r--src/core/hle/service/mii/mii.cpp315
-rw-r--r--src/core/hle/service/mii/mii_manager.cpp420
-rw-r--r--src/core/hle/service/mii/mii_manager.h273
-rw-r--r--src/core/hle/service/mii/raw_data.cpp2261
-rw-r--r--src/core/hle/service/mii/raw_data.h27
-rw-r--r--src/core/hle/service/mii/types.h67
-rw-r--r--src/core/settings.cpp82
-rw-r--r--src/core/settings.h50
-rw-r--r--src/input_common/CMakeLists.txt3
-rw-r--r--src/input_common/gcadapter/gc_adapter.cpp80
-rw-r--r--src/input_common/gcadapter/gc_adapter.h25
-rw-r--r--src/input_common/gcadapter/gc_poller.cpp60
-rw-r--r--src/input_common/gcadapter/gc_poller.h2
-rw-r--r--src/input_common/main.cpp1
-rw-r--r--src/input_common/udp/client.cpp2
-rw-r--r--src/video_core/engines/maxwell_dma.cpp300
-rw-r--r--src/video_core/engines/maxwell_dma.h348
-rw-r--r--src/video_core/macro/macro.h3
-rw-r--r--src/video_core/macro/macro_hle.cpp20
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp718
-rw-r--r--src/video_core/renderer_vulkan/vk_device.cpp276
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp423
-rw-r--r--src/video_core/renderer_vulkan/vk_texture_cache.cpp10
-rw-r--r--src/video_core/shader_cache.h4
-rw-r--r--src/video_core/texture_cache/surface_params.cpp5
-rw-r--r--src/video_core/texture_cache/surface_params.h2
-rw-r--r--src/video_core/textures/decoders.cpp134
-rw-r--r--src/video_core/textures/decoders.h38
-rw-r--r--src/yuzu/CMakeLists.txt6
-rw-r--r--src/yuzu/configuration/config.cpp90
-rw-r--r--src/yuzu/configuration/config.h2
-rw-r--r--src/yuzu/configuration/configure.ui22
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp61
-rw-r--r--src/yuzu/configuration/configure_cpu.h33
-rw-r--r--src/yuzu/configuration/configure_cpu.ui92
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp65
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.h31
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.ui174
-rw-r--r--src/yuzu/configuration/configure_debug.cpp2
-rw-r--r--src/yuzu/configuration/configure_debug.ui7
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp7
-rw-r--r--src/yuzu/configuration/configure_filesystem.cpp27
-rw-r--r--src/yuzu/configuration/configure_filesystem.ui121
-rw-r--r--src/yuzu/configuration/configure_general.cpp2
-rw-r--r--src/yuzu/main.cpp26
-rw-r--r--src/yuzu_cmd/config.cpp11
-rw-r--r--src/yuzu_cmd/default_ini.h36
-rw-r--r--src/yuzu_tester/default_ini.h33
75 files changed, 5573 insertions, 2482 deletions
diff --git a/src/common/swap.h b/src/common/swap.h
index 71932c2bb..7665942a2 100644
--- a/src/common/swap.h
+++ b/src/common/swap.h
@@ -17,43 +17,14 @@
17 17
18#pragma once 18#pragma once
19 19
20#include <type_traits>
21
22#if defined(_MSC_VER) 20#if defined(_MSC_VER)
23#include <cstdlib> 21#include <cstdlib>
24#endif 22#endif
23#include <bit>
25#include <cstring> 24#include <cstring>
25#include <type_traits>
26#include "common/common_types.h" 26#include "common/common_types.h"
27 27
28// GCC
29#ifdef __GNUC__
30
31#if __BYTE_ORDER__ && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) && !defined(COMMON_LITTLE_ENDIAN)
32#define COMMON_LITTLE_ENDIAN 1
33#elif __BYTE_ORDER__ && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) && !defined(COMMON_BIG_ENDIAN)
34#define COMMON_BIG_ENDIAN 1
35#endif
36
37// LLVM/clang
38#elif defined(__clang__)
39
40#if __LITTLE_ENDIAN__ && !defined(COMMON_LITTLE_ENDIAN)
41#define COMMON_LITTLE_ENDIAN 1
42#elif __BIG_ENDIAN__ && !defined(COMMON_BIG_ENDIAN)
43#define COMMON_BIG_ENDIAN 1
44#endif
45
46// MSVC
47#elif defined(_MSC_VER) && !defined(COMMON_BIG_ENDIAN) && !defined(COMMON_LITTLE_ENDIAN)
48
49#define COMMON_LITTLE_ENDIAN 1
50#endif
51
52// Worst case, default to little endian.
53#if !COMMON_BIG_ENDIAN && !COMMON_LITTLE_ENDIAN
54#define COMMON_LITTLE_ENDIAN 1
55#endif
56
57namespace Common { 28namespace Common {
58 29
59#ifdef _MSC_VER 30#ifdef _MSC_VER
@@ -675,17 +646,8 @@ struct AddEndian<T, SwapTag> {
675}; 646};
676 647
677// Alias LETag/BETag as KeepTag/SwapTag depending on the system 648// Alias LETag/BETag as KeepTag/SwapTag depending on the system
678#if COMMON_LITTLE_ENDIAN 649using LETag = std::conditional_t<std::endian::native == std::endian::little, KeepTag, SwapTag>;
679 650using BETag = std::conditional_t<std::endian::native == std::endian::big, KeepTag, SwapTag>;
680using LETag = KeepTag;
681using BETag = SwapTag;
682
683#else
684
685using BETag = KeepTag;
686using LETag = SwapTag;
687
688#endif
689 651
690// Aliases for LE types 652// Aliases for LE types
691using u16_le = AddEndian<u16, LETag>::type; 653using u16_le = AddEndian<u16, LETag>::type;
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index d1f173f42..c42f95705 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -185,6 +185,7 @@ add_library(core STATIC
185 hle/kernel/object.h 185 hle/kernel/object.h
186 hle/kernel/physical_core.cpp 186 hle/kernel/physical_core.cpp
187 hle/kernel/physical_core.h 187 hle/kernel/physical_core.h
188 hle/kernel/physical_memory.h
188 hle/kernel/process.cpp 189 hle/kernel/process.cpp
189 hle/kernel/process.h 190 hle/kernel/process.h
190 hle/kernel/process_capability.cpp 191 hle/kernel/process_capability.cpp
@@ -398,10 +399,13 @@ add_library(core STATIC
398 hle/service/lm/manager.h 399 hle/service/lm/manager.h
399 hle/service/mig/mig.cpp 400 hle/service/mig/mig.cpp
400 hle/service/mig/mig.h 401 hle/service/mig/mig.h
402 hle/service/mii/manager.cpp
403 hle/service/mii/manager.h
401 hle/service/mii/mii.cpp 404 hle/service/mii/mii.cpp
402 hle/service/mii/mii.h 405 hle/service/mii/mii.h
403 hle/service/mii/mii_manager.cpp 406 hle/service/mii/raw_data.cpp
404 hle/service/mii/mii_manager.h 407 hle/service/mii/raw_data.h
408 hle/service/mii/types.h
405 hle/service/mm/mm_u.cpp 409 hle/service/mm/mm_u.cpp
406 hle/service/mm/mm_u.h 410 hle/service/mm/mm_u.h
407 hle/service/ncm/ncm.cpp 411 hle/service/ncm/ncm.cpp
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 0d4ab95b7..443ca72eb 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -142,10 +142,32 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
142 // Timing 142 // Timing
143 config.wall_clock_cntpct = uses_wall_clock; 143 config.wall_clock_cntpct = uses_wall_clock;
144 144
145 // Optimizations 145 // Safe optimizations
146 if (Settings::values.disable_cpu_opt) { 146 if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) {
147 config.enable_optimizations = false; 147 if (!Settings::values.cpuopt_page_tables) {
148 config.enable_fast_dispatch = false; 148 config.page_table = nullptr;
149 }
150 if (!Settings::values.cpuopt_block_linking) {
151 config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
152 }
153 if (!Settings::values.cpuopt_return_stack_buffer) {
154 config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
155 }
156 if (!Settings::values.cpuopt_fast_dispatcher) {
157 config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
158 }
159 if (!Settings::values.cpuopt_context_elimination) {
160 config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
161 }
162 if (!Settings::values.cpuopt_const_prop) {
163 config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
164 }
165 if (!Settings::values.cpuopt_misc_ir) {
166 config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
167 }
168 if (!Settings::values.cpuopt_reduce_misalign_checks) {
169 config.only_detect_misalignment_via_page_table_on_page_boundary = false;
170 }
149 } 171 }
150 172
151 return std::make_unique<Dynarmic::A32::Jit>(config); 173 return std::make_unique<Dynarmic::A32::Jit>(config);
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 790981034..a63a04a25 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -191,15 +191,37 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
191 // Unpredictable instructions 191 // Unpredictable instructions
192 config.define_unpredictable_behaviour = true; 192 config.define_unpredictable_behaviour = true;
193 193
194 // Optimizations
195 if (Settings::values.disable_cpu_opt) {
196 config.enable_optimizations = false;
197 config.enable_fast_dispatch = false;
198 }
199
200 // Timing 194 // Timing
201 config.wall_clock_cntpct = uses_wall_clock; 195 config.wall_clock_cntpct = uses_wall_clock;
202 196
197 // Safe optimizations
198 if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) {
199 if (!Settings::values.cpuopt_page_tables) {
200 config.page_table = nullptr;
201 }
202 if (!Settings::values.cpuopt_block_linking) {
203 config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
204 }
205 if (!Settings::values.cpuopt_return_stack_buffer) {
206 config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
207 }
208 if (!Settings::values.cpuopt_fast_dispatcher) {
209 config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
210 }
211 if (!Settings::values.cpuopt_context_elimination) {
212 config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
213 }
214 if (!Settings::values.cpuopt_const_prop) {
215 config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
216 }
217 if (!Settings::values.cpuopt_misc_ir) {
218 config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
219 }
220 if (!Settings::values.cpuopt_reduce_misalign_checks) {
221 config.only_detect_misalignment_via_page_table_on_page_boundary = false;
222 }
223 }
224
203 return std::make_shared<Dynarmic::A64::Jit>(config); 225 return std::make_shared<Dynarmic::A64::Jit>(config);
204} 226}
205 227
diff --git a/src/core/constants.h b/src/core/constants.h
index 6d0ec022a..81c5cb279 100644
--- a/src/core/constants.h
+++ b/src/core/constants.h
@@ -4,6 +4,7 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <array>
7#include "common/common_types.h" 8#include "common/common_types.h"
8 9
9// This is to consolidate system-wide constants that are used by multiple components of yuzu. 10// This is to consolidate system-wide constants that are used by multiple components of yuzu.
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h
index 35929ed94..17420c941 100644
--- a/src/core/cpu_manager.h
+++ b/src/core/cpu_manager.h
@@ -9,6 +9,9 @@
9#include <functional> 9#include <functional>
10#include <memory> 10#include <memory>
11#include <thread> 11#include <thread>
12
13#include "common/fiber.h"
14#include "common/thread.h"
12#include "core/hardware_properties.h" 15#include "core/hardware_properties.h"
13 16
14namespace Common { 17namespace Common {
@@ -46,9 +49,9 @@ public:
46 49
47 void Pause(bool paused); 50 void Pause(bool paused);
48 51
49 std::function<void(void*)> GetGuestThreadStartFunc(); 52 static std::function<void(void*)> GetGuestThreadStartFunc();
50 std::function<void(void*)> GetIdleThreadStartFunc(); 53 static std::function<void(void*)> GetIdleThreadStartFunc();
51 std::function<void(void*)> GetSuspendThreadStartFunc(); 54 static std::function<void(void*)> GetSuspendThreadStartFunc();
52 void* GetStartFuncParamater(); 55 void* GetStartFuncParamater();
53 56
54 void PreemptSingleCore(bool from_running_enviroment = true); 57 void PreemptSingleCore(bool from_running_enviroment = true);
@@ -97,7 +100,6 @@ private:
97 bool is_async_gpu{}; 100 bool is_async_gpu{};
98 bool is_multicore{}; 101 bool is_multicore{};
99 std::atomic<std::size_t> current_core{}; 102 std::atomic<std::size_t> current_core{};
100 std::size_t preemption_count{};
101 std::size_t idle_count{}; 103 std::size_t idle_count{};
102 static constexpr std::size_t max_cycle_runs = 5; 104 static constexpr std::size_t max_cycle_runs = 5;
103 105
diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp
index 8935a62c3..285277ef8 100644
--- a/src/core/file_sys/bis_factory.cpp
+++ b/src/core/file_sys/bis_factory.cpp
@@ -12,6 +12,10 @@
12 12
13namespace FileSys { 13namespace FileSys {
14 14
15constexpr u64 NAND_USER_SIZE = 0x680000000; // 26624 MiB
16constexpr u64 NAND_SYSTEM_SIZE = 0xA0000000; // 2560 MiB
17constexpr u64 NAND_TOTAL_SIZE = 0x747C00000; // 29820 MiB
18
15BISFactory::BISFactory(VirtualDir nand_root_, VirtualDir load_root_, VirtualDir dump_root_) 19BISFactory::BISFactory(VirtualDir nand_root_, VirtualDir load_root_, VirtualDir dump_root_)
16 : nand_root(std::move(nand_root_)), load_root(std::move(load_root_)), 20 : nand_root(std::move(nand_root_)), load_root(std::move(load_root_)),
17 dump_root(std::move(dump_root_)), 21 dump_root(std::move(dump_root_)),
@@ -110,30 +114,29 @@ VirtualDir BISFactory::GetImageDirectory() const {
110 114
111u64 BISFactory::GetSystemNANDFreeSpace() const { 115u64 BISFactory::GetSystemNANDFreeSpace() const {
112 const auto sys_dir = GetOrCreateDirectoryRelative(nand_root, "/system"); 116 const auto sys_dir = GetOrCreateDirectoryRelative(nand_root, "/system");
113 if (sys_dir == nullptr) 117 if (sys_dir == nullptr) {
114 return 0; 118 return GetSystemNANDTotalSpace();
119 }
115 120
116 return GetSystemNANDTotalSpace() - sys_dir->GetSize(); 121 return GetSystemNANDTotalSpace() - sys_dir->GetSize();
117} 122}
118 123
119u64 BISFactory::GetSystemNANDTotalSpace() const { 124u64 BISFactory::GetSystemNANDTotalSpace() const {
120 return static_cast<u64>(Settings::values.nand_system_size); 125 return NAND_SYSTEM_SIZE;
121} 126}
122 127
123u64 BISFactory::GetUserNANDFreeSpace() const { 128u64 BISFactory::GetUserNANDFreeSpace() const {
124 const auto usr_dir = GetOrCreateDirectoryRelative(nand_root, "/user"); 129 // For some reason games such as BioShock 1 checks whether this is exactly 0x680000000 bytes.
125 if (usr_dir == nullptr) 130 // Set the free space to be 1 MiB less than the total as a workaround to this issue.
126 return 0; 131 return GetUserNANDTotalSpace() - 0x100000;
127
128 return GetUserNANDTotalSpace() - usr_dir->GetSize();
129} 132}
130 133
131u64 BISFactory::GetUserNANDTotalSpace() const { 134u64 BISFactory::GetUserNANDTotalSpace() const {
132 return static_cast<u64>(Settings::values.nand_user_size); 135 return NAND_USER_SIZE;
133} 136}
134 137
135u64 BISFactory::GetFullNANDTotalSpace() const { 138u64 BISFactory::GetFullNANDTotalSpace() const {
136 return static_cast<u64>(Settings::values.nand_total_size); 139 return NAND_TOTAL_SIZE;
137} 140}
138 141
139VirtualDir BISFactory::GetBCATDirectory(u64 title_id) const { 142VirtualDir BISFactory::GetBCATDirectory(u64 title_id) const {
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 27c1b0233..37351c561 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -547,6 +547,56 @@ InstallResult RegisteredCache::InstallEntry(const XCI& xci, bool overwrite_if_ex
547 return InstallEntry(*xci.GetSecurePartitionNSP(), overwrite_if_exists, copy); 547 return InstallEntry(*xci.GetSecurePartitionNSP(), overwrite_if_exists, copy);
548} 548}
549 549
550bool RegisteredCache::RemoveExistingEntry(u64 title_id) {
551 const auto delete_nca = [this](const NcaID& id) {
552 const auto path = GetRelativePathFromNcaID(id, false, true, false);
553
554 if (dir->GetFileRelative(path) == nullptr) {
555 return false;
556 }
557
558 Core::Crypto::SHA256Hash hash{};
559 mbedtls_sha256_ret(id.data(), id.size(), hash.data(), 0);
560 const auto dirname = fmt::format("000000{:02X}", hash[0]);
561
562 const auto dir2 = GetOrCreateDirectoryRelative(dir, dirname);
563
564 const auto res = dir2->DeleteFile(fmt::format("{}.nca", Common::HexToString(id, false)));
565
566 return res;
567 };
568
569 // If an entry exists in the registered cache, remove it
570 if (HasEntry(title_id, ContentRecordType::Meta)) {
571 LOG_INFO(Loader,
572 "Previously installed entry (v{}) for title_id={:016X} detected! "
573 "Attempting to remove...",
574 GetEntryVersion(title_id).value_or(0), title_id);
575 // Get all the ncas associated with the current CNMT and delete them
576 const auto meta_old_id =
577 GetNcaIDFromMetadata(title_id, ContentRecordType::Meta).value_or(NcaID{});
578 const auto program_id =
579 GetNcaIDFromMetadata(title_id, ContentRecordType::Program).value_or(NcaID{});
580 const auto data_id =
581 GetNcaIDFromMetadata(title_id, ContentRecordType::Data).value_or(NcaID{});
582 const auto control_id =
583 GetNcaIDFromMetadata(title_id, ContentRecordType::Control).value_or(NcaID{});
584 const auto html_id =
585 GetNcaIDFromMetadata(title_id, ContentRecordType::HtmlDocument).value_or(NcaID{});
586 const auto legal_id =
587 GetNcaIDFromMetadata(title_id, ContentRecordType::LegalInformation).value_or(NcaID{});
588
589 delete_nca(meta_old_id);
590 delete_nca(program_id);
591 delete_nca(data_id);
592 delete_nca(control_id);
593 delete_nca(html_id);
594 delete_nca(legal_id);
595 return true;
596 }
597 return false;
598}
599
550InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists, 600InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_exists,
551 const VfsCopyFunction& copy) { 601 const VfsCopyFunction& copy) {
552 const auto ncas = nsp.GetNCAsCollapsed(); 602 const auto ncas = nsp.GetNCAsCollapsed();
@@ -560,31 +610,57 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
560 return InstallResult::ErrorMetaFailed; 610 return InstallResult::ErrorMetaFailed;
561 } 611 }
562 612
563 // Install Metadata File
564 const auto meta_id_raw = (*meta_iter)->GetName().substr(0, 32); 613 const auto meta_id_raw = (*meta_iter)->GetName().substr(0, 32);
565 const auto meta_id = Common::HexStringToArray<16>(meta_id_raw); 614 const auto meta_id = Common::HexStringToArray<16>(meta_id_raw);
566 615
567 const auto res = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id); 616 if ((*meta_iter)->GetSubdirectories().empty()) {
568 if (res != InstallResult::Success) 617 LOG_ERROR(Loader,
569 return res; 618 "The file you are attempting to install does not contain a section0 within the "
619 "metadata NCA and is therefore malformed. Verify that the file is valid.");
620 return InstallResult::ErrorMetaFailed;
621 }
570 622
571 // Install all the other NCAs
572 const auto section0 = (*meta_iter)->GetSubdirectories()[0]; 623 const auto section0 = (*meta_iter)->GetSubdirectories()[0];
624
625 if (section0->GetFiles().empty()) {
626 LOG_ERROR(Loader,
627 "The file you are attempting to install does not contain a CNMT within the "
628 "metadata NCA and is therefore malformed. Verify that the file is valid.");
629 return InstallResult::ErrorMetaFailed;
630 }
631
573 const auto cnmt_file = section0->GetFiles()[0]; 632 const auto cnmt_file = section0->GetFiles()[0];
574 const CNMT cnmt(cnmt_file); 633 const CNMT cnmt(cnmt_file);
634
635 const auto title_id = cnmt.GetTitleID();
636 const auto result = RemoveExistingEntry(title_id);
637
638 // Install Metadata File
639 const auto res = RawInstallNCA(**meta_iter, copy, overwrite_if_exists, meta_id);
640 if (res != InstallResult::Success) {
641 return res;
642 }
643
644 // Install all the other NCAs
575 for (const auto& record : cnmt.GetContentRecords()) { 645 for (const auto& record : cnmt.GetContentRecords()) {
576 // Ignore DeltaFragments, they are not useful to us 646 // Ignore DeltaFragments, they are not useful to us
577 if (record.type == ContentRecordType::DeltaFragment) 647 if (record.type == ContentRecordType::DeltaFragment) {
578 continue; 648 continue;
649 }
579 const auto nca = GetNCAFromNSPForID(nsp, record.nca_id); 650 const auto nca = GetNCAFromNSPForID(nsp, record.nca_id);
580 if (nca == nullptr) 651 if (nca == nullptr) {
581 return InstallResult::ErrorCopyFailed; 652 return InstallResult::ErrorCopyFailed;
653 }
582 const auto res2 = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id); 654 const auto res2 = RawInstallNCA(*nca, copy, overwrite_if_exists, record.nca_id);
583 if (res2 != InstallResult::Success) 655 if (res2 != InstallResult::Success) {
584 return res2; 656 return res2;
657 }
585 } 658 }
586 659
587 Refresh(); 660 Refresh();
661 if (result) {
662 return InstallResult::OverwriteExisting;
663 }
588 return InstallResult::Success; 664 return InstallResult::Success;
589} 665}
590 666
@@ -610,8 +686,9 @@ InstallResult RegisteredCache::InstallEntry(const NCA& nca, TitleType type,
610 mbedtls_sha256_ret(data.data(), data.size(), c_rec.hash.data(), 0); 686 mbedtls_sha256_ret(data.data(), data.size(), c_rec.hash.data(), 0);
611 memcpy(&c_rec.nca_id, &c_rec.hash, 16); 687 memcpy(&c_rec.nca_id, &c_rec.hash, 16);
612 const CNMT new_cnmt(header, opt_header, {c_rec}, {}); 688 const CNMT new_cnmt(header, opt_header, {c_rec}, {});
613 if (!RawInstallYuzuMeta(new_cnmt)) 689 if (!RawInstallYuzuMeta(new_cnmt)) {
614 return InstallResult::ErrorMetaFailed; 690 return InstallResult::ErrorMetaFailed;
691 }
615 return RawInstallNCA(nca, copy, overwrite_if_exists, c_rec.nca_id); 692 return RawInstallNCA(nca, copy, overwrite_if_exists, c_rec.nca_id);
616} 693}
617 694
@@ -649,8 +726,9 @@ InstallResult RegisteredCache::RawInstallNCA(const NCA& nca, const VfsCopyFuncti
649 } 726 }
650 727
651 auto out = dir->CreateFileRelative(path); 728 auto out = dir->CreateFileRelative(path);
652 if (out == nullptr) 729 if (out == nullptr) {
653 return InstallResult::ErrorCopyFailed; 730 return InstallResult::ErrorCopyFailed;
731 }
654 return copy(in, out, VFS_RC_LARGE_COPY_BLOCK) ? InstallResult::Success 732 return copy(in, out, VFS_RC_LARGE_COPY_BLOCK) ? InstallResult::Success
655 : InstallResult::ErrorCopyFailed; 733 : InstallResult::ErrorCopyFailed;
656} 734}
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index f339cd17b..29cf0d40c 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -34,6 +34,7 @@ using VfsCopyFunction = std::function<bool(const VirtualFile&, const VirtualFile
34 34
35enum class InstallResult { 35enum class InstallResult {
36 Success, 36 Success,
37 OverwriteExisting,
37 ErrorAlreadyExists, 38 ErrorAlreadyExists,
38 ErrorCopyFailed, 39 ErrorCopyFailed,
39 ErrorMetaFailed, 40 ErrorMetaFailed,
@@ -154,6 +155,9 @@ public:
154 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {}, 155 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
155 std::optional<u64> title_id = {}) const override; 156 std::optional<u64> title_id = {}) const override;
156 157
158 // Removes an existing entry based on title id
159 bool RemoveExistingEntry(u64 title_id);
160
157 // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure 161 // Raw copies all the ncas from the xci/nsp to the csache. Does some quick checks to make sure
158 // there is a meta NCA and all of them are accessible. 162 // there is a meta NCA and all of them are accessible.
159 InstallResult InstallEntry(const XCI& xci, bool overwrite_if_exists = false, 163 InstallResult InstallEntry(const XCI& xci, bool overwrite_if_exists = false,
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp
index 5113a1ca6..6f732e4d8 100644
--- a/src/core/file_sys/sdmc_factory.cpp
+++ b/src/core/file_sys/sdmc_factory.cpp
@@ -10,6 +10,8 @@
10 10
11namespace FileSys { 11namespace FileSys {
12 12
13constexpr u64 SDMC_TOTAL_SIZE = 0x10000000000; // 1 TiB
14
13SDMCFactory::SDMCFactory(VirtualDir dir_) 15SDMCFactory::SDMCFactory(VirtualDir dir_)
14 : dir(std::move(dir_)), contents(std::make_unique<RegisteredCache>( 16 : dir(std::move(dir_)), contents(std::make_unique<RegisteredCache>(
15 GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/registered"), 17 GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/registered"),
@@ -46,7 +48,7 @@ u64 SDMCFactory::GetSDMCFreeSpace() const {
46} 48}
47 49
48u64 SDMCFactory::GetSDMCTotalSpace() const { 50u64 SDMCFactory::GetSDMCTotalSpace() const {
49 return static_cast<u64>(Settings::values.sdmc_size); 51 return SDMC_TOTAL_SIZE;
50} 52}
51 53
52} // namespace FileSys 54} // namespace FileSys
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 4d2a9b35d..df0debe1b 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -24,7 +24,6 @@ namespace Kernel {
24// Wake up num_to_wake (or all) threads in a vector. 24// Wake up num_to_wake (or all) threads in a vector.
25void AddressArbiter::WakeThreads(const std::vector<std::shared_ptr<Thread>>& waiting_threads, 25void AddressArbiter::WakeThreads(const std::vector<std::shared_ptr<Thread>>& waiting_threads,
26 s32 num_to_wake) { 26 s32 num_to_wake) {
27 auto& time_manager = system.Kernel().TimeManager();
28 // Only process up to 'target' threads, unless 'target' is <= 0, in which case process 27 // Only process up to 'target' threads, unless 'target' is <= 0, in which case process
29 // them all. 28 // them all.
30 std::size_t last = waiting_threads.size(); 29 std::size_t last = waiting_threads.size();
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp
index 35448b576..fb30b6f8b 100644
--- a/src/core/hle/kernel/handle_table.cpp
+++ b/src/core/hle/kernel/handle_table.cpp
@@ -8,7 +8,9 @@
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/kernel/errors.h" 9#include "core/hle/kernel/errors.h"
10#include "core/hle/kernel/handle_table.h" 10#include "core/hle/kernel/handle_table.h"
11#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/process.h" 12#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/scheduler.h"
12#include "core/hle/kernel/thread.h" 14#include "core/hle/kernel/thread.h"
13 15
14namespace Kernel { 16namespace Kernel {
@@ -22,7 +24,7 @@ constexpr u16 GetGeneration(Handle handle) {
22} 24}
23} // Anonymous namespace 25} // Anonymous namespace
24 26
25HandleTable::HandleTable() { 27HandleTable::HandleTable(KernelCore& kernel) : kernel{kernel} {
26 Clear(); 28 Clear();
27} 29}
28 30
@@ -103,9 +105,9 @@ bool HandleTable::IsValid(Handle handle) const {
103 105
104std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const { 106std::shared_ptr<Object> HandleTable::GetGeneric(Handle handle) const {
105 if (handle == CurrentThread) { 107 if (handle == CurrentThread) {
106 return SharedFrom(GetCurrentThread()); 108 return SharedFrom(kernel.CurrentScheduler().GetCurrentThread());
107 } else if (handle == CurrentProcess) { 109 } else if (handle == CurrentProcess) {
108 return SharedFrom(Core::System::GetInstance().CurrentProcess()); 110 return SharedFrom(kernel.CurrentProcess());
109 } 111 }
110 112
111 if (!IsValid(handle)) { 113 if (!IsValid(handle)) {
diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h
index 8029660ed..c9dab8cdd 100644
--- a/src/core/hle/kernel/handle_table.h
+++ b/src/core/hle/kernel/handle_table.h
@@ -14,6 +14,8 @@
14 14
15namespace Kernel { 15namespace Kernel {
16 16
17class KernelCore;
18
17enum KernelHandle : Handle { 19enum KernelHandle : Handle {
18 InvalidHandle = 0, 20 InvalidHandle = 0,
19 CurrentThread = 0xFFFF8000, 21 CurrentThread = 0xFFFF8000,
@@ -48,7 +50,7 @@ public:
48 /// This is the maximum limit of handles allowed per process in Horizon 50 /// This is the maximum limit of handles allowed per process in Horizon
49 static constexpr std::size_t MAX_COUNT = 1024; 51 static constexpr std::size_t MAX_COUNT = 1024;
50 52
51 HandleTable(); 53 explicit HandleTable(KernelCore& kernel);
52 ~HandleTable(); 54 ~HandleTable();
53 55
54 /** 56 /**
@@ -134,6 +136,9 @@ private:
134 136
135 /// Head of the free slots linked list. 137 /// Head of the free slots linked list.
136 u16 next_free_slot = 0; 138 u16 next_free_slot = 0;
139
140 /// Underlying kernel instance that this handle table operates under.
141 KernelCore& kernel;
137}; 142};
138 143
139} // namespace Kernel 144} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 1f2af7a1b..e1c7a0f3b 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -50,7 +50,8 @@ namespace Kernel {
50 50
51struct KernelCore::Impl { 51struct KernelCore::Impl {
52 explicit Impl(Core::System& system, KernelCore& kernel) 52 explicit Impl(Core::System& system, KernelCore& kernel)
53 : global_scheduler{kernel}, synchronization{system}, time_manager{system}, system{system} {} 53 : global_scheduler{kernel}, synchronization{system}, time_manager{system},
54 global_handle_table{kernel}, system{system} {}
54 55
55 void SetMulticore(bool is_multicore) { 56 void SetMulticore(bool is_multicore) {
56 this->is_multicore = is_multicore; 57 this->is_multicore = is_multicore;
@@ -160,13 +161,14 @@ struct KernelCore::Impl {
160 void InitializeSuspendThreads() { 161 void InitializeSuspendThreads() {
161 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { 162 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
162 std::string name = "Suspend Thread Id:" + std::to_string(i); 163 std::string name = "Suspend Thread Id:" + std::to_string(i);
163 std::function<void(void*)> init_func = 164 std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc();
164 system.GetCpuManager().GetSuspendThreadStartFunc();
165 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); 165 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
166 ThreadType type = 166 const auto type =
167 static_cast<ThreadType>(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_SUSPEND); 167 static_cast<ThreadType>(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_SUSPEND);
168 auto thread_res = Thread::Create(system, type, name, 0, 0, 0, static_cast<u32>(i), 0, 168 auto thread_res =
169 nullptr, std::move(init_func), init_func_parameter); 169 Thread::Create(system, type, std::move(name), 0, 0, 0, static_cast<u32>(i), 0,
170 nullptr, std::move(init_func), init_func_parameter);
171
170 suspend_threads[i] = std::move(thread_res).Unwrap(); 172 suspend_threads[i] = std::move(thread_res).Unwrap();
171 } 173 }
172 } 174 }
@@ -307,7 +309,7 @@ struct KernelCore::Impl {
307 309
308 // This is the kernel's handle table or supervisor handle table which 310 // This is the kernel's handle table or supervisor handle table which
309 // stores all the objects in place. 311 // stores all the objects in place.
310 Kernel::HandleTable global_handle_table; 312 HandleTable global_handle_table;
311 313
312 /// Map of named ports managed by the kernel, which can be retrieved using 314 /// Map of named ports managed by the kernel, which can be retrieved using
313 /// the ConnectToPort SVC. 315 /// the ConnectToPort SVC.
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 49bd47e89..16285c3f0 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -9,6 +9,7 @@
9#include <string> 9#include <string>
10#include <unordered_map> 10#include <unordered_map>
11#include <vector> 11#include <vector>
12#include "core/arm/cpu_interrupt_handler.h"
12#include "core/hardware_properties.h" 13#include "core/hardware_properties.h"
13#include "core/hle/kernel/memory/memory_types.h" 14#include "core/hle/kernel/memory/memory_types.h"
14#include "core/hle/kernel/object.h" 15#include "core/hle/kernel/object.h"
diff --git a/src/core/hle/kernel/memory/address_space_info.cpp b/src/core/hle/kernel/memory/address_space_info.cpp
index a523a2502..e4288cab4 100644
--- a/src/core/hle/kernel/memory/address_space_info.cpp
+++ b/src/core/hle/kernel/memory/address_space_info.cpp
@@ -29,40 +29,39 @@ enum : u64 {
29 29
30// clang-format off 30// clang-format off
31constexpr std::array<AddressSpaceInfo, 13> AddressSpaceInfos{{ 31constexpr std::array<AddressSpaceInfo, 13> AddressSpaceInfos{{
32 { 32 /*bit_width*/, Size_2_MB /*addr*/, Size_1_GB - Size_2_MB /*size*/, AddressSpaceInfo::Type::Is32Bit, }, 32 { .bit_width = 32, .address = Size_2_MB , .size = Size_1_GB - Size_2_MB , .type = AddressSpaceInfo::Type::Is32Bit, },
33 { 32 /*bit_width*/, Size_1_GB /*addr*/, Size_4_GB - Size_1_GB /*size*/, AddressSpaceInfo::Type::Small64Bit, }, 33 { .bit_width = 32, .address = Size_1_GB , .size = Size_4_GB - Size_1_GB , .type = AddressSpaceInfo::Type::Small64Bit, },
34 { 32 /*bit_width*/, Invalid /*addr*/, Size_1_GB /*size*/, AddressSpaceInfo::Type::Heap, }, 34 { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = AddressSpaceInfo::Type::Heap, },
35 { 32 /*bit_width*/, Invalid /*addr*/, Size_1_GB /*size*/, AddressSpaceInfo::Type::Alias, }, 35 { .bit_width = 32, .address = Invalid , .size = Size_1_GB , .type = AddressSpaceInfo::Type::Alias, },
36 { 36 /*bit_width*/, Size_128_MB /*addr*/, Size_2_GB - Size_128_MB /*size*/, AddressSpaceInfo::Type::Is32Bit, }, 36 { .bit_width = 36, .address = Size_128_MB, .size = Size_2_GB - Size_128_MB, .type = AddressSpaceInfo::Type::Is32Bit, },
37 { 36 /*bit_width*/, Size_2_GB /*addr*/, Size_64_GB - Size_2_GB /*size*/, AddressSpaceInfo::Type::Small64Bit, }, 37 { .bit_width = 36, .address = Size_2_GB , .size = Size_64_GB - Size_2_GB , .type = AddressSpaceInfo::Type::Small64Bit, },
38 { 36 /*bit_width*/, Invalid /*addr*/, Size_6_GB /*size*/, AddressSpaceInfo::Type::Heap, }, 38 { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = AddressSpaceInfo::Type::Heap, },
39 { 36 /*bit_width*/, Invalid /*addr*/, Size_6_GB /*size*/, AddressSpaceInfo::Type::Alias, }, 39 { .bit_width = 36, .address = Invalid , .size = Size_6_GB , .type = AddressSpaceInfo::Type::Alias, },
40 { 39 /*bit_width*/, Size_128_MB /*addr*/, Size_512_GB - Size_128_MB /*size*/, AddressSpaceInfo::Type::Large64Bit, }, 40 { .bit_width = 39, .address = Size_128_MB, .size = Size_512_GB - Size_128_MB, .type = AddressSpaceInfo::Type::Large64Bit, },
41 { 39 /*bit_width*/, Invalid /*addr*/, Size_64_GB /*size*/, AddressSpaceInfo::Type::Is32Bit }, 41 { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = AddressSpaceInfo::Type::Is32Bit },
42 { 39 /*bit_width*/, Invalid /*addr*/, Size_6_GB /*size*/, AddressSpaceInfo::Type::Heap, }, 42 { .bit_width = 39, .address = Invalid , .size = Size_6_GB , .type = AddressSpaceInfo::Type::Heap, },
43 { 39 /*bit_width*/, Invalid /*addr*/, Size_64_GB /*size*/, AddressSpaceInfo::Type::Alias, }, 43 { .bit_width = 39, .address = Invalid , .size = Size_64_GB , .type = AddressSpaceInfo::Type::Alias, },
44 { 39 /*bit_width*/, Invalid /*addr*/, Size_2_GB /*size*/, AddressSpaceInfo::Type::Stack, }, 44 { .bit_width = 39, .address = Invalid , .size = Size_2_GB , .type = AddressSpaceInfo::Type::Stack, },
45}}; 45}};
46// clang-format on 46// clang-format on
47 47
48constexpr bool IsAllowedIndexForAddress(std::size_t index) { 48constexpr bool IsAllowedIndexForAddress(std::size_t index) {
49 return index < std::size(AddressSpaceInfos) && AddressSpaceInfos[index].GetAddress() != Invalid; 49 return index < AddressSpaceInfos.size() && AddressSpaceInfos[index].address != Invalid;
50} 50}
51 51
52constexpr std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)> 52using IndexArray = std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)>;
53 AddressSpaceIndices32Bit{
54 0, 1, 0, 2, 0, 3,
55 };
56 53
57constexpr std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)> 54constexpr IndexArray AddressSpaceIndices32Bit{
58 AddressSpaceIndices36Bit{ 55 0, 1, 0, 2, 0, 3,
59 4, 5, 4, 6, 4, 7, 56};
60 }; 57
58constexpr IndexArray AddressSpaceIndices36Bit{
59 4, 5, 4, 6, 4, 7,
60};
61 61
62constexpr std::array<std::size_t, static_cast<std::size_t>(AddressSpaceInfo::Type::Count)> 62constexpr IndexArray AddressSpaceIndices39Bit{
63 AddressSpaceIndices39Bit{ 63 9, 8, 8, 10, 12, 11,
64 9, 8, 8, 10, 12, 11, 64};
65 };
66 65
67constexpr bool IsAllowed32BitType(AddressSpaceInfo::Type type) { 66constexpr bool IsAllowed32BitType(AddressSpaceInfo::Type type) {
68 return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Large64Bit && 67 return type < AddressSpaceInfo::Type::Count && type != AddressSpaceInfo::Type::Large64Bit &&
@@ -80,37 +79,37 @@ constexpr bool IsAllowed39BitType(AddressSpaceInfo::Type type) {
80 79
81} // namespace 80} // namespace
82 81
83u64 AddressSpaceInfo::GetAddressSpaceStart(std::size_t width, AddressSpaceInfo::Type type) { 82u64 AddressSpaceInfo::GetAddressSpaceStart(std::size_t width, Type type) {
84 const std::size_t index{static_cast<std::size_t>(type)}; 83 const std::size_t index{static_cast<std::size_t>(type)};
85 switch (width) { 84 switch (width) {
86 case 32: 85 case 32:
87 ASSERT(IsAllowed32BitType(type)); 86 ASSERT(IsAllowed32BitType(type));
88 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices32Bit[index])); 87 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices32Bit[index]));
89 return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].GetAddress(); 88 return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].address;
90 case 36: 89 case 36:
91 ASSERT(IsAllowed36BitType(type)); 90 ASSERT(IsAllowed36BitType(type));
92 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices36Bit[index])); 91 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices36Bit[index]));
93 return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].GetAddress(); 92 return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].address;
94 case 39: 93 case 39:
95 ASSERT(IsAllowed39BitType(type)); 94 ASSERT(IsAllowed39BitType(type));
96 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices39Bit[index])); 95 ASSERT(IsAllowedIndexForAddress(AddressSpaceIndices39Bit[index]));
97 return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].GetAddress(); 96 return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].address;
98 } 97 }
99 UNREACHABLE(); 98 UNREACHABLE();
100} 99}
101 100
102std::size_t AddressSpaceInfo::GetAddressSpaceSize(std::size_t width, AddressSpaceInfo::Type type) { 101std::size_t AddressSpaceInfo::GetAddressSpaceSize(std::size_t width, Type type) {
103 const std::size_t index{static_cast<std::size_t>(type)}; 102 const std::size_t index{static_cast<std::size_t>(type)};
104 switch (width) { 103 switch (width) {
105 case 32: 104 case 32:
106 ASSERT(IsAllowed32BitType(type)); 105 ASSERT(IsAllowed32BitType(type));
107 return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].GetSize(); 106 return AddressSpaceInfos[AddressSpaceIndices32Bit[index]].size;
108 case 36: 107 case 36:
109 ASSERT(IsAllowed36BitType(type)); 108 ASSERT(IsAllowed36BitType(type));
110 return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].GetSize(); 109 return AddressSpaceInfos[AddressSpaceIndices36Bit[index]].size;
111 case 39: 110 case 39:
112 ASSERT(IsAllowed39BitType(type)); 111 ASSERT(IsAllowed39BitType(type));
113 return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].GetSize(); 112 return AddressSpaceInfos[AddressSpaceIndices39Bit[index]].size;
114 } 113 }
115 UNREACHABLE(); 114 UNREACHABLE();
116} 115}
diff --git a/src/core/hle/kernel/memory/address_space_info.h b/src/core/hle/kernel/memory/address_space_info.h
index c479890be..a4e6e91e5 100644
--- a/src/core/hle/kernel/memory/address_space_info.h
+++ b/src/core/hle/kernel/memory/address_space_info.h
@@ -11,8 +11,7 @@
11 11
12namespace Kernel::Memory { 12namespace Kernel::Memory {
13 13
14class AddressSpaceInfo final : NonCopyable { 14struct AddressSpaceInfo final {
15public:
16 enum class Type : u32 { 15 enum class Type : u32 {
17 Is32Bit = 0, 16 Is32Bit = 0,
18 Small64Bit = 1, 17 Small64Bit = 1,
@@ -23,31 +22,13 @@ public:
23 Count, 22 Count,
24 }; 23 };
25 24
26private:
27 std::size_t bit_width{};
28 std::size_t addr{};
29 std::size_t size{};
30 Type type{};
31
32public:
33 static u64 GetAddressSpaceStart(std::size_t width, Type type); 25 static u64 GetAddressSpaceStart(std::size_t width, Type type);
34 static std::size_t GetAddressSpaceSize(std::size_t width, Type type); 26 static std::size_t GetAddressSpaceSize(std::size_t width, Type type);
35 27
36 constexpr AddressSpaceInfo(std::size_t bit_width, std::size_t addr, std::size_t size, Type type) 28 const std::size_t bit_width{};
37 : bit_width{bit_width}, addr{addr}, size{size}, type{type} {} 29 const std::size_t address{};
38 30 const std::size_t size{};
39 constexpr std::size_t GetWidth() const { 31 const Type type{};
40 return bit_width;
41 }
42 constexpr std::size_t GetAddress() const {
43 return addr;
44 }
45 constexpr std::size_t GetSize() const {
46 return size;
47 }
48 constexpr Type GetType() const {
49 return type;
50 }
51}; 32};
52 33
53} // namespace Kernel::Memory 34} // namespace Kernel::Memory
diff --git a/src/core/hle/kernel/memory/memory_layout.h b/src/core/hle/kernel/memory/memory_layout.h
index 830c6f0d7..9b3d6267a 100644
--- a/src/core/hle/kernel/memory/memory_layout.h
+++ b/src/core/hle/kernel/memory/memory_layout.h
@@ -66,8 +66,6 @@ private:
66 const MemoryRegion application; 66 const MemoryRegion application;
67 const MemoryRegion applet; 67 const MemoryRegion applet;
68 const MemoryRegion system; 68 const MemoryRegion system;
69
70 const PAddr start_address{};
71}; 69};
72 70
73} // namespace Kernel::Memory 71} // namespace Kernel::Memory
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index c6fcb56ad..ff9d9248b 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -408,7 +408,7 @@ void Process::LoadModule(CodeSet code_set, VAddr base_addr) {
408Process::Process(Core::System& system) 408Process::Process(Core::System& system)
409 : SynchronizationObject{system.Kernel()}, page_table{std::make_unique<Memory::PageTable>( 409 : SynchronizationObject{system.Kernel()}, page_table{std::make_unique<Memory::PageTable>(
410 system)}, 410 system)},
411 address_arbiter{system}, mutex{system}, system{system} {} 411 handle_table{system.Kernel()}, address_arbiter{system}, mutex{system}, system{system} {}
412 412
413Process::~Process() = default; 413Process::~Process() = default;
414 414
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 9dabe3568..f45cb5674 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -382,12 +382,6 @@ private:
382 /// List of threads waiting for a condition variable 382 /// List of threads waiting for a condition variable
383 std::unordered_map<VAddr, std::list<std::shared_ptr<Thread>>> cond_var_threads; 383 std::unordered_map<VAddr, std::list<std::shared_ptr<Thread>>> cond_var_threads;
384 384
385 /// System context
386 Core::System& system;
387
388 /// Name of this process
389 std::string name;
390
391 /// Address of the top of the main thread's stack 385 /// Address of the top of the main thread's stack
392 VAddr main_thread_stack_top{}; 386 VAddr main_thread_stack_top{};
393 387
@@ -399,6 +393,12 @@ private:
399 393
400 /// Process total image size 394 /// Process total image size
401 std::size_t image_size{}; 395 std::size_t image_size{};
396
397 /// Name of this process
398 std::string name;
399
400 /// System context
401 Core::System& system;
402}; 402};
403 403
404} // namespace Kernel 404} // namespace Kernel
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 7b929781c..f93e5e4b0 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -802,7 +802,7 @@ void Scheduler::UpdateLastContextSwitchTime(Thread* thread, Process* process) {
802 802
803void Scheduler::Initialize() { 803void Scheduler::Initialize() {
804 std::string name = "Idle Thread Id:" + std::to_string(core_id); 804 std::string name = "Idle Thread Id:" + std::to_string(core_id);
805 std::function<void(void*)> init_func = system.GetCpuManager().GetIdleThreadStartFunc(); 805 std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc();
806 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); 806 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
807 ThreadType type = static_cast<ThreadType>(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_IDLE); 807 ThreadType type = static_cast<ThreadType>(THREADTYPE_KERNEL | THREADTYPE_HLE | THREADTYPE_IDLE);
808 auto thread_res = Thread::Create(system, type, name, 0, 64, 0, static_cast<u32>(core_id), 0, 808 auto thread_res = Thread::Create(system, type, name, 0, 64, 0, static_cast<u32>(core_id), 0,
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 5db19dcf3..01ae57053 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -458,9 +458,7 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr
458 return ERR_OUT_OF_RANGE; 458 return ERR_OUT_OF_RANGE;
459 } 459 }
460 460
461 auto* const thread = system.CurrentScheduler().GetCurrentThread();
462 auto& kernel = system.Kernel(); 461 auto& kernel = system.Kernel();
463 using ObjectPtr = Thread::ThreadSynchronizationObjects::value_type;
464 Thread::ThreadSynchronizationObjects objects(handle_count); 462 Thread::ThreadSynchronizationObjects objects(handle_count);
465 const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); 463 const auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
466 464
@@ -1750,9 +1748,9 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_
1750 // Only process up to 'target' threads, unless 'target' is less equal 0, in which case process 1748 // Only process up to 'target' threads, unless 'target' is less equal 0, in which case process
1751 // them all. 1749 // them all.
1752 std::size_t last = waiting_threads.size(); 1750 std::size_t last = waiting_threads.size();
1753 if (target > 0) 1751 if (target > 0) {
1754 last = std::min(waiting_threads.size(), static_cast<std::size_t>(target)); 1752 last = std::min(waiting_threads.size(), static_cast<std::size_t>(target));
1755 auto& time_manager = kernel.TimeManager(); 1753 }
1756 for (std::size_t index = 0; index < last; ++index) { 1754 for (std::size_t index = 0; index < last; ++index) {
1757 auto& thread = waiting_threads[index]; 1755 auto& thread = waiting_threads[index];
1758 1756
@@ -1763,7 +1761,6 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_
1763 1761
1764 const std::size_t current_core = system.CurrentCoreIndex(); 1762 const std::size_t current_core = system.CurrentCoreIndex();
1765 auto& monitor = system.Monitor(); 1763 auto& monitor = system.Monitor();
1766 auto& memory = system.Memory();
1767 1764
1768 // Atomically read the value of the mutex. 1765 // Atomically read the value of the mutex.
1769 u32 mutex_val = 0; 1766 u32 mutex_val = 0;
diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp
index 851b702a5..8b875d853 100644
--- a/src/core/hle/kernel/synchronization.cpp
+++ b/src/core/hle/kernel/synchronization.cpp
@@ -19,7 +19,6 @@ Synchronization::Synchronization(Core::System& system) : system{system} {}
19void Synchronization::SignalObject(SynchronizationObject& obj) const { 19void Synchronization::SignalObject(SynchronizationObject& obj) const {
20 auto& kernel = system.Kernel(); 20 auto& kernel = system.Kernel();
21 SchedulerLock lock(kernel); 21 SchedulerLock lock(kernel);
22 auto& time_manager = kernel.TimeManager();
23 if (obj.IsSignaled()) { 22 if (obj.IsSignaled()) {
24 for (auto thread : obj.GetWaitingThreads()) { 23 for (auto thread : obj.GetWaitingThreads()) {
25 if (thread->GetSchedulingStatus() == ThreadSchedStatus::Paused) { 24 if (thread->GetSchedulingStatus() == ThreadSchedStatus::Paused) {
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 2b1092697..d132aba34 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -13,16 +13,8 @@
13#include "common/logging/log.h" 13#include "common/logging/log.h"
14#include "common/thread_queue_list.h" 14#include "common/thread_queue_list.h"
15#include "core/arm/arm_interface.h" 15#include "core/arm/arm_interface.h"
16#ifdef ARCHITECTURE_x86_64
17#include "core/arm/dynarmic/arm_dynarmic_32.h"
18#include "core/arm/dynarmic/arm_dynarmic_64.h"
19#endif
20#include "core/arm/cpu_interrupt_handler.h"
21#include "core/arm/exclusive_monitor.h"
22#include "core/arm/unicorn/arm_unicorn.h" 16#include "core/arm/unicorn/arm_unicorn.h"
23#include "core/core.h" 17#include "core/core.h"
24#include "core/core_timing.h"
25#include "core/core_timing_util.h"
26#include "core/cpu_manager.h" 18#include "core/cpu_manager.h"
27#include "core/hardware_properties.h" 19#include "core/hardware_properties.h"
28#include "core/hle/kernel/errors.h" 20#include "core/hle/kernel/errors.h"
@@ -36,6 +28,11 @@
36#include "core/hle/result.h" 28#include "core/hle/result.h"
37#include "core/memory.h" 29#include "core/memory.h"
38 30
31#ifdef ARCHITECTURE_x86_64
32#include "core/arm/dynarmic/arm_dynarmic_32.h"
33#include "core/arm/dynarmic/arm_dynarmic_64.h"
34#endif
35
39namespace Kernel { 36namespace Kernel {
40 37
41bool Thread::ShouldWait(const Thread* thread) const { 38bool Thread::ShouldWait(const Thread* thread) const {
@@ -158,7 +155,7 @@ ResultVal<std::shared_ptr<Thread>> Thread::Create(Core::System& system, ThreadTy
158 std::string name, VAddr entry_point, u32 priority, 155 std::string name, VAddr entry_point, u32 priority,
159 u64 arg, s32 processor_id, VAddr stack_top, 156 u64 arg, s32 processor_id, VAddr stack_top,
160 Process* owner_process) { 157 Process* owner_process) {
161 std::function<void(void*)> init_func = system.GetCpuManager().GetGuestThreadStartFunc(); 158 std::function<void(void*)> init_func = Core::CpuManager::GetGuestThreadStartFunc();
162 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); 159 void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
163 return Create(system, type_flags, name, entry_point, priority, arg, processor_id, stack_top, 160 return Create(system, type_flags, name, entry_point, priority, arg, processor_id, stack_top,
164 owner_process, std::move(init_func), init_func_parameter); 161 owner_process, std::move(init_func), init_func_parameter);
@@ -540,13 +537,4 @@ ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) {
540 return RESULT_SUCCESS; 537 return RESULT_SUCCESS;
541} 538}
542 539
543////////////////////////////////////////////////////////////////////////////////////////////////////
544
545/**
546 * Gets the current thread
547 */
548Thread* GetCurrentThread() {
549 return Core::System::GetInstance().CurrentScheduler().GetCurrentThread();
550}
551
552} // namespace Kernel 540} // namespace Kernel
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index c0342c462..8daf79fac 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -583,8 +583,6 @@ private:
583 583
584 void SetCurrentPriority(u32 new_priority); 584 void SetCurrentPriority(u32 new_priority);
585 585
586 void AdjustSchedulingOnAffinity(u64 old_affinity_mask, s32 old_core);
587
588 Common::SpinLock context_guard{}; 586 Common::SpinLock context_guard{};
589 ThreadContext32 context_32{}; 587 ThreadContext32 context_32{};
590 ThreadContext64 context_64{}; 588 ThreadContext64 context_64{};
@@ -680,9 +678,4 @@ private:
680 std::string name; 678 std::string name;
681}; 679};
682 680
683/**
684 * Gets the current thread
685 */
686Thread* GetCurrentThread();
687
688} // namespace Kernel 681} // namespace Kernel
diff --git a/src/core/hle/service/mii/manager.cpp b/src/core/hle/service/mii/manager.cpp
new file mode 100644
index 000000000..4a1d1182e
--- /dev/null
+++ b/src/core/hle/service/mii/manager.cpp
@@ -0,0 +1,483 @@
1// Copyright 2020 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <cstring>
6#include <random>
7
8#include "common/assert.h"
9#include "common/file_util.h"
10#include "common/logging/log.h"
11#include "common/string_util.h"
12
13#include "core/hle/service/acc/profile_manager.h"
14#include "core/hle/service/mii/manager.h"
15#include "core/hle/service/mii/raw_data.h"
16#include "core/hle/service/mii/types.h"
17
18namespace Service::Mii {
19
20namespace {
21
22constexpr ResultCode ERROR_CANNOT_FIND_ENTRY{ErrorModule::Mii, 4};
23
24constexpr std::size_t DefaultMiiCount{sizeof(RawData::DefaultMii) / sizeof(DefaultMii)};
25
26constexpr MiiStoreData::Name DefaultMiiName{u'y', u'u', u'z', u'u'};
27constexpr std::array<u8, 8> HairColorLookup{8, 1, 2, 3, 4, 5, 6, 7};
28constexpr std::array<u8, 6> EyeColorLookup{8, 9, 10, 11, 12, 13};
29constexpr std::array<u8, 5> MouthColorLookup{19, 20, 21, 22, 23};
30constexpr std::array<u8, 7> GlassesColorLookup{8, 14, 15, 16, 17, 18, 0};
31constexpr std::array<u8, 62> EyeRotateLookup{
32 {0x03, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x04,
33 0x04, 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x03, 0x03, 0x04, 0x03, 0x04, 0x04, 0x03, 0x04, 0x04,
34 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03,
35 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x03, 0x04, 0x04}};
36constexpr std::array<u8, 24> EyebrowRotateLookup{{0x06, 0x06, 0x05, 0x07, 0x06, 0x07, 0x06, 0x07,
37 0x04, 0x07, 0x06, 0x08, 0x05, 0x05, 0x06, 0x06,
38 0x07, 0x07, 0x06, 0x06, 0x05, 0x06, 0x07, 0x05}};
39
40template <typename T, std::size_t SourceArraySize, std::size_t DestArraySize>
41std::array<T, DestArraySize> ResizeArray(const std::array<T, SourceArraySize>& in) {
42 std::array<T, DestArraySize> out{};
43 std::memcpy(out.data(), in.data(), sizeof(T) * std::min(SourceArraySize, DestArraySize));
44 return out;
45}
46
47MiiInfo ConvertStoreDataToInfo(const MiiStoreData& data) {
48 MiiStoreBitFields bf;
49 std::memcpy(&bf, data.data.data.data(), sizeof(MiiStoreBitFields));
50 MiiInfo info{};
51 info.name = ResizeArray<char16_t, 10, 11>(data.data.name);
52 info.uuid = data.data.uuid;
53 info.font_region = static_cast<u8>(bf.font_region.Value());
54 info.favorite_color = static_cast<u8>(bf.favorite_color.Value());
55 info.gender = static_cast<u8>(bf.gender.Value());
56 info.height = static_cast<u8>(bf.height.Value());
57 info.build = static_cast<u8>(bf.build.Value());
58 info.type = static_cast<u8>(bf.type.Value());
59 info.region_move = static_cast<u8>(bf.region_move.Value());
60 info.faceline_type = static_cast<u8>(bf.faceline_type.Value());
61 info.faceline_color = static_cast<u8>(bf.faceline_color.Value());
62 info.faceline_wrinkle = static_cast<u8>(bf.faceline_wrinkle.Value());
63 info.faceline_make = static_cast<u8>(bf.faceline_makeup.Value());
64 info.hair_type = static_cast<u8>(bf.hair_type.Value());
65 info.hair_color = static_cast<u8>(bf.hair_color.Value());
66 info.hair_flip = static_cast<u8>(bf.hair_flip.Value());
67 info.eye_type = static_cast<u8>(bf.eye_type.Value());
68 info.eye_color = static_cast<u8>(bf.eye_color.Value());
69 info.eye_scale = static_cast<u8>(bf.eye_scale.Value());
70 info.eye_aspect = static_cast<u8>(bf.eye_aspect.Value());
71 info.eye_rotate = static_cast<u8>(bf.eye_rotate.Value());
72 info.eye_x = static_cast<u8>(bf.eye_x.Value());
73 info.eye_y = static_cast<u8>(bf.eye_y.Value());
74 info.eyebrow_type = static_cast<u8>(bf.eyebrow_type.Value());
75 info.eyebrow_color = static_cast<u8>(bf.eyebrow_color.Value());
76 info.eyebrow_scale = static_cast<u8>(bf.eyebrow_scale.Value());
77 info.eyebrow_aspect = static_cast<u8>(bf.eyebrow_aspect.Value());
78 info.eyebrow_rotate = static_cast<u8>(bf.eyebrow_rotate.Value());
79 info.eyebrow_x = static_cast<u8>(bf.eyebrow_x.Value());
80 info.eyebrow_y = static_cast<u8>(bf.eyebrow_y.Value() + 3);
81 info.nose_type = static_cast<u8>(bf.nose_type.Value());
82 info.nose_scale = static_cast<u8>(bf.nose_scale.Value());
83 info.nose_y = static_cast<u8>(bf.nose_y.Value());
84 info.mouth_type = static_cast<u8>(bf.mouth_type.Value());
85 info.mouth_color = static_cast<u8>(bf.mouth_color.Value());
86 info.mouth_scale = static_cast<u8>(bf.mouth_scale.Value());
87 info.mouth_aspect = static_cast<u8>(bf.mouth_aspect.Value());
88 info.mouth_y = static_cast<u8>(bf.mouth_y.Value());
89 info.beard_color = static_cast<u8>(bf.beard_color.Value());
90 info.beard_type = static_cast<u8>(bf.beard_type.Value());
91 info.mustache_type = static_cast<u8>(bf.mustache_type.Value());
92 info.mustache_scale = static_cast<u8>(bf.mustache_scale.Value());
93 info.mustache_y = static_cast<u8>(bf.mustache_y.Value());
94 info.glasses_type = static_cast<u8>(bf.glasses_type.Value());
95 info.glasses_color = static_cast<u8>(bf.glasses_color.Value());
96 info.glasses_scale = static_cast<u8>(bf.glasses_scale.Value());
97 info.glasses_y = static_cast<u8>(bf.glasses_y.Value());
98 info.mole_type = static_cast<u8>(bf.mole_type.Value());
99 info.mole_scale = static_cast<u8>(bf.mole_scale.Value());
100 info.mole_x = static_cast<u8>(bf.mole_x.Value());
101 info.mole_y = static_cast<u8>(bf.mole_y.Value());
102 return info;
103}
104
105u16 GenerateCrc16(const void* data, std::size_t size) {
106 s32 crc{};
107 for (int i = 0; i < size; i++) {
108 crc ^= reinterpret_cast<const u8*>(data)[i] << 8;
109 for (int j = 0; j < 8; j++) {
110 crc <<= 1;
111 if ((crc & 0x10000) != 0) {
112 crc = (crc ^ 0x1021) & 0xFFFF;
113 }
114 }
115 }
116 return Common::swap16(static_cast<u16>(crc));
117}
118
119Common::UUID GenerateValidUUID() {
120 auto uuid{Common::UUID::Generate()};
121
122 // Bit 7 must be set, and bit 6 unset for the UUID to be valid
123 uuid.uuid[1] &= 0xFFFFFFFFFFFFFF3FULL;
124 uuid.uuid[1] |= 0x0000000000000080ULL;
125
126 return uuid;
127}
128
129template <typename T>
130T GetRandomValue(T min, T max) {
131 std::random_device device;
132 std::mt19937 gen(device());
133 std::uniform_int_distribution<u64> distribution(0, static_cast<u64>(max));
134 return static_cast<T>(distribution(gen));
135}
136
137template <typename T>
138T GetRandomValue(T max) {
139 return GetRandomValue<T>({}, max);
140}
141
142template <typename T>
143T GetArrayValue(const u8* data, std::size_t index) {
144 T result{};
145 std::memcpy(&result, &data[index * sizeof(T)], sizeof(T));
146 return result;
147}
148
149MiiStoreData BuildRandomStoreData(Age age, Gender gender, Race race, const Common::UUID& user_id) {
150 MiiStoreBitFields bf{};
151
152 if (gender == Gender::All) {
153 gender = GetRandomValue<Gender>(Gender::Maximum);
154 }
155
156 bf.gender.Assign(gender);
157 bf.favorite_color.Assign(GetRandomValue<u8>(11));
158 bf.region_move.Assign(0);
159 bf.font_region.Assign(FontRegion::Standard);
160 bf.type.Assign(0);
161 bf.height.Assign(64);
162 bf.build.Assign(64);
163
164 if (age == Age::All) {
165 const auto temp{GetRandomValue<int>(10)};
166 if (temp >= 8) {
167 age = Age::Old;
168 } else if (temp >= 4) {
169 age = Age::Normal;
170 } else {
171 age = Age::Young;
172 }
173 }
174
175 if (race == Race::All) {
176 const auto temp{GetRandomValue<int>(10)};
177 if (temp >= 8) {
178 race = Race::Black;
179 } else if (temp >= 4) {
180 race = Race::White;
181 } else {
182 race = Race::Asian;
183 }
184 }
185
186 u32 axis_y{};
187 if (gender == Gender::Female && age == Age::Young) {
188 axis_y = GetRandomValue<u32>(3);
189 }
190
191 const std::size_t index{3 * static_cast<std::size_t>(age) +
192 9 * static_cast<std::size_t>(gender) + static_cast<std::size_t>(race)};
193
194 const auto faceline_type_info{
195 GetArrayValue<RandomMiiData4>(&RawData::RandomMiiFaceline[0], index)};
196 const auto faceline_color_info{GetArrayValue<RandomMiiData3>(
197 RawData::RandomMiiFacelineColor.data(),
198 3 * static_cast<std::size_t>(gender) + static_cast<std::size_t>(race))};
199 const auto faceline_wrinkle_info{
200 GetArrayValue<RandomMiiData4>(RawData::RandomMiiFacelineWrinkle.data(), index)};
201 const auto faceline_makeup_info{
202 GetArrayValue<RandomMiiData4>(RawData::RandomMiiFacelineMakeup.data(), index)};
203 const auto hair_type_info{
204 GetArrayValue<RandomMiiData4>(RawData::RandomMiiHairType.data(), index)};
205 const auto hair_color_info{GetArrayValue<RandomMiiData3>(RawData::RandomMiiHairColor.data(),
206 3 * static_cast<std::size_t>(race) +
207 static_cast<std::size_t>(age))};
208 const auto eye_type_info{
209 GetArrayValue<RandomMiiData4>(RawData::RandomMiiEyeType.data(), index)};
210 const auto eye_color_info{GetArrayValue<RandomMiiData2>(RawData::RandomMiiEyeColor.data(),
211 static_cast<std::size_t>(race))};
212 const auto eyebrow_type_info{
213 GetArrayValue<RandomMiiData4>(RawData::RandomMiiEyebrowType.data(), index)};
214 const auto nose_type_info{
215 GetArrayValue<RandomMiiData4>(RawData::RandomMiiNoseType.data(), index)};
216 const auto mouth_type_info{
217 GetArrayValue<RandomMiiData4>(RawData::RandomMiiMouthType.data(), index)};
218 const auto glasses_type_info{GetArrayValue<RandomMiiData2>(RawData::RandomMiiGlassType.data(),
219 static_cast<std::size_t>(age))};
220
221 bf.faceline_type.Assign(
222 faceline_type_info.values[GetRandomValue<std::size_t>(faceline_type_info.values_count)]);
223 bf.faceline_color.Assign(
224 faceline_color_info.values[GetRandomValue<std::size_t>(faceline_color_info.values_count)]);
225 bf.faceline_wrinkle.Assign(
226 faceline_wrinkle_info
227 .values[GetRandomValue<std::size_t>(faceline_wrinkle_info.values_count)]);
228 bf.faceline_makeup.Assign(
229 faceline_makeup_info
230 .values[GetRandomValue<std::size_t>(faceline_makeup_info.values_count)]);
231
232 bf.hair_type.Assign(
233 hair_type_info.values[GetRandomValue<std::size_t>(hair_type_info.values_count)]);
234 bf.hair_color.Assign(
235 HairColorLookup[hair_color_info
236 .values[GetRandomValue<std::size_t>(hair_color_info.values_count)]]);
237 bf.hair_flip.Assign(GetRandomValue<HairFlip>(HairFlip::Maximum));
238
239 bf.eye_type.Assign(
240 eye_type_info.values[GetRandomValue<std::size_t>(eye_type_info.values_count)]);
241
242 const auto eye_rotate_1{gender != Gender::Male ? 4 : 2};
243 const auto eye_rotate_2{gender != Gender::Male ? 3 : 4};
244 const auto eye_rotate_offset{32 - EyeRotateLookup[eye_rotate_1] + eye_rotate_2};
245 const auto eye_rotate{32 - EyeRotateLookup[bf.eye_type]};
246
247 bf.eye_color.Assign(
248 EyeColorLookup[eye_color_info
249 .values[GetRandomValue<std::size_t>(eye_color_info.values_count)]]);
250 bf.eye_scale.Assign(4);
251 bf.eye_aspect.Assign(3);
252 bf.eye_rotate.Assign(eye_rotate_offset - eye_rotate);
253 bf.eye_x.Assign(2);
254 bf.eye_y.Assign(axis_y + 12);
255
256 bf.eyebrow_type.Assign(
257 eyebrow_type_info.values[GetRandomValue<std::size_t>(eyebrow_type_info.values_count)]);
258
259 const auto eyebrow_rotate_1{race == Race::Asian ? 6 : 0};
260 const auto eyebrow_y{race == Race::Asian ? 9 : 10};
261 const auto eyebrow_rotate_offset{32 - EyebrowRotateLookup[eyebrow_rotate_1] + 6};
262 const auto eyebrow_rotate{
263 32 - EyebrowRotateLookup[static_cast<std::size_t>(bf.eyebrow_type.Value())]};
264
265 bf.eyebrow_color.Assign(bf.hair_color);
266 bf.eyebrow_scale.Assign(4);
267 bf.eyebrow_aspect.Assign(3);
268 bf.eyebrow_rotate.Assign(eyebrow_rotate_offset - eyebrow_rotate);
269 bf.eyebrow_x.Assign(2);
270 bf.eyebrow_y.Assign(axis_y + eyebrow_y);
271
272 const auto nose_scale{gender == Gender::Female ? 3 : 4};
273
274 bf.nose_type.Assign(
275 nose_type_info.values[GetRandomValue<std::size_t>(nose_type_info.values_count)]);
276 bf.nose_scale.Assign(nose_scale);
277 bf.nose_y.Assign(axis_y + 9);
278
279 const auto mouth_color{gender == Gender::Female ? GetRandomValue<int>(4) : 0};
280
281 bf.mouth_type.Assign(
282 mouth_type_info.values[GetRandomValue<std::size_t>(mouth_type_info.values_count)]);
283 bf.mouth_color.Assign(MouthColorLookup[mouth_color]);
284 bf.mouth_scale.Assign(4);
285 bf.mouth_aspect.Assign(3);
286 bf.mouth_y.Assign(axis_y + 13);
287
288 bf.beard_color.Assign(bf.hair_color);
289 bf.mustache_scale.Assign(4);
290
291 if (gender == Gender::Male && age != Age::Young && GetRandomValue<int>(10) < 2) {
292 const auto mustache_and_beard_flag{
293 GetRandomValue<BeardAndMustacheFlag>(BeardAndMustacheFlag::All)};
294
295 auto beard_type{BeardType::None};
296 auto mustache_type{MustacheType::None};
297
298 if ((mustache_and_beard_flag & BeardAndMustacheFlag::Beard) ==
299 BeardAndMustacheFlag::Beard) {
300 beard_type = GetRandomValue<BeardType>(BeardType::Beard1, BeardType::Beard5);
301 }
302
303 if ((mustache_and_beard_flag & BeardAndMustacheFlag::Mustache) ==
304 BeardAndMustacheFlag::Mustache) {
305 mustache_type =
306 GetRandomValue<MustacheType>(MustacheType::Mustache1, MustacheType::Mustache5);
307 }
308
309 bf.mustache_type.Assign(mustache_type);
310 bf.beard_type.Assign(beard_type);
311 bf.mustache_y.Assign(10);
312 } else {
313 bf.mustache_type.Assign(MustacheType::None);
314 bf.beard_type.Assign(BeardType::None);
315 bf.mustache_y.Assign(axis_y + 10);
316 }
317
318 const auto glasses_type_start{GetRandomValue<std::size_t>(100)};
319 u8 glasses_type{};
320 while (glasses_type_start < glasses_type_info.values[glasses_type]) {
321 if (++glasses_type >= glasses_type_info.values_count) {
322 UNREACHABLE();
323 break;
324 }
325 }
326
327 bf.glasses_type.Assign(glasses_type);
328 bf.glasses_color.Assign(GlassesColorLookup[0]);
329 bf.glasses_scale.Assign(4);
330 bf.glasses_y.Assign(axis_y + 10);
331
332 bf.mole_type.Assign(0);
333 bf.mole_scale.Assign(4);
334 bf.mole_x.Assign(2);
335 bf.mole_y.Assign(20);
336
337 return {DefaultMiiName, bf, user_id};
338}
339
340MiiStoreData BuildDefaultStoreData(const DefaultMii& info, const Common::UUID& user_id) {
341 MiiStoreBitFields bf{};
342
343 bf.font_region.Assign(info.font_region);
344 bf.favorite_color.Assign(info.favorite_color);
345 bf.gender.Assign(info.gender);
346 bf.height.Assign(info.height);
347 bf.build.Assign(info.weight);
348 bf.type.Assign(info.type);
349 bf.region_move.Assign(info.region);
350 bf.faceline_type.Assign(info.face_type);
351 bf.faceline_color.Assign(info.face_color);
352 bf.faceline_wrinkle.Assign(info.face_wrinkle);
353 bf.faceline_makeup.Assign(info.face_makeup);
354 bf.hair_type.Assign(info.hair_type);
355 bf.hair_color.Assign(HairColorLookup[info.hair_color]);
356 bf.hair_flip.Assign(static_cast<HairFlip>(info.hair_flip));
357 bf.eye_type.Assign(info.eye_type);
358 bf.eye_color.Assign(EyeColorLookup[info.eye_color]);
359 bf.eye_scale.Assign(info.eye_scale);
360 bf.eye_aspect.Assign(info.eye_aspect);
361 bf.eye_rotate.Assign(info.eye_rotate);
362 bf.eye_x.Assign(info.eye_x);
363 bf.eye_y.Assign(info.eye_y);
364 bf.eyebrow_type.Assign(info.eyebrow_type);
365 bf.eyebrow_color.Assign(HairColorLookup[info.eyebrow_color]);
366 bf.eyebrow_scale.Assign(info.eyebrow_scale);
367 bf.eyebrow_aspect.Assign(info.eyebrow_aspect);
368 bf.eyebrow_rotate.Assign(info.eyebrow_rotate);
369 bf.eyebrow_x.Assign(info.eyebrow_x);
370 bf.eyebrow_y.Assign(info.eyebrow_y - 3);
371 bf.nose_type.Assign(info.nose_type);
372 bf.nose_scale.Assign(info.nose_scale);
373 bf.nose_y.Assign(info.nose_y);
374 bf.mouth_type.Assign(info.mouth_type);
375 bf.mouth_color.Assign(MouthColorLookup[info.mouth_color]);
376 bf.mouth_scale.Assign(info.mouth_scale);
377 bf.mouth_aspect.Assign(info.mouth_aspect);
378 bf.mouth_y.Assign(info.mouth_y);
379 bf.beard_color.Assign(HairColorLookup[info.beard_color]);
380 bf.beard_type.Assign(static_cast<BeardType>(info.beard_type));
381 bf.mustache_type.Assign(static_cast<MustacheType>(info.mustache_type));
382 bf.mustache_scale.Assign(info.mustache_scale);
383 bf.mustache_y.Assign(info.mustache_y);
384 bf.glasses_type.Assign(info.glasses_type);
385 bf.glasses_color.Assign(GlassesColorLookup[info.glasses_color]);
386 bf.glasses_scale.Assign(info.glasses_scale);
387 bf.glasses_y.Assign(info.glasses_y);
388 bf.mole_type.Assign(info.mole_type);
389 bf.mole_scale.Assign(info.mole_scale);
390 bf.mole_x.Assign(info.mole_x);
391 bf.mole_y.Assign(info.mole_y);
392
393 return {DefaultMiiName, bf, user_id};
394}
395
396} // namespace
397
398MiiStoreData::MiiStoreData() = default;
399
400MiiStoreData::MiiStoreData(const MiiStoreData::Name& name, const MiiStoreBitFields& bit_fields,
401 const Common::UUID& user_id) {
402 data.name = name;
403 data.uuid = GenerateValidUUID();
404
405 std::memcpy(data.data.data(), &bit_fields, sizeof(MiiStoreBitFields));
406 data_crc = GenerateCrc16(data.data.data(), sizeof(data));
407 device_crc = GenerateCrc16(&user_id, sizeof(Common::UUID));
408}
409
410MiiManager::MiiManager() : user_id{Service::Account::ProfileManager().GetLastOpenedUser()} {}
411
412bool MiiManager::CheckAndResetUpdateCounter(SourceFlag source_flag, u64& current_update_counter) {
413 if ((source_flag & SourceFlag::Database) == SourceFlag::None) {
414 return false;
415 }
416
417 const bool result{current_update_counter != update_counter};
418
419 current_update_counter = update_counter;
420
421 return result;
422}
423
424bool MiiManager::IsFullDatabase() const {
425 // TODO(bunnei): We don't implement the Mii database, so it cannot be full
426 return false;
427}
428
429u32 MiiManager::GetCount(SourceFlag source_flag) const {
430 u32 count{};
431 if ((source_flag & SourceFlag::Database) != SourceFlag::None) {
432 // TODO(bunnei): We don't implement the Mii database, but when we do, update this
433 count += 0;
434 }
435 if ((source_flag & SourceFlag::Default) != SourceFlag::None) {
436 count += DefaultMiiCount;
437 }
438 return count;
439}
440
441ResultVal<MiiInfo> MiiManager::UpdateLatest([[maybe_unused]] const MiiInfo& info,
442 SourceFlag source_flag) {
443 if ((source_flag & SourceFlag::Database) == SourceFlag::None) {
444 return ERROR_CANNOT_FIND_ENTRY;
445 }
446
447 // TODO(bunnei): We don't implement the Mii database, so we can't have an entry
448 return ERROR_CANNOT_FIND_ENTRY;
449}
450
451MiiInfo MiiManager::BuildRandom(Age age, Gender gender, Race race) {
452 return ConvertStoreDataToInfo(BuildRandomStoreData(age, gender, race, user_id));
453}
454
455MiiInfo MiiManager::BuildDefault(std::size_t index) {
456 return ConvertStoreDataToInfo(BuildDefaultStoreData(
457 GetArrayValue<DefaultMii>(RawData::DefaultMii.data(), index), user_id));
458}
459
460ResultVal<std::vector<MiiInfoElement>> MiiManager::GetDefault(SourceFlag source_flag) {
461 std::vector<MiiInfoElement> result;
462
463 if ((source_flag & SourceFlag::Default) == SourceFlag::None) {
464 return MakeResult(std::move(result));
465 }
466
467 for (std::size_t index = 0; index < DefaultMiiCount; index++) {
468 result.emplace_back(BuildDefault(index), Source::Default);
469 }
470
471 return MakeResult(std::move(result));
472}
473
474ResultCode MiiManager::GetIndex([[maybe_unused]] const MiiInfo& info, u32& index) {
475 constexpr u32 INVALID_INDEX{0xFFFFFFFF};
476
477 index = INVALID_INDEX;
478
479 // TODO(bunnei): We don't implement the Mii database, so we can't have an index
480 return ERROR_CANNOT_FIND_ENTRY;
481}
482
483} // namespace Service::Mii
diff --git a/src/core/hle/service/mii/manager.h b/src/core/hle/service/mii/manager.h
new file mode 100644
index 000000000..927451dea
--- /dev/null
+++ b/src/core/hle/service/mii/manager.h
@@ -0,0 +1,331 @@
1// Copyright 2020 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/bit_field.h"
8#include "common/common_funcs.h"
9#include "common/uuid.h"
10#include "core/hle/result.h"
11#include "core/hle/service/mii/types.h"
12
13namespace Service::Mii {
14
15enum class Source : u32 {
16 Database = 0,
17 Default = 1,
18 Account = 2,
19 Friend = 3,
20};
21
22enum class SourceFlag : u32 {
23 None = 0,
24 Database = 1 << 0,
25 Default = 1 << 1,
26};
27DECLARE_ENUM_FLAG_OPERATORS(SourceFlag);
28
29struct MiiInfo {
30 Common::UUID uuid{Common::INVALID_UUID};
31 std::array<char16_t, 11> name{};
32 u8 font_region{};
33 u8 favorite_color{};
34 u8 gender{};
35 u8 height{};
36 u8 build{};
37 u8 type{};
38 u8 region_move{};
39 u8 faceline_type{};
40 u8 faceline_color{};
41 u8 faceline_wrinkle{};
42 u8 faceline_make{};
43 u8 hair_type{};
44 u8 hair_color{};
45 u8 hair_flip{};
46 u8 eye_type{};
47 u8 eye_color{};
48 u8 eye_scale{};
49 u8 eye_aspect{};
50 u8 eye_rotate{};
51 u8 eye_x{};
52 u8 eye_y{};
53 u8 eyebrow_type{};
54 u8 eyebrow_color{};
55 u8 eyebrow_scale{};
56 u8 eyebrow_aspect{};
57 u8 eyebrow_rotate{};
58 u8 eyebrow_x{};
59 u8 eyebrow_y{};
60 u8 nose_type{};
61 u8 nose_scale{};
62 u8 nose_y{};
63 u8 mouth_type{};
64 u8 mouth_color{};
65 u8 mouth_scale{};
66 u8 mouth_aspect{};
67 u8 mouth_y{};
68 u8 beard_color{};
69 u8 beard_type{};
70 u8 mustache_type{};
71 u8 mustache_scale{};
72 u8 mustache_y{};
73 u8 glasses_type{};
74 u8 glasses_color{};
75 u8 glasses_scale{};
76 u8 glasses_y{};
77 u8 mole_type{};
78 u8 mole_scale{};
79 u8 mole_x{};
80 u8 mole_y{};
81 INSERT_PADDING_BYTES(1);
82
83 std::u16string Name() const;
84};
85static_assert(sizeof(MiiInfo) == 0x58, "MiiInfo has incorrect size.");
86static_assert(std::has_unique_object_representations_v<MiiInfo>,
87 "All bits of MiiInfo must contribute to its value.");
88
89#pragma pack(push, 4)
90
91struct MiiInfoElement {
92 MiiInfoElement(const MiiInfo& info, Source source) : info{info}, source{source} {}
93
94 MiiInfo info{};
95 Source source{};
96};
97static_assert(sizeof(MiiInfoElement) == 0x5c, "MiiInfoElement has incorrect size.");
98
99struct MiiStoreBitFields {
100 union {
101 u32 word_0{};
102
103 BitField<0, 8, u32> hair_type;
104 BitField<8, 7, u32> height;
105 BitField<15, 1, u32> mole_type;
106 BitField<16, 7, u32> build;
107 BitField<23, 1, HairFlip> hair_flip;
108 BitField<24, 7, u32> hair_color;
109 BitField<31, 1, u32> type;
110 };
111
112 union {
113 u32 word_1{};
114
115 BitField<0, 7, u32> eye_color;
116 BitField<7, 1, Gender> gender;
117 BitField<8, 7, u32> eyebrow_color;
118 BitField<16, 7, u32> mouth_color;
119 BitField<24, 7, u32> beard_color;
120 };
121
122 union {
123 u32 word_2{};
124
125 BitField<0, 7, u32> glasses_color;
126 BitField<8, 6, u32> eye_type;
127 BitField<14, 2, u32> region_move;
128 BitField<16, 6, u32> mouth_type;
129 BitField<22, 2, FontRegion> font_region;
130 BitField<24, 5, u32> eye_y;
131 BitField<29, 3, u32> glasses_scale;
132 };
133
134 union {
135 u32 word_3{};
136
137 BitField<0, 5, u32> eyebrow_type;
138 BitField<5, 3, MustacheType> mustache_type;
139 BitField<8, 5, u32> nose_type;
140 BitField<13, 3, BeardType> beard_type;
141 BitField<16, 5, u32> nose_y;
142 BitField<21, 3, u32> mouth_aspect;
143 BitField<24, 5, u32> mouth_y;
144 BitField<29, 3, u32> eyebrow_aspect;
145 };
146
147 union {
148 u32 word_4{};
149
150 BitField<0, 5, u32> mustache_y;
151 BitField<5, 3, u32> eye_rotate;
152 BitField<8, 5, u32> glasses_y;
153 BitField<13, 3, u32> eye_aspect;
154 BitField<16, 5, u32> mole_x;
155 BitField<21, 3, u32> eye_scale;
156 BitField<24, 5, u32> mole_y;
157 };
158
159 union {
160 u32 word_5{};
161
162 BitField<0, 5, u32> glasses_type;
163 BitField<8, 4, u32> favorite_color;
164 BitField<12, 4, u32> faceline_type;
165 BitField<16, 4, u32> faceline_color;
166 BitField<20, 4, u32> faceline_wrinkle;
167 BitField<24, 4, u32> faceline_makeup;
168 BitField<28, 4, u32> eye_x;
169 };
170
171 union {
172 u32 word_6{};
173
174 BitField<0, 4, u32> eyebrow_scale;
175 BitField<4, 4, u32> eyebrow_rotate;
176 BitField<8, 4, u32> eyebrow_x;
177 BitField<12, 4, u32> eyebrow_y;
178 BitField<16, 4, u32> nose_scale;
179 BitField<20, 4, u32> mouth_scale;
180 BitField<24, 4, u32> mustache_scale;
181 BitField<28, 4, u32> mole_scale;
182 };
183};
184static_assert(sizeof(MiiStoreBitFields) == 0x1c, "MiiStoreBitFields has incorrect size.");
185static_assert(std::is_trivially_copyable_v<MiiStoreBitFields>,
186 "MiiStoreBitFields is not trivially copyable.");
187
188struct MiiStoreData {
189 using Name = std::array<char16_t, 10>;
190
191 MiiStoreData();
192 MiiStoreData(const Name& name, const MiiStoreBitFields& bit_fields,
193 const Common::UUID& user_id);
194
195 // This corresponds to the above structure MiiStoreBitFields. I did it like this because the
196 // BitField<> type makes this (and any thing that contains it) not trivially copyable, which is
197 // not suitable for our uses.
198 struct {
199 std::array<u8, 0x1C> data{};
200 static_assert(sizeof(MiiStoreBitFields) == sizeof(data), "data field has incorrect size.");
201
202 Name name{};
203 Common::UUID uuid{Common::INVALID_UUID};
204 } data;
205
206 u16 data_crc{};
207 u16 device_crc{};
208};
209static_assert(sizeof(MiiStoreData) == 0x44, "MiiStoreData has incorrect size.");
210
211struct MiiStoreDataElement {
212 MiiStoreData data{};
213 Source source{};
214};
215static_assert(sizeof(MiiStoreDataElement) == 0x48, "MiiStoreDataElement has incorrect size.");
216
217struct MiiDatabase {
218 u32 magic{}; // 'NFDB'
219 std::array<MiiStoreData, 0x64> miis{};
220 INSERT_PADDING_BYTES(1);
221 u8 count{};
222 u16 crc{};
223};
224static_assert(sizeof(MiiDatabase) == 0x1A98, "MiiDatabase has incorrect size.");
225
226struct RandomMiiValues {
227 std::array<u8, 0xbc> values{};
228};
229static_assert(sizeof(RandomMiiValues) == 0xbc, "RandomMiiValues has incorrect size.");
230
231struct RandomMiiData4 {
232 Gender gender{};
233 Age age{};
234 Race race{};
235 u32 values_count{};
236 std::array<u8, 0xbc> values{};
237};
238static_assert(sizeof(RandomMiiData4) == 0xcc, "RandomMiiData4 has incorrect size.");
239
240struct RandomMiiData3 {
241 u32 arg_1;
242 u32 arg_2;
243 u32 values_count;
244 std::array<u8, 0xbc> values{};
245};
246static_assert(sizeof(RandomMiiData3) == 0xc8, "RandomMiiData3 has incorrect size.");
247
248struct RandomMiiData2 {
249 u32 arg_1;
250 u32 values_count;
251 std::array<u8, 0xbc> values{};
252};
253static_assert(sizeof(RandomMiiData2) == 0xc4, "RandomMiiData2 has incorrect size.");
254
255struct DefaultMii {
256 u32 face_type{};
257 u32 face_color{};
258 u32 face_wrinkle{};
259 u32 face_makeup{};
260 u32 hair_type{};
261 u32 hair_color{};
262 u32 hair_flip{};
263 u32 eye_type{};
264 u32 eye_color{};
265 u32 eye_scale{};
266 u32 eye_aspect{};
267 u32 eye_rotate{};
268 u32 eye_x{};
269 u32 eye_y{};
270 u32 eyebrow_type{};
271 u32 eyebrow_color{};
272 u32 eyebrow_scale{};
273 u32 eyebrow_aspect{};
274 u32 eyebrow_rotate{};
275 u32 eyebrow_x{};
276 u32 eyebrow_y{};
277 u32 nose_type{};
278 u32 nose_scale{};
279 u32 nose_y{};
280 u32 mouth_type{};
281 u32 mouth_color{};
282 u32 mouth_scale{};
283 u32 mouth_aspect{};
284 u32 mouth_y{};
285 u32 mustache_type{};
286 u32 beard_type{};
287 u32 beard_color{};
288 u32 mustache_scale{};
289 u32 mustache_y{};
290 u32 glasses_type{};
291 u32 glasses_color{};
292 u32 glasses_scale{};
293 u32 glasses_y{};
294 u32 mole_type{};
295 u32 mole_scale{};
296 u32 mole_x{};
297 u32 mole_y{};
298 u32 height{};
299 u32 weight{};
300 Gender gender{};
301 u32 favorite_color{};
302 u32 region{};
303 FontRegion font_region{};
304 u32 type{};
305 INSERT_PADDING_WORDS(5);
306};
307static_assert(sizeof(DefaultMii) == 0xd8, "MiiStoreData has incorrect size.");
308
309#pragma pack(pop)
310
311// The Mii manager is responsible for loading and storing the Miis to the database in NAND along
312// with providing an easy interface for HLE emulation of the mii service.
313class MiiManager {
314public:
315 MiiManager();
316
317 bool CheckAndResetUpdateCounter(SourceFlag source_flag, u64& current_update_counter);
318 bool IsFullDatabase() const;
319 u32 GetCount(SourceFlag source_flag) const;
320 ResultVal<MiiInfo> UpdateLatest(const MiiInfo& info, SourceFlag source_flag);
321 MiiInfo BuildRandom(Age age, Gender gender, Race race);
322 MiiInfo BuildDefault(std::size_t index);
323 ResultVal<std::vector<MiiInfoElement>> GetDefault(SourceFlag source_flag);
324 ResultCode GetIndex(const MiiInfo& info, u32& index);
325
326private:
327 const Common::UUID user_id;
328 u64 update_counter{};
329};
330
331}; // namespace Service::Mii
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp
index a128edb43..b81bf6277 100644
--- a/src/core/hle/service/mii/mii.cpp
+++ b/src/core/hle/service/mii/mii.cpp
@@ -4,22 +4,17 @@
4 4
5#include <memory> 5#include <memory>
6 6
7#include <fmt/ostream.h>
8
9#include "common/logging/log.h" 7#include "common/logging/log.h"
10#include "common/string_util.h"
11#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
12#include "core/hle/kernel/hle_ipc.h" 9#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/mii/manager.h"
13#include "core/hle/service/mii/mii.h" 11#include "core/hle/service/mii/mii.h"
14#include "core/hle/service/mii/mii_manager.h"
15#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
16#include "core/hle/service/sm/sm.h" 13#include "core/hle/service/sm/sm.h"
17 14
18namespace Service::Mii { 15namespace Service::Mii {
19 16
20constexpr ResultCode ERROR_INVALID_ARGUMENT{ErrorModule::Mii, 1}; 17constexpr ResultCode ERROR_INVALID_ARGUMENT{ErrorModule::Mii, 1};
21constexpr ResultCode ERROR_CANNOT_FIND_ENTRY{ErrorModule::Mii, 4};
22constexpr ResultCode ERROR_NOT_IN_TEST_MODE{ErrorModule::Mii, 99};
23 18
24class IDatabaseService final : public ServiceFramework<IDatabaseService> { 19class IDatabaseService final : public ServiceFramework<IDatabaseService> {
25public: 20public:
@@ -31,19 +26,19 @@ public:
31 {2, &IDatabaseService::GetCount, "GetCount"}, 26 {2, &IDatabaseService::GetCount, "GetCount"},
32 {3, &IDatabaseService::Get, "Get"}, 27 {3, &IDatabaseService::Get, "Get"},
33 {4, &IDatabaseService::Get1, "Get1"}, 28 {4, &IDatabaseService::Get1, "Get1"},
34 {5, nullptr, "UpdateLatest"}, 29 {5, &IDatabaseService::UpdateLatest, "UpdateLatest"},
35 {6, &IDatabaseService::BuildRandom, "BuildRandom"}, 30 {6, &IDatabaseService::BuildRandom, "BuildRandom"},
36 {7, &IDatabaseService::BuildDefault, "BuildDefault"}, 31 {7, &IDatabaseService::BuildDefault, "BuildDefault"},
37 {8, &IDatabaseService::Get2, "Get2"}, 32 {8, nullptr, "Get2"},
38 {9, &IDatabaseService::Get3, "Get3"}, 33 {9, nullptr, "Get3"},
39 {10, nullptr, "UpdateLatest1"}, 34 {10, nullptr, "UpdateLatest1"},
40 {11, &IDatabaseService::FindIndex, "FindIndex"}, 35 {11, nullptr, "FindIndex"},
41 {12, &IDatabaseService::Move, "Move"}, 36 {12, nullptr, "Move"},
42 {13, &IDatabaseService::AddOrReplace, "AddOrReplace"}, 37 {13, nullptr, "AddOrReplace"},
43 {14, &IDatabaseService::Delete, "Delete"}, 38 {14, nullptr, "Delete"},
44 {15, &IDatabaseService::DestroyFile, "DestroyFile"}, 39 {15, nullptr, "DestroyFile"},
45 {16, &IDatabaseService::DeleteFile, "DeleteFile"}, 40 {16, nullptr, "DeleteFile"},
46 {17, &IDatabaseService::Format, "Format"}, 41 {17, nullptr, "Format"},
47 {18, nullptr, "Import"}, 42 {18, nullptr, "Import"},
48 {19, nullptr, "Export"}, 43 {19, nullptr, "Export"},
49 {20, nullptr, "IsBrokenDatabaseWithClearFlag"}, 44 {20, nullptr, "IsBrokenDatabaseWithClearFlag"},
@@ -59,31 +54,26 @@ public:
59 } 54 }
60 55
61private: 56private:
62 template <typename OutType> 57 template <typename T>
63 std::vector<u8> SerializeArray(OutType (MiiManager::*getter)(u32) const, u32 offset, 58 std::vector<u8> SerializeArray(const std::vector<T>& values) {
64 u32 requested_size, u32& read_size) { 59 std::vector<u8> out(values.size() * sizeof(T));
65 read_size = std::min(requested_size, db.Size() - offset); 60 std::size_t offset{};
66 61 for (const auto& value : values) {
67 std::vector<u8> out(read_size * sizeof(OutType)); 62 std::memcpy(out.data() + offset, &value, sizeof(T));
68 63 offset += sizeof(T);
69 for (u32 i = 0; i < read_size; ++i) {
70 const auto obj = (db.*getter)(offset + i);
71 std::memcpy(out.data() + i * sizeof(OutType), &obj, sizeof(OutType));
72 } 64 }
73
74 return out; 65 return out;
75 } 66 }
76 67
77 void IsUpdated(Kernel::HLERequestContext& ctx) { 68 void IsUpdated(Kernel::HLERequestContext& ctx) {
78 IPC::RequestParser rp{ctx}; 69 IPC::RequestParser rp{ctx};
79 const auto source{rp.PopRaw<Source>()}; 70 const auto source_flag{rp.PopRaw<SourceFlag>()};
80 71
81 LOG_DEBUG(Service_Mii, "called with source={}", source); 72 LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag);
82 73
83 IPC::ResponseBuilder rb{ctx, 3}; 74 IPC::ResponseBuilder rb{ctx, 3};
84 rb.Push(RESULT_SUCCESS); 75 rb.Push(RESULT_SUCCESS);
85 rb.Push(db.CheckUpdatedFlag()); 76 rb.Push(manager.CheckAndResetUpdateCounter(source_flag, current_update_counter));
86 db.ResetUpdatedFlag();
87 } 77 }
88 78
89 void IsFullDatabase(Kernel::HLERequestContext& ctx) { 79 void IsFullDatabase(Kernel::HLERequestContext& ctx) {
@@ -91,264 +81,149 @@ private:
91 81
92 IPC::ResponseBuilder rb{ctx, 3}; 82 IPC::ResponseBuilder rb{ctx, 3};
93 rb.Push(RESULT_SUCCESS); 83 rb.Push(RESULT_SUCCESS);
94 rb.Push(db.Full()); 84 rb.Push(manager.IsFullDatabase());
95 } 85 }
96 86
97 void GetCount(Kernel::HLERequestContext& ctx) { 87 void GetCount(Kernel::HLERequestContext& ctx) {
98 IPC::RequestParser rp{ctx}; 88 IPC::RequestParser rp{ctx};
99 const auto source{rp.PopRaw<Source>()}; 89 const auto source_flag{rp.PopRaw<SourceFlag>()};
100 90
101 LOG_DEBUG(Service_Mii, "called with source={}", source); 91 LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag);
102 92
103 IPC::ResponseBuilder rb{ctx, 3}; 93 IPC::ResponseBuilder rb{ctx, 3};
104 rb.Push(RESULT_SUCCESS); 94 rb.Push(RESULT_SUCCESS);
105 rb.Push<u32>(db.Size()); 95 rb.Push<u32>(manager.GetCount(source_flag));
106 } 96 }
107 97
108 // Gets Miis from database at offset and index in format MiiInfoElement
109 void Get(Kernel::HLERequestContext& ctx) { 98 void Get(Kernel::HLERequestContext& ctx) {
110 IPC::RequestParser rp{ctx}; 99 IPC::RequestParser rp{ctx};
111 const auto size{rp.PopRaw<u32>()}; 100 const auto source_flag{rp.PopRaw<SourceFlag>()};
112 const auto source{rp.PopRaw<Source>()};
113
114 LOG_DEBUG(Service_Mii, "called with size={:08X}, offset={:08X}, source={}", size,
115 offsets[0], source);
116
117 u32 read_size{};
118 ctx.WriteBuffer(SerializeArray(&MiiManager::GetInfoElement, offsets[0], size, read_size));
119 offsets[0] += read_size;
120
121 IPC::ResponseBuilder rb{ctx, 3};
122 rb.Push(RESULT_SUCCESS);
123 rb.Push<u32>(read_size);
124 }
125 101
126 // Gets Miis from database at offset and index in format MiiInfo 102 LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag);
127 void Get1(Kernel::HLERequestContext& ctx) {
128 IPC::RequestParser rp{ctx};
129 const auto size{rp.PopRaw<u32>()};
130 const auto source{rp.PopRaw<Source>()};
131 103
132 LOG_DEBUG(Service_Mii, "called with size={:08X}, offset={:08X}, source={}", size, 104 const auto result{manager.GetDefault(source_flag)};
133 offsets[1], source); 105 if (result.Failed()) {
106 IPC::ResponseBuilder rb{ctx, 2};
107 rb.Push(result.Code());
108 return;
109 }
134 110
135 u32 read_size{}; 111 if (result->size() > 0) {
136 ctx.WriteBuffer(SerializeArray(&MiiManager::GetInfo, offsets[1], size, read_size)); 112 ctx.WriteBuffer(SerializeArray(*result));
137 offsets[1] += read_size; 113 }
138 114
139 IPC::ResponseBuilder rb{ctx, 3}; 115 IPC::ResponseBuilder rb{ctx, 3};
140 rb.Push(RESULT_SUCCESS); 116 rb.Push(RESULT_SUCCESS);
141 rb.Push<u32>(read_size); 117 rb.Push<u32>(static_cast<u32>(result->size()));
142 } 118 }
143 119
144 void BuildRandom(Kernel::HLERequestContext& ctx) { 120 void Get1(Kernel::HLERequestContext& ctx) {
145 IPC::RequestParser rp{ctx}; 121 IPC::RequestParser rp{ctx};
146 const auto [unknown1, unknown2, unknown3] = rp.PopRaw<RandomParameters>(); 122 const auto source_flag{rp.PopRaw<SourceFlag>()};
147 123
148 if (unknown1 > 3) { 124 LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag);
149 IPC::ResponseBuilder rb{ctx, 2};
150 rb.Push(ERROR_INVALID_ARGUMENT);
151 LOG_ERROR(Service_Mii, "Invalid unknown1 value: {}", unknown1);
152 return;
153 }
154 125
155 if (unknown2 > 2) { 126 const auto result{manager.GetDefault(source_flag)};
127 if (result.Failed()) {
156 IPC::ResponseBuilder rb{ctx, 2}; 128 IPC::ResponseBuilder rb{ctx, 2};
157 rb.Push(ERROR_INVALID_ARGUMENT); 129 rb.Push(result.Code());
158 LOG_ERROR(Service_Mii, "Invalid unknown2 value: {}", unknown2);
159 return; 130 return;
160 } 131 }
161 132
162 if (unknown3 > 3) { 133 std::vector<MiiInfo> values;
163 IPC::ResponseBuilder rb{ctx, 2}; 134 for (const auto& element : *result) {
164 rb.Push(ERROR_INVALID_ARGUMENT); 135 values.emplace_back(element.info);
165 LOG_ERROR(Service_Mii, "Invalid unknown3 value: {}", unknown3);
166 return;
167 } 136 }
168 137
169 LOG_DEBUG(Service_Mii, "called with param_1={:08X}, param_2={:08X}, param_3={:08X}", 138 ctx.WriteBuffer(SerializeArray(values));
170 unknown1, unknown2, unknown3);
171 139
172 const auto info = db.CreateRandom({unknown1, unknown2, unknown3}); 140 IPC::ResponseBuilder rb{ctx, 3};
173 IPC::ResponseBuilder rb{ctx, 2 + sizeof(MiiInfo) / sizeof(u32)};
174 rb.Push(RESULT_SUCCESS); 141 rb.Push(RESULT_SUCCESS);
175 rb.PushRaw<MiiInfo>(info); 142 rb.Push<u32>(static_cast<u32>(result->size()));
176 } 143 }
177 144
178 void BuildDefault(Kernel::HLERequestContext& ctx) { 145 void UpdateLatest(Kernel::HLERequestContext& ctx) {
179 IPC::RequestParser rp{ctx}; 146 IPC::RequestParser rp{ctx};
180 const auto index{rp.PopRaw<u32>()}; 147 const auto info{rp.PopRaw<MiiInfo>()};
148 const auto source_flag{rp.PopRaw<SourceFlag>()};
181 149
182 if (index > 5) { 150 LOG_DEBUG(Service_Mii, "called with source_flag={}", source_flag);
183 LOG_ERROR(Service_Mii, "invalid argument, index cannot be greater than 5 but is {:08X}", 151
184 index); 152 const auto result{manager.UpdateLatest(info, source_flag)};
153 if (result.Failed()) {
185 IPC::ResponseBuilder rb{ctx, 2}; 154 IPC::ResponseBuilder rb{ctx, 2};
186 rb.Push(ERROR_INVALID_ARGUMENT); 155 rb.Push(result.Code());
187 return; 156 return;
188 } 157 }
189 158
190 LOG_DEBUG(Service_Mii, "called with index={:08X}", index);
191
192 const auto info = db.CreateDefault(index);
193 IPC::ResponseBuilder rb{ctx, 2 + sizeof(MiiInfo) / sizeof(u32)}; 159 IPC::ResponseBuilder rb{ctx, 2 + sizeof(MiiInfo) / sizeof(u32)};
194 rb.Push(RESULT_SUCCESS); 160 rb.Push(RESULT_SUCCESS);
195 rb.PushRaw<MiiInfo>(info); 161 rb.PushRaw<MiiInfo>(*result);
196 } 162 }
197 163
198 // Gets Miis from database at offset and index in format MiiStoreDataElement 164 void BuildRandom(Kernel::HLERequestContext& ctx) {
199 void Get2(Kernel::HLERequestContext& ctx) {
200 IPC::RequestParser rp{ctx};
201 const auto size{rp.PopRaw<u32>()};
202 const auto source{rp.PopRaw<Source>()};
203
204 LOG_DEBUG(Service_Mii, "called with size={:08X}, offset={:08X}, source={}", size,
205 offsets[2], source);
206
207 u32 read_size{};
208 ctx.WriteBuffer(
209 SerializeArray(&MiiManager::GetStoreDataElement, offsets[2], size, read_size));
210 offsets[2] += read_size;
211
212 IPC::ResponseBuilder rb{ctx, 3};
213 rb.Push(RESULT_SUCCESS);
214 rb.Push<u32>(read_size);
215 }
216
217 // Gets Miis from database at offset and index in format MiiStoreData
218 void Get3(Kernel::HLERequestContext& ctx) {
219 IPC::RequestParser rp{ctx};
220 const auto size{rp.PopRaw<u32>()};
221 const auto source{rp.PopRaw<Source>()};
222
223 LOG_DEBUG(Service_Mii, "called with size={:08X}, offset={:08X}, source={}", size,
224 offsets[3], source);
225
226 u32 read_size{};
227 ctx.WriteBuffer(SerializeArray(&MiiManager::GetStoreData, offsets[3], size, read_size));
228 offsets[3] += read_size;
229
230 IPC::ResponseBuilder rb{ctx, 3};
231 rb.Push(RESULT_SUCCESS);
232 rb.Push<u32>(read_size);
233 }
234
235 void FindIndex(Kernel::HLERequestContext& ctx) {
236 IPC::RequestParser rp{ctx}; 165 IPC::RequestParser rp{ctx};
237 const auto uuid{rp.PopRaw<Common::UUID>()};
238 const auto unknown{rp.PopRaw<bool>()};
239 166
240 LOG_DEBUG(Service_Mii, "called with uuid={}, unknown={}", uuid.FormatSwitch(), unknown); 167 const auto age{rp.PopRaw<Age>()};
168 const auto gender{rp.PopRaw<Gender>()};
169 const auto race{rp.PopRaw<Race>()};
241 170
242 IPC::ResponseBuilder rb{ctx, 3}; 171 LOG_DEBUG(Service_Mii, "called with age={}, gender={}, race={}", age, gender, race);
243 172
244 const auto index = db.IndexOf(uuid); 173 if (age > Age::All) {
245 if (index > MAX_MIIS) { 174 IPC::ResponseBuilder rb{ctx, 2};
246 // TODO(DarkLordZach): Find a better error code 175 rb.Push(ERROR_INVALID_ARGUMENT);
247 rb.Push(RESULT_UNKNOWN); 176 LOG_ERROR(Service_Mii, "invalid age={}", age);
248 rb.Push(index); 177 return;
249 } else {
250 rb.Push(RESULT_SUCCESS);
251 rb.Push(index);
252 } 178 }
253 }
254 179
255 void Move(Kernel::HLERequestContext& ctx) { 180 if (gender > Gender::All) {
256 IPC::RequestParser rp{ctx};
257 const auto uuid{rp.PopRaw<Common::UUID>()};
258 const auto index{rp.PopRaw<s32>()};
259
260 if (index < 0) {
261 LOG_ERROR(Service_Mii, "Index cannot be negative but is {:08X}!", index);
262 IPC::ResponseBuilder rb{ctx, 2}; 181 IPC::ResponseBuilder rb{ctx, 2};
263 rb.Push(ERROR_INVALID_ARGUMENT); 182 rb.Push(ERROR_INVALID_ARGUMENT);
183 LOG_ERROR(Service_Mii, "invalid gender={}", gender);
264 return; 184 return;
265 } 185 }
266 186
267 LOG_DEBUG(Service_Mii, "called with uuid={}, index={:08X}", uuid.FormatSwitch(), index); 187 if (race > Race::All) {
268
269 const auto success = db.Move(uuid, index);
270
271 IPC::ResponseBuilder rb{ctx, 2};
272 // TODO(DarkLordZach): Find a better error code
273 rb.Push(success ? RESULT_SUCCESS : RESULT_UNKNOWN);
274 }
275
276 void AddOrReplace(Kernel::HLERequestContext& ctx) {
277 IPC::RequestParser rp{ctx};
278 const auto data{rp.PopRaw<MiiStoreData>()};
279
280 LOG_DEBUG(Service_Mii, "called with Mii data uuid={}, name={}", data.uuid.FormatSwitch(),
281 Common::UTF16ToUTF8(data.Name()));
282
283 const auto success = db.AddOrReplace(data);
284
285 IPC::ResponseBuilder rb{ctx, 2};
286 // TODO(DarkLordZach): Find a better error code
287 rb.Push(success ? RESULT_SUCCESS : RESULT_UNKNOWN);
288 }
289
290 void Delete(Kernel::HLERequestContext& ctx) {
291 IPC::RequestParser rp{ctx};
292 const auto uuid{rp.PopRaw<Common::UUID>()};
293
294 LOG_DEBUG(Service_Mii, "called with uuid={}", uuid.FormatSwitch());
295
296 const auto success = db.Remove(uuid);
297
298 IPC::ResponseBuilder rb{ctx, 2};
299 rb.Push(success ? RESULT_SUCCESS : ERROR_CANNOT_FIND_ENTRY);
300 }
301
302 void DestroyFile(Kernel::HLERequestContext& ctx) {
303 LOG_DEBUG(Service_Mii, "called");
304
305 if (!db.IsTestModeEnabled()) {
306 LOG_ERROR(Service_Mii, "Database is not in test mode -- cannot destory database file.");
307 IPC::ResponseBuilder rb{ctx, 2}; 188 IPC::ResponseBuilder rb{ctx, 2};
308 rb.Push(ERROR_NOT_IN_TEST_MODE); 189 rb.Push(ERROR_INVALID_ARGUMENT);
190 LOG_ERROR(Service_Mii, "invalid race={}", race);
309 return; 191 return;
310 } 192 }
311 193
312 IPC::ResponseBuilder rb{ctx, 3}; 194 IPC::ResponseBuilder rb{ctx, 2 + sizeof(MiiInfo) / sizeof(u32)};
313 rb.Push(RESULT_SUCCESS); 195 rb.Push(RESULT_SUCCESS);
314 rb.Push(db.DestroyFile()); 196 rb.PushRaw<MiiInfo>(manager.BuildRandom(age, gender, race));
315 } 197 }
316 198
317 void DeleteFile(Kernel::HLERequestContext& ctx) { 199 void BuildDefault(Kernel::HLERequestContext& ctx) {
318 LOG_DEBUG(Service_Mii, "called"); 200 IPC::RequestParser rp{ctx};
201 const auto index{rp.Pop<u32>()};
202
203 LOG_DEBUG(Service_Mii, "called with index={}", index);
319 204
320 if (!db.IsTestModeEnabled()) { 205 if (index > 5) {
321 LOG_ERROR(Service_Mii, "Database is not in test mode -- cannot delete database file."); 206 LOG_ERROR(Service_Mii, "invalid argument, index cannot be greater than 5 but is {:08X}",
207 index);
322 IPC::ResponseBuilder rb{ctx, 2}; 208 IPC::ResponseBuilder rb{ctx, 2};
323 rb.Push(ERROR_NOT_IN_TEST_MODE); 209 rb.Push(ERROR_INVALID_ARGUMENT);
324 return; 210 return;
325 } 211 }
326 212
327 IPC::ResponseBuilder rb{ctx, 3}; 213 IPC::ResponseBuilder rb{ctx, 2 + sizeof(MiiInfo) / sizeof(u32)};
328 rb.Push(RESULT_SUCCESS);
329 rb.Push(db.DeleteFile());
330 }
331
332 void Format(Kernel::HLERequestContext& ctx) {
333 LOG_DEBUG(Service_Mii, "called");
334
335 db.Clear();
336
337 IPC::ResponseBuilder rb{ctx, 2};
338 rb.Push(RESULT_SUCCESS); 214 rb.Push(RESULT_SUCCESS);
215 rb.PushRaw<MiiInfo>(manager.BuildDefault(index));
339 } 216 }
340 217
341 void GetIndex(Kernel::HLERequestContext& ctx) { 218 void GetIndex(Kernel::HLERequestContext& ctx) {
342 IPC::RequestParser rp{ctx}; 219 IPC::RequestParser rp{ctx};
343 const auto info{rp.PopRaw<MiiInfo>()}; 220 const auto info{rp.PopRaw<MiiInfo>()};
344 221
345 LOG_DEBUG(Service_Mii, "called with Mii info uuid={}, name={}", info.uuid.FormatSwitch(), 222 LOG_DEBUG(Service_Mii, "called");
346 Common::UTF16ToUTF8(info.Name()));
347
348 const auto index = db.IndexOf(info);
349 223
350 IPC::ResponseBuilder rb{ctx, 2}; 224 u32 index{};
351 rb.Push(RESULT_SUCCESS); 225 IPC::ResponseBuilder rb{ctx, 3};
226 rb.Push(manager.GetIndex(info, index));
352 rb.Push(index); 227 rb.Push(index);
353 } 228 }
354 229
@@ -364,12 +239,14 @@ private:
364 rb.Push(RESULT_SUCCESS); 239 rb.Push(RESULT_SUCCESS);
365 } 240 }
366 241
367 MiiManager db; 242 constexpr bool IsInterfaceVersionSupported(u32 interface_version) const {
243 return current_interface_version >= interface_version;
244 }
368 245
369 u32 current_interface_version = 0; 246 MiiManager manager;
370 247
371 // Last read offsets of Get functions 248 u32 current_interface_version{};
372 std::array<u32, 4> offsets{}; 249 u64 current_update_counter{};
373}; 250};
374 251
375class MiiDBModule final : public ServiceFramework<MiiDBModule> { 252class MiiDBModule final : public ServiceFramework<MiiDBModule> {
diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp
deleted file mode 100644
index 8d0353075..000000000
--- a/src/core/hle/service/mii/mii_manager.cpp
+++ /dev/null
@@ -1,420 +0,0 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <cstring>
7#include "common/assert.h"
8#include "common/file_util.h"
9#include "common/logging/log.h"
10#include "common/string_util.h"
11#include "core/hle/service/mii/mii_manager.h"
12
13namespace Service::Mii {
14
15namespace {
16
17constexpr char MII_SAVE_DATABASE_PATH[] = "/system/save/8000000000000030/MiiDatabase.dat";
18constexpr std::array<char16_t, 11> DEFAULT_MII_NAME = {u'y', u'u', u'z', u'u', u'\0'};
19
20// This value was retrieved from HW test
21constexpr MiiStoreData DEFAULT_MII = {
22 {
23 0x21, 0x40, 0x40, 0x01, 0x08, 0x01, 0x13, 0x08, 0x08, 0x02, 0x17, 0x8C, 0x06, 0x01,
24 0x69, 0x6D, 0x8A, 0x6A, 0x82, 0x14, 0x00, 0x00, 0x00, 0x20, 0x64, 0x72, 0x44, 0x44,
25 },
26 {'y', 'u', 'z', 'u', '\0'},
27 Common::UUID{1, 0},
28 0,
29 0,
30};
31
32// Default values taken from multiple real databases
33const MiiDatabase DEFAULT_MII_DATABASE{Common::MakeMagic('N', 'F', 'D', 'B'), {}, {1}, 0, 0};
34
35constexpr std::array<const char*, 4> SOURCE_NAMES{
36 "Database",
37 "Default",
38 "Account",
39 "Friend",
40};
41
42template <typename T, std::size_t SourceArraySize, std::size_t DestArraySize>
43std::array<T, DestArraySize> ResizeArray(const std::array<T, SourceArraySize>& in) {
44 std::array<T, DestArraySize> out{};
45 std::memcpy(out.data(), in.data(), sizeof(T) * std::min(SourceArraySize, DestArraySize));
46 return out;
47}
48
49MiiInfo ConvertStoreDataToInfo(const MiiStoreData& data) {
50 MiiStoreBitFields bf{};
51 std::memcpy(&bf, data.data.data(), sizeof(MiiStoreBitFields));
52 return {
53 data.uuid,
54 ResizeArray<char16_t, 10, 11>(data.name),
55 static_cast<u8>(bf.font_region.Value()),
56 static_cast<u8>(bf.favorite_color.Value()),
57 static_cast<u8>(bf.gender.Value()),
58 static_cast<u8>(bf.height.Value()),
59 static_cast<u8>(bf.weight.Value()),
60 static_cast<u8>(bf.mii_type.Value()),
61 static_cast<u8>(bf.mii_region.Value()),
62 static_cast<u8>(bf.face_type.Value()),
63 static_cast<u8>(bf.face_color.Value()),
64 static_cast<u8>(bf.face_wrinkle.Value()),
65 static_cast<u8>(bf.face_makeup.Value()),
66 static_cast<u8>(bf.hair_type.Value()),
67 static_cast<u8>(bf.hair_color.Value()),
68 static_cast<bool>(bf.hair_flip.Value()),
69 static_cast<u8>(bf.eye_type.Value()),
70 static_cast<u8>(bf.eye_color.Value()),
71 static_cast<u8>(bf.eye_scale.Value()),
72 static_cast<u8>(bf.eye_aspect.Value()),
73 static_cast<u8>(bf.eye_rotate.Value()),
74 static_cast<u8>(bf.eye_x.Value()),
75 static_cast<u8>(bf.eye_y.Value()),
76 static_cast<u8>(bf.eyebrow_type.Value()),
77 static_cast<u8>(bf.eyebrow_color.Value()),
78 static_cast<u8>(bf.eyebrow_scale.Value()),
79 static_cast<u8>(bf.eyebrow_aspect.Value()),
80 static_cast<u8>(bf.eyebrow_rotate.Value()),
81 static_cast<u8>(bf.eyebrow_x.Value()),
82 static_cast<u8>(bf.eyebrow_y.Value()),
83 static_cast<u8>(bf.nose_type.Value()),
84 static_cast<u8>(bf.nose_scale.Value()),
85 static_cast<u8>(bf.nose_y.Value()),
86 static_cast<u8>(bf.mouth_type.Value()),
87 static_cast<u8>(bf.mouth_color.Value()),
88 static_cast<u8>(bf.mouth_scale.Value()),
89 static_cast<u8>(bf.mouth_aspect.Value()),
90 static_cast<u8>(bf.mouth_y.Value()),
91 static_cast<u8>(bf.facial_hair_color.Value()),
92 static_cast<u8>(bf.beard_type.Value()),
93 static_cast<u8>(bf.mustache_type.Value()),
94 static_cast<u8>(bf.mustache_scale.Value()),
95 static_cast<u8>(bf.mustache_y.Value()),
96 static_cast<u8>(bf.glasses_type.Value()),
97 static_cast<u8>(bf.glasses_color.Value()),
98 static_cast<u8>(bf.glasses_scale.Value()),
99 static_cast<u8>(bf.glasses_y.Value()),
100 static_cast<u8>(bf.mole_type.Value()),
101 static_cast<u8>(bf.mole_scale.Value()),
102 static_cast<u8>(bf.mole_x.Value()),
103 static_cast<u8>(bf.mole_y.Value()),
104 0x00,
105 };
106}
107MiiStoreData ConvertInfoToStoreData(const MiiInfo& info) {
108 MiiStoreData out{};
109 out.name = ResizeArray<char16_t, 11, 10>(info.name);
110 out.uuid = info.uuid;
111
112 MiiStoreBitFields bf{};
113
114 bf.hair_type.Assign(info.hair_type);
115 bf.mole_type.Assign(info.mole_type);
116 bf.height.Assign(info.height);
117 bf.hair_flip.Assign(info.hair_flip);
118 bf.weight.Assign(info.weight);
119 bf.hair_color.Assign(info.hair_color);
120
121 bf.gender.Assign(info.gender);
122 bf.eye_color.Assign(info.eye_color);
123 bf.eyebrow_color.Assign(info.eyebrow_color);
124 bf.mouth_color.Assign(info.mouth_color);
125 bf.facial_hair_color.Assign(info.facial_hair_color);
126
127 bf.mii_type.Assign(info.mii_type);
128 bf.glasses_color.Assign(info.glasses_color);
129 bf.font_region.Assign(info.font_region);
130 bf.eye_type.Assign(info.eye_type);
131 bf.mii_region.Assign(info.mii_region);
132 bf.mouth_type.Assign(info.mouth_type);
133 bf.glasses_scale.Assign(info.glasses_scale);
134 bf.eye_y.Assign(info.eye_y);
135
136 bf.mustache_type.Assign(info.mustache_type);
137 bf.eyebrow_type.Assign(info.eyebrow_type);
138 bf.beard_type.Assign(info.beard_type);
139 bf.nose_type.Assign(info.nose_type);
140 bf.mouth_aspect.Assign(info.mouth_aspect_ratio);
141 bf.nose_y.Assign(info.nose_y);
142 bf.eyebrow_aspect.Assign(info.eyebrow_aspect_ratio);
143 bf.mouth_y.Assign(info.mouth_y);
144
145 bf.eye_rotate.Assign(info.eye_rotate);
146 bf.mustache_y.Assign(info.mustache_y);
147 bf.eye_aspect.Assign(info.eye_aspect_ratio);
148 bf.glasses_y.Assign(info.glasses_y);
149 bf.eye_scale.Assign(info.eye_scale);
150 bf.mole_x.Assign(info.mole_x);
151 bf.mole_y.Assign(info.mole_y);
152
153 bf.glasses_type.Assign(info.glasses_type);
154 bf.face_type.Assign(info.face_type);
155 bf.favorite_color.Assign(info.favorite_color);
156 bf.face_wrinkle.Assign(info.face_wrinkle);
157 bf.face_color.Assign(info.face_color);
158 bf.eye_x.Assign(info.eye_x);
159 bf.face_makeup.Assign(info.face_makeup);
160
161 bf.eyebrow_rotate.Assign(info.eyebrow_rotate);
162 bf.eyebrow_scale.Assign(info.eyebrow_scale);
163 bf.eyebrow_y.Assign(info.eyebrow_y);
164 bf.eyebrow_x.Assign(info.eyebrow_x);
165 bf.mouth_scale.Assign(info.mouth_scale);
166 bf.nose_scale.Assign(info.nose_scale);
167 bf.mole_scale.Assign(info.mole_scale);
168 bf.mustache_scale.Assign(info.mustache_scale);
169
170 std::memcpy(out.data.data(), &bf, sizeof(MiiStoreBitFields));
171
172 return out;
173}
174
175} // namespace
176
177std::ostream& operator<<(std::ostream& os, Source source) {
178 if (static_cast<std::size_t>(source) >= SOURCE_NAMES.size()) {
179 return os << "[UNKNOWN SOURCE]";
180 }
181
182 os << SOURCE_NAMES.at(static_cast<std::size_t>(source));
183 return os;
184}
185
186std::u16string MiiInfo::Name() const {
187 return Common::UTF16StringFromFixedZeroTerminatedBuffer(name.data(), name.size());
188}
189
190bool operator==(const MiiInfo& lhs, const MiiInfo& rhs) {
191 return std::memcmp(&lhs, &rhs, sizeof(MiiInfo)) == 0;
192}
193
194bool operator!=(const MiiInfo& lhs, const MiiInfo& rhs) {
195 return !operator==(lhs, rhs);
196}
197
198std::u16string MiiStoreData::Name() const {
199 return Common::UTF16StringFromFixedZeroTerminatedBuffer(name.data(), name.size());
200}
201
202MiiManager::MiiManager() = default;
203
204MiiManager::~MiiManager() = default;
205
206MiiInfo MiiManager::CreateRandom(RandomParameters params) {
207 LOG_WARNING(Service_Mii,
208 "(STUBBED) called with params={:08X}{:08X}{:08X}, returning default Mii",
209 params.unknown_1, params.unknown_2, params.unknown_3);
210
211 return ConvertStoreDataToInfo(CreateMiiWithUniqueUUID());
212}
213
214MiiInfo MiiManager::CreateDefault(u32 index) {
215 const auto new_mii = CreateMiiWithUniqueUUID();
216
217 database.miis.at(index) = new_mii;
218
219 EnsureDatabasePartition();
220 return ConvertStoreDataToInfo(new_mii);
221}
222
223bool MiiManager::CheckUpdatedFlag() const {
224 return updated_flag;
225}
226
227void MiiManager::ResetUpdatedFlag() {
228 updated_flag = false;
229}
230
231bool MiiManager::IsTestModeEnabled() const {
232 return is_test_mode_enabled;
233}
234
235bool MiiManager::Empty() const {
236 return Size() == 0;
237}
238
239bool MiiManager::Full() const {
240 return Size() == MAX_MIIS;
241}
242
243void MiiManager::Clear() {
244 updated_flag = true;
245 std::fill(database.miis.begin(), database.miis.end(), MiiStoreData{});
246}
247
248u32 MiiManager::Size() const {
249 return static_cast<u32>(std::count_if(database.miis.begin(), database.miis.end(),
250 [](const MiiStoreData& elem) { return elem.uuid; }));
251}
252
253MiiInfo MiiManager::GetInfo(u32 index) const {
254 return ConvertStoreDataToInfo(GetStoreData(index));
255}
256
257MiiInfoElement MiiManager::GetInfoElement(u32 index) const {
258 return {GetInfo(index), Source::Database};
259}
260
261MiiStoreData MiiManager::GetStoreData(u32 index) const {
262 return database.miis.at(index);
263}
264
265MiiStoreDataElement MiiManager::GetStoreDataElement(u32 index) const {
266 return {GetStoreData(index), Source::Database};
267}
268
269bool MiiManager::Remove(Common::UUID uuid) {
270 const auto iter = std::find_if(database.miis.begin(), database.miis.end(),
271 [uuid](const MiiStoreData& elem) { return elem.uuid == uuid; });
272
273 if (iter == database.miis.end())
274 return false;
275
276 updated_flag = true;
277 *iter = MiiStoreData{};
278 EnsureDatabasePartition();
279 return true;
280}
281
282u32 MiiManager::IndexOf(Common::UUID uuid) const {
283 const auto iter = std::find_if(database.miis.begin(), database.miis.end(),
284 [uuid](const MiiStoreData& elem) { return elem.uuid == uuid; });
285
286 if (iter == database.miis.end())
287 return INVALID_INDEX;
288
289 return static_cast<u32>(std::distance(database.miis.begin(), iter));
290}
291
292u32 MiiManager::IndexOf(const MiiInfo& info) const {
293 const auto iter =
294 std::find_if(database.miis.begin(), database.miis.end(), [&info](const MiiStoreData& elem) {
295 return ConvertStoreDataToInfo(elem) == info;
296 });
297
298 if (iter == database.miis.end())
299 return INVALID_INDEX;
300
301 return static_cast<u32>(std::distance(database.miis.begin(), iter));
302}
303
304bool MiiManager::Move(Common::UUID uuid, u32 new_index) {
305 const auto index = IndexOf(uuid);
306
307 if (index == INVALID_INDEX || new_index >= MAX_MIIS)
308 return false;
309
310 updated_flag = true;
311 const auto moving = database.miis[index];
312 const auto replacing = database.miis[new_index];
313 if (replacing.uuid) {
314 database.miis[index] = replacing;
315 database.miis[new_index] = moving;
316 } else {
317 database.miis[index] = MiiStoreData{};
318 database.miis[new_index] = moving;
319 }
320
321 EnsureDatabasePartition();
322 return true;
323}
324
325bool MiiManager::AddOrReplace(const MiiStoreData& data) {
326 const auto index = IndexOf(data.uuid);
327
328 updated_flag = true;
329 if (index == INVALID_INDEX) {
330 const auto size = Size();
331 if (size == MAX_MIIS)
332 return false;
333 database.miis[size] = data;
334 } else {
335 database.miis[index] = data;
336 }
337
338 return true;
339}
340
341bool MiiManager::DestroyFile() {
342 database = DEFAULT_MII_DATABASE;
343 updated_flag = false;
344 return DeleteFile();
345}
346
347bool MiiManager::DeleteFile() {
348 const auto path = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) + MII_SAVE_DATABASE_PATH;
349 return FileUtil::Exists(path) && FileUtil::Delete(path);
350}
351
352void MiiManager::WriteToFile() {
353 const auto raw_path =
354 FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) + "/system/save/8000000000000030";
355 if (FileUtil::Exists(raw_path) && !FileUtil::IsDirectory(raw_path))
356 FileUtil::Delete(raw_path);
357
358 const auto path = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) + MII_SAVE_DATABASE_PATH;
359
360 if (!FileUtil::CreateFullPath(path)) {
361 LOG_WARNING(Service_Mii,
362 "Failed to create full path of MiiDatabase.dat. Create the directory "
363 "nand/system/save/8000000000000030 to mitigate this "
364 "issue.");
365 return;
366 }
367
368 FileUtil::IOFile save(path, "wb");
369
370 if (!save.IsOpen()) {
371 LOG_WARNING(Service_Mii, "Failed to write save data to file... No changes to user data "
372 "made in current session will be saved.");
373 return;
374 }
375
376 save.Resize(sizeof(MiiDatabase));
377 if (save.WriteBytes(&database, sizeof(MiiDatabase)) != sizeof(MiiDatabase)) {
378 LOG_WARNING(Service_Mii, "Failed to write all data to save file... Data may be malformed "
379 "and/or regenerated on next run.");
380 save.Resize(0);
381 }
382}
383
384void MiiManager::ReadFromFile() {
385 FileUtil::IOFile save(
386 FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) + MII_SAVE_DATABASE_PATH, "rb");
387
388 if (!save.IsOpen()) {
389 LOG_WARNING(Service_ACC, "Failed to load profile data from save data... Generating new "
390 "blank Mii database with no Miis.");
391 std::memcpy(&database, &DEFAULT_MII_DATABASE, sizeof(MiiDatabase));
392 return;
393 }
394
395 if (save.ReadBytes(&database, sizeof(MiiDatabase)) != sizeof(MiiDatabase)) {
396 LOG_WARNING(Service_ACC, "MiiDatabase.dat is smaller than expected... Generating new blank "
397 "Mii database with no Miis.");
398 std::memcpy(&database, &DEFAULT_MII_DATABASE, sizeof(MiiDatabase));
399 return;
400 }
401
402 EnsureDatabasePartition();
403}
404
405MiiStoreData MiiManager::CreateMiiWithUniqueUUID() const {
406 auto new_mii = DEFAULT_MII;
407
408 do {
409 new_mii.uuid = Common::UUID::Generate();
410 } while (IndexOf(new_mii.uuid) != INVALID_INDEX);
411
412 return new_mii;
413}
414
415void MiiManager::EnsureDatabasePartition() {
416 std::stable_partition(database.miis.begin(), database.miis.end(),
417 [](const MiiStoreData& elem) { return elem.uuid; });
418}
419
420} // namespace Service::Mii
diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h
deleted file mode 100644
index fc742816a..000000000
--- a/src/core/hle/service/mii/mii_manager.h
+++ /dev/null
@@ -1,273 +0,0 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/bit_field.h"
8#include "common/common_funcs.h"
9#include "common/uuid.h"
10
11namespace Service::Mii {
12
13constexpr std::size_t MAX_MIIS{100};
14constexpr u32 INVALID_INDEX{0xFFFFFFFF};
15
16struct RandomParameters {
17 u32 unknown_1{};
18 u32 unknown_2{};
19 u32 unknown_3{};
20};
21static_assert(sizeof(RandomParameters) == 0xC, "RandomParameters has incorrect size.");
22
23enum class Source : u32 {
24 Database = 0,
25 Default = 1,
26 Account = 2,
27 Friend = 3,
28};
29
30std::ostream& operator<<(std::ostream& os, Source source);
31
32struct MiiInfo {
33 Common::UUID uuid{Common::INVALID_UUID};
34 std::array<char16_t, 11> name{};
35 u8 font_region{};
36 u8 favorite_color{};
37 u8 gender{};
38 u8 height{};
39 u8 weight{};
40 u8 mii_type{};
41 u8 mii_region{};
42 u8 face_type{};
43 u8 face_color{};
44 u8 face_wrinkle{};
45 u8 face_makeup{};
46 u8 hair_type{};
47 u8 hair_color{};
48 bool hair_flip{};
49 u8 eye_type{};
50 u8 eye_color{};
51 u8 eye_scale{};
52 u8 eye_aspect_ratio{};
53 u8 eye_rotate{};
54 u8 eye_x{};
55 u8 eye_y{};
56 u8 eyebrow_type{};
57 u8 eyebrow_color{};
58 u8 eyebrow_scale{};
59 u8 eyebrow_aspect_ratio{};
60 u8 eyebrow_rotate{};
61 u8 eyebrow_x{};
62 u8 eyebrow_y{};
63 u8 nose_type{};
64 u8 nose_scale{};
65 u8 nose_y{};
66 u8 mouth_type{};
67 u8 mouth_color{};
68 u8 mouth_scale{};
69 u8 mouth_aspect_ratio{};
70 u8 mouth_y{};
71 u8 facial_hair_color{};
72 u8 beard_type{};
73 u8 mustache_type{};
74 u8 mustache_scale{};
75 u8 mustache_y{};
76 u8 glasses_type{};
77 u8 glasses_color{};
78 u8 glasses_scale{};
79 u8 glasses_y{};
80 u8 mole_type{};
81 u8 mole_scale{};
82 u8 mole_x{};
83 u8 mole_y{};
84 INSERT_PADDING_BYTES(1);
85
86 std::u16string Name() const;
87};
88static_assert(sizeof(MiiInfo) == 0x58, "MiiInfo has incorrect size.");
89static_assert(std::has_unique_object_representations_v<MiiInfo>,
90 "All bits of MiiInfo must contribute to its value.");
91
92bool operator==(const MiiInfo& lhs, const MiiInfo& rhs);
93bool operator!=(const MiiInfo& lhs, const MiiInfo& rhs);
94
95#pragma pack(push, 4)
96struct MiiInfoElement {
97 MiiInfo info{};
98 Source source{};
99};
100static_assert(sizeof(MiiInfoElement) == 0x5C, "MiiInfoElement has incorrect size.");
101
102struct MiiStoreBitFields {
103 union {
104 u32 word_0{};
105
106 BitField<24, 8, u32> hair_type;
107 BitField<23, 1, u32> mole_type;
108 BitField<16, 7, u32> height;
109 BitField<15, 1, u32> hair_flip;
110 BitField<8, 7, u32> weight;
111 BitField<0, 7, u32> hair_color;
112 };
113
114 union {
115 u32 word_1{};
116
117 BitField<31, 1, u32> gender;
118 BitField<24, 7, u32> eye_color;
119 BitField<16, 7, u32> eyebrow_color;
120 BitField<8, 7, u32> mouth_color;
121 BitField<0, 7, u32> facial_hair_color;
122 };
123
124 union {
125 u32 word_2{};
126
127 BitField<31, 1, u32> mii_type;
128 BitField<24, 7, u32> glasses_color;
129 BitField<22, 2, u32> font_region;
130 BitField<16, 6, u32> eye_type;
131 BitField<14, 2, u32> mii_region;
132 BitField<8, 6, u32> mouth_type;
133 BitField<5, 3, u32> glasses_scale;
134 BitField<0, 5, u32> eye_y;
135 };
136
137 union {
138 u32 word_3{};
139
140 BitField<29, 3, u32> mustache_type;
141 BitField<24, 5, u32> eyebrow_type;
142 BitField<21, 3, u32> beard_type;
143 BitField<16, 5, u32> nose_type;
144 BitField<13, 3, u32> mouth_aspect;
145 BitField<8, 5, u32> nose_y;
146 BitField<5, 3, u32> eyebrow_aspect;
147 BitField<0, 5, u32> mouth_y;
148 };
149
150 union {
151 u32 word_4{};
152
153 BitField<29, 3, u32> eye_rotate;
154 BitField<24, 5, u32> mustache_y;
155 BitField<21, 3, u32> eye_aspect;
156 BitField<16, 5, u32> glasses_y;
157 BitField<13, 3, u32> eye_scale;
158 BitField<8, 5, u32> mole_x;
159 BitField<0, 5, u32> mole_y;
160 };
161
162 union {
163 u32 word_5{};
164
165 BitField<24, 5, u32> glasses_type;
166 BitField<20, 4, u32> face_type;
167 BitField<16, 4, u32> favorite_color;
168 BitField<12, 4, u32> face_wrinkle;
169 BitField<8, 4, u32> face_color;
170 BitField<4, 4, u32> eye_x;
171 BitField<0, 4, u32> face_makeup;
172 };
173
174 union {
175 u32 word_6{};
176
177 BitField<28, 4, u32> eyebrow_rotate;
178 BitField<24, 4, u32> eyebrow_scale;
179 BitField<20, 4, u32> eyebrow_y;
180 BitField<16, 4, u32> eyebrow_x;
181 BitField<12, 4, u32> mouth_scale;
182 BitField<8, 4, u32> nose_scale;
183 BitField<4, 4, u32> mole_scale;
184 BitField<0, 4, u32> mustache_scale;
185 };
186};
187static_assert(sizeof(MiiStoreBitFields) == 0x1C, "MiiStoreBitFields has incorrect size.");
188static_assert(std::is_trivially_copyable_v<MiiStoreBitFields>,
189 "MiiStoreBitFields is not trivially copyable.");
190
191struct MiiStoreData {
192 // This corresponds to the above structure MiiStoreBitFields. I did it like this because the
193 // BitField<> type makes this (and any thing that contains it) not trivially copyable, which is
194 // not suitable for our uses.
195 std::array<u8, 0x1C> data{};
196 static_assert(sizeof(MiiStoreBitFields) == sizeof(data), "data field has incorrect size.");
197
198 std::array<char16_t, 10> name{};
199 Common::UUID uuid{Common::INVALID_UUID};
200 u16 crc_1{};
201 u16 crc_2{};
202
203 std::u16string Name() const;
204};
205static_assert(sizeof(MiiStoreData) == 0x44, "MiiStoreData has incorrect size.");
206
207struct MiiStoreDataElement {
208 MiiStoreData data{};
209 Source source{};
210};
211static_assert(sizeof(MiiStoreDataElement) == 0x48, "MiiStoreDataElement has incorrect size.");
212
213struct MiiDatabase {
214 u32 magic{}; // 'NFDB'
215 std::array<MiiStoreData, MAX_MIIS> miis{};
216 INSERT_PADDING_BYTES(1);
217 u8 count{};
218 u16 crc{};
219};
220static_assert(sizeof(MiiDatabase) == 0x1A98, "MiiDatabase has incorrect size.");
221#pragma pack(pop)
222
223// The Mii manager is responsible for loading and storing the Miis to the database in NAND along
224// with providing an easy interface for HLE emulation of the mii service.
225class MiiManager {
226public:
227 MiiManager();
228 ~MiiManager();
229
230 MiiInfo CreateRandom(RandomParameters params);
231 MiiInfo CreateDefault(u32 index);
232
233 bool CheckUpdatedFlag() const;
234 void ResetUpdatedFlag();
235
236 bool IsTestModeEnabled() const;
237
238 bool Empty() const;
239 bool Full() const;
240
241 void Clear();
242
243 u32 Size() const;
244
245 MiiInfo GetInfo(u32 index) const;
246 MiiInfoElement GetInfoElement(u32 index) const;
247 MiiStoreData GetStoreData(u32 index) const;
248 MiiStoreDataElement GetStoreDataElement(u32 index) const;
249
250 bool Remove(Common::UUID uuid);
251 u32 IndexOf(Common::UUID uuid) const;
252 u32 IndexOf(const MiiInfo& info) const;
253
254 bool Move(Common::UUID uuid, u32 new_index);
255 bool AddOrReplace(const MiiStoreData& data);
256
257 bool DestroyFile();
258 bool DeleteFile();
259
260private:
261 void WriteToFile();
262 void ReadFromFile();
263
264 MiiStoreData CreateMiiWithUniqueUUID() const;
265
266 void EnsureDatabasePartition();
267
268 MiiDatabase database;
269 bool updated_flag{};
270 bool is_test_mode_enabled{};
271};
272
273}; // namespace Service::Mii
diff --git a/src/core/hle/service/mii/raw_data.cpp b/src/core/hle/service/mii/raw_data.cpp
new file mode 100644
index 000000000..25d7bae0c
--- /dev/null
+++ b/src/core/hle/service/mii/raw_data.cpp
@@ -0,0 +1,2261 @@
1// MIT License
2//
3// Copyright (c) Ryujinx Team and Contributors
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6// associated documentation files (the "Software"), to deal in the Software without restriction,
7// including without limitation the rights to use, copy, modify, merge, publish, distribute,
8// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
9// furnished to do so, subject to the following conditions:
10//
11// The above copyright notice and this permission notice shall be included in all copies or
12// substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
15// NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
17// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19//
20
21#include "core/hle/service/mii/raw_data.h"
22
23namespace Service::Mii::RawData {
24
25const std::array<u8, 1728> DefaultMii{
26 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
29 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
30 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
31 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
32 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
33 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
36 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
42 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
44 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
45 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
50 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
56 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
58 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
59 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
60 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
63 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00,
66 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
69 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
70 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
71 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
72 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
77 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x6f, 0x00,
79 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x21, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
83 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
84 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
85 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
86 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
87 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
90 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00,
93 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
96 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
98 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
99 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
104 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x6f, 0x00,
106 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x0e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
109 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
110 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
111 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
112 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
113 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
114 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
117 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
118 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
119 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x6f, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00,
120 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
123 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
125 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
126 0x04, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
131 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x00, 0x6f, 0x00,
133 0x20, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
134
135const std::array<u8, 3672> RandomMiiFaceline{
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
138 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
139 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
149 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
151 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
152 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
164 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
175 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
176 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
177 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
178 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
188 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
189 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
190 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
191 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
195 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
196 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
202 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
203 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
215 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
216 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
226 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
227 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
228 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
229 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
240 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
241 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
252 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
253 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
254 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
266 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
277 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
278 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
279 0x05, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
291 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
292 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
295 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
296 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
298 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
299 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
302 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
303 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
304 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
305 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
308 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
309 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
311 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
315 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
317 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
318 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
323 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
324 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
325 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
326 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
328 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
329 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
330 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
331 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
333 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
334 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
335 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
342 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
343 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
353 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
355 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
356 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
366
367const std::array<u8, 1200> RandomMiiFacelineColor{
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
369 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
370 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
371 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
381 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
383 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
395 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
396 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
402 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
403 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
404 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x0a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
407 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
408 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
411 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
421 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
425 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
426 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
427 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
428 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
429 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
431 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
432 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
433 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
434 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
436 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
437 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
439 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
441 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
442 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
443
444const std::array<u8, 3672> RandomMiiFacelineWrinkle{
445 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
446 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
451 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
458 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
465 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
466 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
467 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
471 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
474 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
476 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
479 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
484 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
487 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
488 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
489 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
500 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
501 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
508 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
509 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
513 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
514 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
521 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
523 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
524 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
525 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
526 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
527 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
529 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
531 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
532 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
535 0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
536 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
537 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
538 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
539 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
540 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
542 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
543 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
544 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
545 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
548 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
549 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
550 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
551 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
552 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
553 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
554 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
566 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
568 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
569 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
571 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
573 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
585 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
591 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
593 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
594 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
595 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
596 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
597 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
598 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
603 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
604 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
606 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
607 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
608 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
611 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
615 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
616 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
617 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
624 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
629 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
637 0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
638 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
639 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
640 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
641 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
642 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
649 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
650 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
651 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
652 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
653 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
654 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
656 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
657 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
662 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
663 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
664 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
665 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
666 0x0a, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
667 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
668 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
675
676const std::array<u8, 3672> RandomMiiFacelineMakeup{
677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
681 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
682 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
683 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
693 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
694 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
695 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
696 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
703 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
706 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
707 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
708 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
709 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
716 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
721 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
734 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
744 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
747 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
748 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
751 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
754 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
757 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
758 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
759 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
761 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
762 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
767 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
769 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
772 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
773 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
774 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
775 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
779 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
785 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
797 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
798 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
799 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
802 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
804 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
805 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
808 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
809 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
810 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
811 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
812 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
813 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
814 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
815 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
817 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
818 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
820 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
821 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
822 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
823 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
824 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
825 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
826 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
827 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
829 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
830 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
831 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
832 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
833 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
834 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
835 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
836 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
837 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
838 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
839 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
840 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
843 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
844 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
845 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
846 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
847 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
848 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
849 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
850 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
851 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
852 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
853 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
854 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
856 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
858 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
859 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
860 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
861 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
862 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
863 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
864 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
865 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
868 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
869 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
870 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
871 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
872 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
873 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
874 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
875 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
876 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
880 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
882 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
883 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
884 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
885 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
886 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
887 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
888 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
889 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
890 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
891 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
892 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
893 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
894 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
895 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
897 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
898 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
899 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
900 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
901 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
902 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
903 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
904 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
905 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
906 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
907
908const std::array<u8, 3672> RandomMiiHairType{
909 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
910 0x0d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
911 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
912 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
913 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
914 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
915 0x34, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
916 0x40, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
917 0x56, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
918 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
919 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
920 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
921 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
922 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
923 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
924 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
925 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
926 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
927 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
928 0x36, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
929 0x42, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00,
930 0x56, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
931 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
932 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
933 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
934 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
935 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
936 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
937 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
938 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
939 0x2d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00,
940 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
941 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
942 0x49, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
943 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
944 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
945 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
946 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
947 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
948 0x26, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
949 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
950 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
951 0x2a, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
952 0x2f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
953 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
954 0x37, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
955 0x3c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
956 0x43, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00,
957 0x4c, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
958 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
959 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
960 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
961 0x0d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
962 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
963 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
964 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
965 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
966 0x34, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00,
967 0x38, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
968 0x40, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00,
969 0x44, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00,
970 0x51, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
971 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
972 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
973 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
974 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
975 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
976 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
977 0x2c, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
978 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
979 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
980 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
981 0x41, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
982 0x46, 0x00, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00,
983 0x56, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
984 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
985 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
986 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
987 0x1e, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
988 0x2d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
989 0x36, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
990 0x41, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
992 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
993 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
994 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
995 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
996 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
997 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
998 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
999 0x13, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
1000 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
1001 0x2d, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
1002 0x36, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
1003 0x41, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00,
1004 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1005 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1006 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1007 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1008 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1009 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1010 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1011 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1012 0x0d, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
1013 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
1014 0x2f, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
1015 0x37, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00,
1016 0x43, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1017 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1018 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1019 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1020 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1021 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1022 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1023 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1024 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1025 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1026 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1027 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1028 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1029 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
1030 0x16, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
1031 0x1c, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00,
1032 0x3e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
1033 0x4c, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
1034 0x53, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1035 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1036 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1037 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1038 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1039 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1040 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1041 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1042 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
1043 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
1044 0x2e, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
1045 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
1046 0x4a, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
1047 0x53, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00,
1048 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1049 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1050 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1051 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1052 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1053 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1054 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1055 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
1056 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
1057 0x32, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
1058 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
1059 0x4d, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00,
1060 0x54, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1061 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1062 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
1063 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1064 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1065 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1066 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1067 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1068 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
1069 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
1070 0x2a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
1071 0x3e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00,
1072 0x47, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
1073 0x51, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x56, 0x00, 0x00, 0x00,
1074 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1075 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1076 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1077 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1078 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1079 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1080 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1081 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1082 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00,
1083 0x3a, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
1084 0x40, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00,
1085 0x4a, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00,
1086 0x53, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1087 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1088 0x01, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1089 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1090 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1091 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1092 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1093 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
1094 0x16, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
1095 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
1096 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
1097 0x45, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
1098 0x4f, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00,
1099 0x54, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1101 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1102 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1103 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1104 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1105 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1106 0x3a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
1107 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1113 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
1114 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1115 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1116 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1117 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1118 0x15, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
1119 0x3e, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00,
1120 0x51, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1126 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1127 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1128 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1129 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1130 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
1131 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00,
1132 0x45, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0x00,
1133 0x53, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1139
1140const std::array<u8, 1800> RandomMiiHairColor{
1141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1146 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1147 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1148 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1149 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1150 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1154 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1166 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1168 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1169 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1170 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1171 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1172 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1173 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1174 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1176 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1179 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1180 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1181 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1182 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1183 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1184 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1185 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1188 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1189 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1191 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1192 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1193 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1194 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1195 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1196 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1197 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1198 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1201 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1202 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1204 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1205 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1206 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1207 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1208 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1209 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1212 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1216 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1220 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1221 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1223 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1229 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1231 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1232 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1233 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1234 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1241 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1242 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1243 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1244 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1245 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1246 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1248 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1254
1255const std::array<u8, 3672> RandomMiiEyeType{
1256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
1257 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1258 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1259 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1260 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1261 0x24, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
1262 0x2b, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
1263 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1265 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1267 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1268 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1269 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1270 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1271 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1272 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
1273 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
1274 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
1275 0x2f, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
1276 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1277 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1281 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1282 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1283 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1284 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1285 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
1286 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
1287 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
1288 0x2f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
1289 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1294 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1295 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1296 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1297 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1298 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
1299 0x16, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
1300 0x20, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1301 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
1302 0x2c, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
1303 0x35, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
1304 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1305 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1306 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1307 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
1308 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1309 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1310 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1311 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
1312 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
1313 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
1314 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
1315 0x2f, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
1316 0x37, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1318 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1320 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1321 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1322 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1323 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1324 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
1325 0x1d, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1326 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
1327 0x29, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
1328 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
1329 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1330 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1331 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1332 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1333 0x02, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1334 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1335 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1336 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1337 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
1338 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
1339 0x29, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
1340 0x35, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
1341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1346 0x1e, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1347 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1348 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1349 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
1350 0x16, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1351 0x24, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
1352 0x2c, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
1353 0x37, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1358 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
1359 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1360 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1361 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1362 0x12, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
1363 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
1364 0x25, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,
1365 0x30, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00,
1366 0x35, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1372 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1373 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1374 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1375 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
1376 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
1377 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1378 0x23, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
1379 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
1380 0x2f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00,
1381 0x39, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1384 0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1385 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1386 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1387 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1388 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
1389 0x19, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
1390 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
1391 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
1392 0x2a, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
1393 0x30, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
1394 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1396 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1397 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1398 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1399 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1400 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1401 0x13, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1402 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
1403 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
1404 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
1405 0x2a, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
1406 0x30, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
1407 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1409 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00,
1410 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1411 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1412 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1413 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1414 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
1415 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
1416 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
1417 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
1418 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00,
1419 0x2a, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00,
1420 0x30, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
1421 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1422 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1423 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1424 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1425 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1426 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1427 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
1428 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
1429 0x1d, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
1430 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
1431 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
1432 0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
1433 0x35, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
1434 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1435 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1436 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1437 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1438 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1439 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1440 0x15, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1441 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
1442 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1443 0x23, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
1444 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
1445 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00,
1446 0x36, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
1447 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1448 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1449 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1450 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1451 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1452 0x13, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1453 0x1b, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
1454 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
1455 0x27, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00,
1456 0x2d, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1457 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1458 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1460 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1461 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1462 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1463 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1464 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1465 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
1466 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
1467 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
1468 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
1469 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1471 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1472 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1473 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1474 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1475 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1476 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1477 0x10, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
1478 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00,
1479 0x1c, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
1480 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00,
1481 0x28, 0x00, 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00,
1482 0x2e, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1483 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1484 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1486
1487const std::array<u8, 588> RandomMiiEyeColor{
1488 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1489 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1490 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1491 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1492 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1493 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1494 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1496 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1497 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1500 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1501 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1502 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1503 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1504 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1505 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1506 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1507 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1508 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1509 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1513 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1514 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1515 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1516 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1517 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1518 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1519 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1520 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1521 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1522 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1523 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1524 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1525
1526const std::array<u8, 3672> RandomMiiEyebrowType{
1527 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1528 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1529 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1530 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1531 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1532 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1533 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1534 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1536 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1537 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1539 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1540 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1541 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1542 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1543 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1544 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1545 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1546 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1547 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1552 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1553 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1554 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1555 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1556 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1557 0x0e, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1558 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1559 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1560 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1561 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1562 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1563 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1564 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1565 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1566 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1567 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1568 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1569 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1570 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1571 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
1572 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1573 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1574 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1575 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1576 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1578 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
1579 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1580 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1581 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1582 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1583 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
1584 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1585 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1586 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1587 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1588 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1589 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1590 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1591 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1592 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1593 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1594 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1595 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1596 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1597 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1598 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1599 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1600 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1601 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1602 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1603 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1604 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1605 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1606 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1607 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1608 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1609 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1611 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1612 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1613 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1614 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1615 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1616 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1617 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1618 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1619 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1620 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1621 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
1622 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1623 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1624 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1625 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1627 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1628 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1629 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
1630 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1631 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1632 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1633 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
1634 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
1635 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1637 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1638 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1643 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1644 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1645 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1647 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1648 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1649 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1650 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1651 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1652 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1653 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1654 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1655 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1656 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1657 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1658 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1659 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1661 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1662 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1663 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1664 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1667 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1668 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1669 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1670 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1674 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1675 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1676 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1677 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1678 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1679 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1680 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1681 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1682 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1683 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1684 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1685 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1686 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1687 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1689 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1691 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1692 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1693 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1694 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1695 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1696 0x0f, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1697 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1698 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1699 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1700 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1701 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1702 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1703 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1704 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1705 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1706 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1707 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1708 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1709 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1710 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1711 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1712 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1713 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1714 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1715 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1716 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1717 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1718 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1719 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1720 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1721 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1722 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1723 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1724 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1726 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1727 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1728 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1729 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1730 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1731 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1732 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1733 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1734 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1735 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1736 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1737 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1738 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1739 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1740 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1741 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1742 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1743 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1744 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1745 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1746 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1747 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1748 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1749 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1751 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1752 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1753 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1754 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1755 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1756 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1757
1758const std::array<u8, 3672> RandomMiiNoseType{
1759 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1760 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1761 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1762 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1763 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1764 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1766 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1767 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1768 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1769 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1770 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1771 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1772 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1773 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1774 0x05, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1775 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1776 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1777 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1778 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1779 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1781 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1782 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1783 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1784 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1785 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1786 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1787 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1788 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1789 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1791 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1792 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1793 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1795 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1796 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1797 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1798 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1799 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1800 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1801 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1802 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1803 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1804 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1805 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1806 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1807 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1808 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
1811 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1812 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1813 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1814 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1815 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1816 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1817 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1818 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1819 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1821 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1822 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1823 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1824 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1825 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1826 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1827 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1828 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1829 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1830 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1831 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1832 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1833 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1834 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1836 0x02, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1837 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
1838 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1839 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1840 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1841 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1842 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1844 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1845 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1846 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1847 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1848 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1849 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1850 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1851 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1852 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1853 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1854 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1855 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1856 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1857 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1858 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1861 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1862 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1863 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
1864 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1865 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1866 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1867 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1868 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1869 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1871 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1872 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1873 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1874 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1875 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1876 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1877 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1878 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1879 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1880 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1881 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1882 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1883 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1884 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1885 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1886 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1887 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1888 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1889 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1890 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1891 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1892 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1893 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1894 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1895 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1896 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1897 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1898 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1899 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1900 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1901 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1902 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1903 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1904 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1905 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1906 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1907 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1908 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1909 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1910 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1911 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1912 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
1913 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1914 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1915 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
1916 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1917 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1918 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1919 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1920 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1921 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1922 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1923 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1924 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1925 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1926 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1927 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1928 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1929 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1930 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1931 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1932 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1933 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1934 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1935 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1936 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1937 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1938 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1939 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1940 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1941 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1942 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1943 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1944 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1945 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1946 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1947 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1948 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1949 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1950 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
1951 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
1952 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
1953 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
1954 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1955 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1956 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1957 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1958 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1959 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1960 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1961 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1962 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1963 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
1964 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
1965 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1966 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1967 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1968 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1969 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1970 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1971 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1972 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1973 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1974 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1975 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
1976 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1977 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1978 0x08, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
1979 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1980 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1981 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1982 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1983 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1984 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1985 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1986 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1987 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1988 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
1989
1990const std::array<u8, 3672> RandomMiiMouthType{
1991 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
1992 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
1993 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
1994 0x0c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
1995 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
1996 0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
1997 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
1998 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1999 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2000 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2001 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2002 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2003 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2004 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2005 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
2006 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
2007 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
2008 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
2009 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
2010 0x1c, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
2011 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2012 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2013 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2014 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2015 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2016 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2017 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2018 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
2019 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
2020 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
2021 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
2022 0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00,
2023 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
2024 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2025 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2026 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2027 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2028 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2029 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2030 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
2031 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
2032 0x0a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
2033 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
2034 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
2035 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
2036 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2037 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2038 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2039 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2040 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2041 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2042 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
2043 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
2044 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
2045 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2046 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
2047 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
2048 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
2049 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2050 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2051 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2052 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2053 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2054 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2055 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2056 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
2057 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
2058 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
2059 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
2060 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
2061 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
2062 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2063 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2064 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2065 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2066 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2067 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2068 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2069 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
2070 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2071 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
2072 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
2073 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
2074 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2075 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2076 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2077 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2078 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2079 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2080 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2081 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
2082 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
2083 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
2084 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
2085 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
2086 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
2087 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2088 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2089 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2090 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2091 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2092 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2093 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
2094 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
2095 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00,
2096 0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2097 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
2098 0x13, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
2099 0x17, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
2100 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2107 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
2108 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
2109 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
2110 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
2111 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
2112 0x1e, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
2113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2118 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2119 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2120 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
2121 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
2122 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
2123 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
2124 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00,
2125 0x1e, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
2126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2131 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2132 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2133 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
2134 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
2135 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
2136 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
2137 0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00,
2138 0x21, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2144 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
2145 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
2146 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
2147 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2148 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
2149 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
2150 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
2151 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2157 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2158 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
2159 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
2160 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2161 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
2162 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
2163 0x1a, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
2164 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2165 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2166 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2167 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2168 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2170 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2171 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
2172 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
2173 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
2174 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
2175 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
2176 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2182 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2183 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
2184 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
2185 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
2186 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
2187 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
2188 0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
2189 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2190 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2191 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2192 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2193 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2194 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2195 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00,
2196 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
2197 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
2198 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00,
2199 0x0e, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
2200 0x12, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00,
2201 0x17, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
2202 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2203 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2204 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
2208 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2209 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
2210 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
2211 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
2212 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
2213 0x13, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00,
2214 0x19, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
2215 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2218 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2219 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2220 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2221
2222const std::array<u8, 588> RandomMiiGlassType{
2223 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
2224 0x60, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2227 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2229 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2235 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00,
2236 0x56, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00,
2237 0x60, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2238 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2246 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2247 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
2248 0x4e, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x00, 0x00, 0x00,
2249 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00,
2250 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2251 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2252 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2253 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2254 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2255 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2256 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2257 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2258 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2259 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
2260
2261} // namespace Service::Mii::RawData
diff --git a/src/core/hle/service/mii/raw_data.h b/src/core/hle/service/mii/raw_data.h
new file mode 100644
index 000000000..a02a5c0fd
--- /dev/null
+++ b/src/core/hle/service/mii/raw_data.h
@@ -0,0 +1,27 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8
9#include "common/common_types.h"
10
11namespace Service::Mii::RawData {
12
13extern const std::array<u8, 1728> DefaultMii;
14extern const std::array<u8, 3672> RandomMiiFaceline;
15extern const std::array<u8, 1200> RandomMiiFacelineColor;
16extern const std::array<u8, 3672> RandomMiiFacelineWrinkle;
17extern const std::array<u8, 3672> RandomMiiFacelineMakeup;
18extern const std::array<u8, 3672> RandomMiiHairType;
19extern const std::array<u8, 1800> RandomMiiHairColor;
20extern const std::array<u8, 3672> RandomMiiEyeType;
21extern const std::array<u8, 588> RandomMiiEyeColor;
22extern const std::array<u8, 3672> RandomMiiEyebrowType;
23extern const std::array<u8, 3672> RandomMiiNoseType;
24extern const std::array<u8, 3672> RandomMiiMouthType;
25extern const std::array<u8, 588> RandomMiiGlassType;
26
27} // namespace Service::Mii::RawData
diff --git a/src/core/hle/service/mii/types.h b/src/core/hle/service/mii/types.h
new file mode 100644
index 000000000..d65a1055e
--- /dev/null
+++ b/src/core/hle/service/mii/types.h
@@ -0,0 +1,67 @@
1// Copyright 2020 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_funcs.h"
8#include "common/common_types.h"
9
10namespace Service::Mii {
11
12enum class Age : u32 {
13 Young,
14 Normal,
15 Old,
16 All,
17};
18
19enum class BeardType : u32 {
20 None,
21 Beard1,
22 Beard2,
23 Beard3,
24 Beard4,
25 Beard5,
26};
27
28enum class BeardAndMustacheFlag : u32 { Beard = 1, Mustache, All = Beard | Mustache };
29DECLARE_ENUM_FLAG_OPERATORS(BeardAndMustacheFlag);
30
31enum class FontRegion : u32 {
32 Standard,
33 China,
34 Korea,
35 Taiwan,
36};
37
38enum class Gender : u32 {
39 Male,
40 Female,
41 All,
42 Maximum = Female,
43};
44
45enum class HairFlip : u32 {
46 Left,
47 Right,
48 Maximum = Right,
49};
50
51enum class MustacheType : u32 {
52 None,
53 Mustache1,
54 Mustache2,
55 Mustache3,
56 Mustache4,
57 Mustache5,
58};
59
60enum class Race : u32 {
61 Black,
62 White,
63 Asian,
64 All,
65};
66
67} // namespace Service::Mii
diff --git a/src/core/settings.cpp b/src/core/settings.cpp
index d3886c4ec..e8a6f2a6e 100644
--- a/src/core/settings.cpp
+++ b/src/core/settings.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 <string_view>
6
5#include "common/file_util.h" 7#include "common/file_util.h"
6#include "core/core.h" 8#include "core/core.h"
7#include "core/gdbstub/gdbstub.h" 9#include "core/gdbstub/gdbstub.h"
@@ -65,18 +67,18 @@ Values values = {};
65bool configuring_global = true; 67bool configuring_global = true;
66 68
67std::string GetTimeZoneString() { 69std::string GetTimeZoneString() {
68 static constexpr std::array<const char*, 46> timezones{{ 70 static constexpr std::array timezones{
69 "auto", "default", "CET", "CST6CDT", "Cuba", "EET", "Egypt", "Eire", 71 "auto", "default", "CET", "CST6CDT", "Cuba", "EET", "Egypt", "Eire",
70 "EST", "EST5EDT", "GB", "GB-Eire", "GMT", "GMT+0", "GMT-0", "GMT0", 72 "EST", "EST5EDT", "GB", "GB-Eire", "GMT", "GMT+0", "GMT-0", "GMT0",
71 "Greenwich", "Hongkong", "HST", "Iceland", "Iran", "Israel", "Jamaica", "Japan", 73 "Greenwich", "Hongkong", "HST", "Iceland", "Iran", "Israel", "Jamaica", "Japan",
72 "Kwajalein", "Libya", "MET", "MST", "MST7MDT", "Navajo", "NZ", "NZ-CHAT", 74 "Kwajalein", "Libya", "MET", "MST", "MST7MDT", "Navajo", "NZ", "NZ-CHAT",
73 "Poland", "Portugal", "PRC", "PST8PDT", "ROC", "ROK", "Singapore", "Turkey", 75 "Poland", "Portugal", "PRC", "PST8PDT", "ROC", "ROK", "Singapore", "Turkey",
74 "UCT", "Universal", "UTC", "W-SU", "WET", "Zulu", 76 "UCT", "Universal", "UTC", "W-SU", "WET", "Zulu",
75 }}; 77 };
76
77 ASSERT(Settings::values.time_zone_index.GetValue() < timezones.size());
78 78
79 return timezones[Settings::values.time_zone_index.GetValue()]; 79 const auto time_zone_index = static_cast<std::size_t>(values.time_zone_index.GetValue());
80 ASSERT(time_zone_index < timezones.size());
81 return timezones[time_zone_index];
80} 82}
81 83
82void Apply() { 84void Apply() {
@@ -91,41 +93,40 @@ void Apply() {
91 Service::HID::ReloadInputDevices(); 93 Service::HID::ReloadInputDevices();
92} 94}
93 95
94template <typename T>
95void LogSetting(const std::string& name, const T& value) {
96 LOG_INFO(Config, "{}: {}", name, value);
97}
98
99void LogSettings() { 96void LogSettings() {
97 const auto log_setting = [](std::string_view name, const auto& value) {
98 LOG_INFO(Config, "{}: {}", name, value);
99 };
100
100 LOG_INFO(Config, "yuzu Configuration:"); 101 LOG_INFO(Config, "yuzu Configuration:");
101 LogSetting("Controls_UseDockedMode", Settings::values.use_docked_mode); 102 log_setting("Controls_UseDockedMode", values.use_docked_mode);
102 LogSetting("System_RngSeed", Settings::values.rng_seed.GetValue().value_or(0)); 103 log_setting("System_RngSeed", values.rng_seed.GetValue().value_or(0));
103 LogSetting("System_CurrentUser", Settings::values.current_user); 104 log_setting("System_CurrentUser", values.current_user);
104 LogSetting("System_LanguageIndex", Settings::values.language_index.GetValue()); 105 log_setting("System_LanguageIndex", values.language_index.GetValue());
105 LogSetting("System_RegionIndex", Settings::values.region_index.GetValue()); 106 log_setting("System_RegionIndex", values.region_index.GetValue());
106 LogSetting("System_TimeZoneIndex", Settings::values.time_zone_index.GetValue()); 107 log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue());
107 LogSetting("Core_UseMultiCore", Settings::values.use_multi_core.GetValue()); 108 log_setting("Core_UseMultiCore", values.use_multi_core.GetValue());
108 LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor.GetValue()); 109 log_setting("Renderer_UseResolutionFactor", values.resolution_factor.GetValue());
109 LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit.GetValue()); 110 log_setting("Renderer_UseFrameLimit", values.use_frame_limit.GetValue());
110 LogSetting("Renderer_FrameLimit", Settings::values.frame_limit.GetValue()); 111 log_setting("Renderer_FrameLimit", values.frame_limit.GetValue());
111 LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache.GetValue()); 112 log_setting("Renderer_UseDiskShaderCache", values.use_disk_shader_cache.GetValue());
112 LogSetting("Renderer_GPUAccuracyLevel", Settings::values.gpu_accuracy.GetValue()); 113 log_setting("Renderer_GPUAccuracyLevel", values.gpu_accuracy.GetValue());
113 LogSetting("Renderer_UseAsynchronousGpuEmulation", 114 log_setting("Renderer_UseAsynchronousGpuEmulation",
114 Settings::values.use_asynchronous_gpu_emulation.GetValue()); 115 values.use_asynchronous_gpu_emulation.GetValue());
115 LogSetting("Renderer_UseVsync", Settings::values.use_vsync.GetValue()); 116 log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
116 LogSetting("Renderer_UseAssemblyShaders", Settings::values.use_assembly_shaders.GetValue()); 117 log_setting("Renderer_UseAssemblyShaders", values.use_assembly_shaders.GetValue());
117 LogSetting("Renderer_AnisotropicFilteringLevel", Settings::values.max_anisotropy.GetValue()); 118 log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
118 LogSetting("Audio_OutputEngine", Settings::values.sink_id); 119 log_setting("Audio_OutputEngine", values.sink_id);
119 LogSetting("Audio_EnableAudioStretching", Settings::values.enable_audio_stretching.GetValue()); 120 log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
120 LogSetting("Audio_OutputDevice", Settings::values.audio_device_id); 121 log_setting("Audio_OutputDevice", values.audio_device_id);
121 LogSetting("DataStorage_UseVirtualSd", Settings::values.use_virtual_sd); 122 log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd);
122 LogSetting("DataStorage_NandDir", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)); 123 log_setting("DataStorage_NandDir", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir));
123 LogSetting("DataStorage_SdmcDir", FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)); 124 log_setting("DataStorage_SdmcDir", FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir));
124 LogSetting("Debugging_UseGdbstub", Settings::values.use_gdbstub); 125 log_setting("Debugging_UseGdbstub", values.use_gdbstub);
125 LogSetting("Debugging_GdbstubPort", Settings::values.gdbstub_port); 126 log_setting("Debugging_GdbstubPort", values.gdbstub_port);
126 LogSetting("Debugging_ProgramArgs", Settings::values.program_args); 127 log_setting("Debugging_ProgramArgs", values.program_args);
127 LogSetting("Services_BCATBackend", Settings::values.bcat_backend); 128 log_setting("Services_BCATBackend", values.bcat_backend);
128 LogSetting("Services_BCATBoxcatLocal", Settings::values.bcat_boxcat_local); 129 log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local);
129} 130}
130 131
131float Volume() { 132float Volume() {
@@ -184,4 +185,9 @@ void RestoreGlobalState() {
184 values.sound_index.SetGlobal(true); 185 values.sound_index.SetGlobal(true);
185} 186}
186 187
188void Sanitize() {
189 values.use_asynchronous_gpu_emulation.SetValue(
190 values.use_asynchronous_gpu_emulation.GetValue() || values.use_multi_core.GetValue());
191}
192
187} // namespace Settings 193} // namespace Settings
diff --git a/src/core/settings.h b/src/core/settings.h
index 850ca4072..a64debd25 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -346,31 +346,6 @@ struct TouchscreenInput {
346 u32 rotation_angle; 346 u32 rotation_angle;
347}; 347};
348 348
349enum class NANDTotalSize : u64 {
350 S29_1GB = 0x747C00000ULL,
351};
352
353enum class NANDUserSize : u64 {
354 S26GB = 0x680000000ULL,
355};
356
357enum class NANDSystemSize : u64 {
358 S2_5GB = 0xA0000000,
359};
360
361enum class SDMCSize : u64 {
362 S1GB = 0x40000000,
363 S2GB = 0x80000000,
364 S4GB = 0x100000000ULL,
365 S8GB = 0x200000000ULL,
366 S16GB = 0x400000000ULL,
367 S32GB = 0x800000000ULL,
368 S64GB = 0x1000000000ULL,
369 S128GB = 0x2000000000ULL,
370 S256GB = 0x4000000000ULL,
371 S1TB = 0x10000000000ULL,
372};
373
374enum class RendererBackend { 349enum class RendererBackend {
375 OpenGL = 0, 350 OpenGL = 0,
376 Vulkan = 1, 351 Vulkan = 1,
@@ -382,6 +357,11 @@ enum class GPUAccuracy : u32 {
382 Extreme = 2, 357 Extreme = 2,
383}; 358};
384 359
360enum class CPUAccuracy {
361 Accurate = 0,
362 DebugMode = 1,
363};
364
385extern bool configuring_global; 365extern bool configuring_global;
386 366
387template <typename Type> 367template <typename Type>
@@ -427,6 +407,18 @@ struct Values {
427 // Core 407 // Core
428 Setting<bool> use_multi_core; 408 Setting<bool> use_multi_core;
429 409
410 // Cpu
411 CPUAccuracy cpu_accuracy;
412
413 bool cpuopt_page_tables;
414 bool cpuopt_block_linking;
415 bool cpuopt_return_stack_buffer;
416 bool cpuopt_fast_dispatcher;
417 bool cpuopt_context_elimination;
418 bool cpuopt_const_prop;
419 bool cpuopt_misc_ir;
420 bool cpuopt_reduce_misalign_checks;
421
430 // Renderer 422 // Renderer
431 Setting<RendererBackend> renderer_backend; 423 Setting<RendererBackend> renderer_backend;
432 bool renderer_debug; 424 bool renderer_debug;
@@ -491,10 +483,6 @@ struct Values {
491 bool gamecard_inserted; 483 bool gamecard_inserted;
492 bool gamecard_current_game; 484 bool gamecard_current_game;
493 std::string gamecard_path; 485 std::string gamecard_path;
494 NANDTotalSize nand_total_size;
495 NANDSystemSize nand_system_size;
496 NANDUserSize nand_user_size;
497 SDMCSize sdmc_size;
498 486
499 // Debugging 487 // Debugging
500 bool record_frame_times; 488 bool record_frame_times;
@@ -505,7 +493,6 @@ struct Values {
505 bool dump_nso; 493 bool dump_nso;
506 bool reporting_services; 494 bool reporting_services;
507 bool quest_flag; 495 bool quest_flag;
508 bool disable_cpu_opt;
509 bool disable_macro_jit; 496 bool disable_macro_jit;
510 497
511 // Misceallaneous 498 // Misceallaneous
@@ -539,4 +526,7 @@ void LogSettings();
539// Restore the global state of all applicable settings in the Values struct 526// Restore the global state of all applicable settings in the Values struct
540void RestoreGlobalState(); 527void RestoreGlobalState();
541 528
529// Fixes settings that are known to cause issues with the emulator
530void Sanitize();
531
542} // namespace Settings 532} // namespace Settings
diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt
index 3bd76dd23..317c25bad 100644
--- a/src/input_common/CMakeLists.txt
+++ b/src/input_common/CMakeLists.txt
@@ -30,7 +30,8 @@ if(SDL2_FOUND)
30 target_compile_definitions(input_common PRIVATE HAVE_SDL2) 30 target_compile_definitions(input_common PRIVATE HAVE_SDL2)
31endif() 31endif()
32 32
33target_link_libraries(input_common PUBLIC ${LIBUSB_LIBRARIES}) 33target_include_directories(input_common SYSTEM PRIVATE ${LIBUSB_INCLUDE_DIR})
34target_link_libraries(input_common PRIVATE ${LIBUSB_LIBRARIES})
34 35
35create_target_directory_groups(input_common) 36create_target_directory_groups(input_common)
36target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost) 37target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost)
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp
index 6d9f4d9eb..898a278a9 100644
--- a/src/input_common/gcadapter/gc_adapter.cpp
+++ b/src/input_common/gcadapter/gc_adapter.cpp
@@ -4,6 +4,7 @@
4 4
5#include <chrono> 5#include <chrono>
6#include <thread> 6#include <thread>
7#include <libusb.h>
7#include "common/logging/log.h" 8#include "common/logging/log.h"
8#include "input_common/gcadapter/gc_adapter.h" 9#include "input_common/gcadapter/gc_adapter.h"
9 10
@@ -24,6 +25,7 @@ Adapter::Adapter() {
24 LOG_INFO(Input, "GC Adapter Initialization started"); 25 LOG_INFO(Input, "GC Adapter Initialization started");
25 26
26 current_status = NO_ADAPTER_DETECTED; 27 current_status = NO_ADAPTER_DETECTED;
28 get_origin.fill(true);
27 29
28 const int init_res = libusb_init(&libusb_ctx); 30 const int init_res = libusb_init(&libusb_ctx);
29 if (init_res == LIBUSB_SUCCESS) { 31 if (init_res == LIBUSB_SUCCESS) {
@@ -33,15 +35,10 @@ Adapter::Adapter() {
33 } 35 }
34} 36}
35 37
36GCPadStatus Adapter::GetPadStatus(int port, const std::array<u8, 37>& adapter_payload) { 38GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload) {
37 GCPadStatus pad = {}; 39 GCPadStatus pad = {};
38 bool get_origin = false;
39 40
40 ControllerTypes type = ControllerTypes(adapter_payload[1 + (9 * port)] >> 4); 41 ControllerTypes type = ControllerTypes(adapter_payload[1 + (9 * port)] >> 4);
41 if (type != ControllerTypes::None) {
42 get_origin = true;
43 }
44
45 adapter_controllers_status[port] = type; 42 adapter_controllers_status[port] = type;
46 43
47 static constexpr std::array<PadButton, 8> b1_buttons{ 44 static constexpr std::array<PadButton, 8> b1_buttons{
@@ -57,6 +54,11 @@ GCPadStatus Adapter::GetPadStatus(int port, const std::array<u8, 37>& adapter_pa
57 PadButton::PAD_TRIGGER_L, 54 PadButton::PAD_TRIGGER_L,
58 }; 55 };
59 56
57 if (adapter_controllers_status[port] == ControllerTypes::None && !get_origin[port]) {
58 // Controller may have been disconnected, recalibrate if reconnected.
59 get_origin[port] = true;
60 }
61
60 if (adapter_controllers_status[port] != ControllerTypes::None) { 62 if (adapter_controllers_status[port] != ControllerTypes::None) {
61 const u8 b1 = adapter_payload[1 + (9 * port) + 1]; 63 const u8 b1 = adapter_payload[1 + (9 * port) + 1];
62 const u8 b2 = adapter_payload[1 + (9 * port) + 2]; 64 const u8 b2 = adapter_payload[1 + (9 * port) + 2];
@@ -73,16 +75,22 @@ GCPadStatus Adapter::GetPadStatus(int port, const std::array<u8, 37>& adapter_pa
73 } 75 }
74 } 76 }
75 77
76 if (get_origin) {
77 pad.button |= PAD_GET_ORIGIN;
78 }
79
80 pad.stick_x = adapter_payload[1 + (9 * port) + 3]; 78 pad.stick_x = adapter_payload[1 + (9 * port) + 3];
81 pad.stick_y = adapter_payload[1 + (9 * port) + 4]; 79 pad.stick_y = adapter_payload[1 + (9 * port) + 4];
82 pad.substick_x = adapter_payload[1 + (9 * port) + 5]; 80 pad.substick_x = adapter_payload[1 + (9 * port) + 5];
83 pad.substick_y = adapter_payload[1 + (9 * port) + 6]; 81 pad.substick_y = adapter_payload[1 + (9 * port) + 6];
84 pad.trigger_left = adapter_payload[1 + (9 * port) + 7]; 82 pad.trigger_left = adapter_payload[1 + (9 * port) + 7];
85 pad.trigger_right = adapter_payload[1 + (9 * port) + 8]; 83 pad.trigger_right = adapter_payload[1 + (9 * port) + 8];
84
85 if (get_origin[port]) {
86 origin_status[port].stick_x = pad.stick_x;
87 origin_status[port].stick_y = pad.stick_y;
88 origin_status[port].substick_x = pad.substick_x;
89 origin_status[port].substick_y = pad.substick_y;
90 origin_status[port].trigger_left = pad.trigger_left;
91 origin_status[port].trigger_right = pad.trigger_right;
92 get_origin[port] = false;
93 }
86 } 94 }
87 return pad; 95 return pad;
88} 96}
@@ -131,31 +139,31 @@ void Adapter::Read() {
131 for (std::size_t port = 0; port < pads.size(); ++port) { 139 for (std::size_t port = 0; port < pads.size(); ++port) {
132 pads[port] = GetPadStatus(port, adapter_payload_copy); 140 pads[port] = GetPadStatus(port, adapter_payload_copy);
133 if (DeviceConnected(port) && configuring) { 141 if (DeviceConnected(port) && configuring) {
134 if (pads[port].button != PAD_GET_ORIGIN) { 142 if (pads[port].button != 0) {
135 pad_queue[port].Push(pads[port]); 143 pad_queue[port].Push(pads[port]);
136 } 144 }
137 145
138 // Accounting for a threshold here because of some controller variance 146 // Accounting for a threshold here because of some controller variance
139 if (pads[port].stick_x > pads[port].MAIN_STICK_CENTER_X + pads[port].THRESHOLD || 147 if (pads[port].stick_x > origin_status[port].stick_x + pads[port].THRESHOLD ||
140 pads[port].stick_x < pads[port].MAIN_STICK_CENTER_X - pads[port].THRESHOLD) { 148 pads[port].stick_x < origin_status[port].stick_x - pads[port].THRESHOLD) {
141 pads[port].axis = GCAdapter::PadAxes::StickX; 149 pads[port].axis = GCAdapter::PadAxes::StickX;
142 pads[port].axis_value = pads[port].stick_x; 150 pads[port].axis_value = pads[port].stick_x;
143 pad_queue[port].Push(pads[port]); 151 pad_queue[port].Push(pads[port]);
144 } 152 }
145 if (pads[port].stick_y > pads[port].MAIN_STICK_CENTER_Y + pads[port].THRESHOLD || 153 if (pads[port].stick_y > origin_status[port].stick_y + pads[port].THRESHOLD ||
146 pads[port].stick_y < pads[port].MAIN_STICK_CENTER_Y - pads[port].THRESHOLD) { 154 pads[port].stick_y < origin_status[port].stick_y - pads[port].THRESHOLD) {
147 pads[port].axis = GCAdapter::PadAxes::StickY; 155 pads[port].axis = GCAdapter::PadAxes::StickY;
148 pads[port].axis_value = pads[port].stick_y; 156 pads[port].axis_value = pads[port].stick_y;
149 pad_queue[port].Push(pads[port]); 157 pad_queue[port].Push(pads[port]);
150 } 158 }
151 if (pads[port].substick_x > pads[port].C_STICK_CENTER_X + pads[port].THRESHOLD || 159 if (pads[port].substick_x > origin_status[port].substick_x + pads[port].THRESHOLD ||
152 pads[port].substick_x < pads[port].C_STICK_CENTER_X - pads[port].THRESHOLD) { 160 pads[port].substick_x < origin_status[port].substick_x - pads[port].THRESHOLD) {
153 pads[port].axis = GCAdapter::PadAxes::SubstickX; 161 pads[port].axis = GCAdapter::PadAxes::SubstickX;
154 pads[port].axis_value = pads[port].substick_x; 162 pads[port].axis_value = pads[port].substick_x;
155 pad_queue[port].Push(pads[port]); 163 pad_queue[port].Push(pads[port]);
156 } 164 }
157 if (pads[port].substick_y > pads[port].C_STICK_CENTER_Y + pads[port].THRESHOLD || 165 if (pads[port].substick_y > origin_status[port].substick_y + pads[port].THRESHOLD ||
158 pads[port].substick_y < pads[port].C_STICK_CENTER_Y - pads[port].THRESHOLD) { 166 pads[port].substick_y < origin_status[port].substick_y - pads[port].THRESHOLD) {
159 pads[port].axis = GCAdapter::PadAxes::SubstickY; 167 pads[port].axis = GCAdapter::PadAxes::SubstickY;
160 pads[port].axis_value = pads[port].substick_y; 168 pads[port].axis_value = pads[port].substick_y;
161 pad_queue[port].Push(pads[port]); 169 pad_queue[port].Push(pads[port]);
@@ -198,7 +206,7 @@ void Adapter::StartScanThread() {
198 } 206 }
199 207
200 detect_thread_running = true; 208 detect_thread_running = true;
201 detect_thread = std::thread([=] { ScanThreadFunc(); }); 209 detect_thread = std::thread(&Adapter::ScanThreadFunc, this);
202} 210}
203 211
204void Adapter::StopScanThread() { 212void Adapter::StopScanThread() {
@@ -227,7 +235,7 @@ void Adapter::Setup() {
227 } 235 }
228 236
229 if (devices != nullptr) { 237 if (devices != nullptr) {
230 for (std::size_t index = 0; index < device_count; ++index) { 238 for (std::size_t index = 0; index < static_cast<std::size_t>(device_count); ++index) {
231 if (CheckDeviceAccess(devices[index])) { 239 if (CheckDeviceAccess(devices[index])) {
232 // GC Adapter found and accessible, registering it 240 // GC Adapter found and accessible, registering it
233 GetGCEndpoint(devices[index]); 241 GetGCEndpoint(devices[index]);
@@ -236,6 +244,9 @@ void Adapter::Setup() {
236 } 244 }
237 libusb_free_device_list(devices, 1); 245 libusb_free_device_list(devices, 1);
238 } 246 }
247 // Break out of the ScanThreadFunc() loop that is constantly looking for the device
248 // Assumes user has GC adapter plugged in before launch to use the adapter
249 detect_thread_running = false;
239} 250}
240 251
241bool Adapter::CheckDeviceAccess(libusb_device* device) { 252bool Adapter::CheckDeviceAccess(libusb_device* device) {
@@ -344,6 +355,7 @@ void Adapter::Reset() {
344 adapter_input_thread.join(); 355 adapter_input_thread.join();
345 356
346 adapter_controllers_status.fill(ControllerTypes::None); 357 adapter_controllers_status.fill(ControllerTypes::None);
358 get_origin.fill(true);
347 current_status = NO_ADAPTER_DETECTED; 359 current_status = NO_ADAPTER_DETECTED;
348 360
349 if (usb_adapter_handle) { 361 if (usb_adapter_handle) {
@@ -357,15 +369,16 @@ void Adapter::Reset() {
357 } 369 }
358} 370}
359 371
360bool Adapter::DeviceConnected(int port) { 372bool Adapter::DeviceConnected(std::size_t port) {
361 return adapter_controllers_status[port] != ControllerTypes::None; 373 return adapter_controllers_status[port] != ControllerTypes::None;
362} 374}
363 375
364void Adapter::ResetDeviceType(int port) { 376void Adapter::ResetDeviceType(std::size_t port) {
365 adapter_controllers_status[port] = ControllerTypes::None; 377 adapter_controllers_status[port] = ControllerTypes::None;
366} 378}
367 379
368void Adapter::BeginConfiguration() { 380void Adapter::BeginConfiguration() {
381 get_origin.fill(true);
369 for (auto& pq : pad_queue) { 382 for (auto& pq : pad_queue) {
370 pq.Clear(); 383 pq.Clear();
371 } 384 }
@@ -395,4 +408,25 @@ const std::array<GCState, 4>& Adapter::GetPadState() const {
395 return state; 408 return state;
396} 409}
397 410
411int Adapter::GetOriginValue(int port, int axis) const {
412 const auto& status = origin_status[port];
413
414 switch (static_cast<PadAxes>(axis)) {
415 case PadAxes::StickX:
416 return status.stick_x;
417 case PadAxes::StickY:
418 return status.stick_y;
419 case PadAxes::SubstickX:
420 return status.substick_x;
421 case PadAxes::SubstickY:
422 return status.substick_y;
423 case PadAxes::TriggerLeft:
424 return status.trigger_left;
425 case PadAxes::TriggerRight:
426 return status.trigger_right;
427 default:
428 return 0;
429 }
430}
431
398} // namespace GCAdapter 432} // namespace GCAdapter
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h
index b1c2a1958..3586c8bda 100644
--- a/src/input_common/gcadapter/gc_adapter.h
+++ b/src/input_common/gcadapter/gc_adapter.h
@@ -8,17 +8,14 @@
8#include <mutex> 8#include <mutex>
9#include <thread> 9#include <thread>
10#include <unordered_map> 10#include <unordered_map>
11#include <libusb.h>
12#include "common/common_types.h" 11#include "common/common_types.h"
13#include "common/threadsafe_queue.h" 12#include "common/threadsafe_queue.h"
14 13
15namespace GCAdapter { 14struct libusb_context;
15struct libusb_device;
16struct libusb_device_handle;
16 17
17enum { 18namespace GCAdapter {
18 PAD_USE_ORIGIN = 0x0080,
19 PAD_GET_ORIGIN = 0x2000,
20 PAD_ERR_STATUS = 0x8000,
21};
22 19
23enum class PadButton { 20enum class PadButton {
24 PAD_BUTTON_LEFT = 0x0001, 21 PAD_BUTTON_LEFT = 0x0001,
@@ -97,14 +94,19 @@ public:
97 void BeginConfiguration(); 94 void BeginConfiguration();
98 void EndConfiguration(); 95 void EndConfiguration();
99 96
97 /// Returns true if there is a device connected to port
98 bool DeviceConnected(std::size_t port);
99
100 std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue(); 100 std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue();
101 const std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue() const; 101 const std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue() const;
102 102
103 std::array<GCState, 4>& GetPadState(); 103 std::array<GCState, 4>& GetPadState();
104 const std::array<GCState, 4>& GetPadState() const; 104 const std::array<GCState, 4>& GetPadState() const;
105 105
106 int GetOriginValue(int port, int axis) const;
107
106private: 108private:
107 GCPadStatus GetPadStatus(int port, const std::array<u8, 37>& adapter_payload); 109 GCPadStatus GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload);
108 110
109 void PadToState(const GCPadStatus& pad, GCState& state); 111 void PadToState(const GCPadStatus& pad, GCState& state);
110 112
@@ -116,11 +118,8 @@ private:
116 /// Stop scanning for the adapter 118 /// Stop scanning for the adapter
117 void StopScanThread(); 119 void StopScanThread();
118 120
119 /// Returns true if there is a device connected to port
120 bool DeviceConnected(int port);
121
122 /// Resets status of device connected to port 121 /// Resets status of device connected to port
123 void ResetDeviceType(int port); 122 void ResetDeviceType(std::size_t port);
124 123
125 /// Returns true if we successfully gain access to GC Adapter 124 /// Returns true if we successfully gain access to GC Adapter
126 bool CheckDeviceAccess(libusb_device* device); 125 bool CheckDeviceAccess(libusb_device* device);
@@ -156,6 +155,8 @@ private:
156 155
157 std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue; 156 std::array<Common::SPSCQueue<GCPadStatus>, 4> pad_queue;
158 std::array<GCState, 4> state; 157 std::array<GCState, 4> state;
158 std::array<bool, 4> get_origin;
159 std::array<GCPadStatus, 4> origin_status;
159}; 160};
160 161
161} // namespace GCAdapter 162} // namespace GCAdapter
diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp
index 385ce8430..96e22d3ad 100644
--- a/src/input_common/gcadapter/gc_poller.cpp
+++ b/src/input_common/gcadapter/gc_poller.cpp
@@ -6,6 +6,7 @@
6#include <list> 6#include <list>
7#include <mutex> 7#include <mutex>
8#include <utility> 8#include <utility>
9#include "common/assert.h"
9#include "common/threadsafe_queue.h" 10#include "common/threadsafe_queue.h"
10#include "input_common/gcadapter/gc_adapter.h" 11#include "input_common/gcadapter/gc_adapter.h"
11#include "input_common/gcadapter/gc_poller.h" 12#include "input_common/gcadapter/gc_poller.h"
@@ -20,7 +21,10 @@ public:
20 ~GCButton() override; 21 ~GCButton() override;
21 22
22 bool GetStatus() const override { 23 bool GetStatus() const override {
23 return gcadapter->GetPadState()[port].buttons.at(button); 24 if (gcadapter->DeviceConnected(port)) {
25 return gcadapter->GetPadState()[port].buttons.at(button);
26 }
27 return false;
24 } 28 }
25 29
26private: 30private:
@@ -34,22 +38,20 @@ public:
34 explicit GCAxisButton(int port_, int axis_, float threshold_, bool trigger_if_greater_, 38 explicit GCAxisButton(int port_, int axis_, float threshold_, bool trigger_if_greater_,
35 GCAdapter::Adapter* adapter) 39 GCAdapter::Adapter* adapter)
36 : port(port_), axis(axis_), threshold(threshold_), trigger_if_greater(trigger_if_greater_), 40 : port(port_), axis(axis_), threshold(threshold_), trigger_if_greater(trigger_if_greater_),
37 gcadapter(adapter) { 41 gcadapter(adapter), origin_value(adapter->GetOriginValue(port_, axis_)) {}
38 // L/R triggers range is only in positive direction beginning near 0
39 // 0.0 threshold equates to near half trigger press, but threshold accounts for variability.
40 if (axis > 3) {
41 threshold *= -0.5;
42 }
43 }
44 42
45 bool GetStatus() const override { 43 bool GetStatus() const override {
46 const float axis_value = (gcadapter->GetPadState()[port].axes.at(axis) - 128.0f) / 128.0f; 44 if (gcadapter->DeviceConnected(port)) {
47 if (trigger_if_greater) { 45 const float current_axis_value = gcadapter->GetPadState()[port].axes.at(axis);
48 // TODO: Might be worthwile to set a slider for the trigger threshold. It is currently 46 const float axis_value = (current_axis_value - origin_value) / 128.0f;
49 // always set to 0.5 in configure_input_player.cpp ZL/ZR HandleClick 47 if (trigger_if_greater) {
50 return axis_value > threshold; 48 // TODO: Might be worthwile to set a slider for the trigger threshold. It is
49 // currently always set to 0.5 in configure_input_player.cpp ZL/ZR HandleClick
50 return axis_value > threshold;
51 }
52 return axis_value < -threshold;
51 } 53 }
52 return axis_value < -threshold; 54 return false;
53 } 55 }
54 56
55private: 57private:
@@ -58,6 +60,7 @@ private:
58 float threshold; 60 float threshold;
59 bool trigger_if_greater; 61 bool trigger_if_greater;
60 GCAdapter::Adapter* gcadapter; 62 GCAdapter::Adapter* gcadapter;
63 const float origin_value;
61}; 64};
62 65
63GCButtonFactory::GCButtonFactory(std::shared_ptr<GCAdapter::Adapter> adapter_) 66GCButtonFactory::GCButtonFactory(std::shared_ptr<GCAdapter::Adapter> adapter_)
@@ -94,9 +97,12 @@ std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::Param
94 return std::make_unique<GCAxisButton>(port, axis, threshold, trigger_if_greater, 97 return std::make_unique<GCAxisButton>(port, axis, threshold, trigger_if_greater,
95 adapter.get()); 98 adapter.get());
96 } 99 }
100
101 UNREACHABLE();
102 return nullptr;
97} 103}
98 104
99Common::ParamPackage GCButtonFactory::GetNextInput() { 105Common::ParamPackage GCButtonFactory::GetNextInput() const {
100 Common::ParamPackage params; 106 Common::ParamPackage params;
101 GCAdapter::GCPadStatus pad; 107 GCAdapter::GCPadStatus pad;
102 auto& queue = adapter->GetPadQueue(); 108 auto& queue = adapter->GetPadQueue();
@@ -144,14 +150,20 @@ void GCButtonFactory::EndConfiguration() {
144class GCAnalog final : public Input::AnalogDevice { 150class GCAnalog final : public Input::AnalogDevice {
145public: 151public:
146 GCAnalog(int port_, int axis_x_, int axis_y_, float deadzone_, GCAdapter::Adapter* adapter) 152 GCAnalog(int port_, int axis_x_, int axis_y_, float deadzone_, GCAdapter::Adapter* adapter)
147 : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter) {} 153 : port(port_), axis_x(axis_x_), axis_y(axis_y_), deadzone(deadzone_), gcadapter(adapter),
154 origin_value_x(adapter->GetOriginValue(port_, axis_x_)),
155 origin_value_y(adapter->GetOriginValue(port_, axis_y_)) {}
148 156
149 float GetAxis(int axis) const { 157 float GetAxis(int axis) const {
150 std::lock_guard lock{mutex}; 158 if (gcadapter->DeviceConnected(port)) {
151 // division is not by a perfect 128 to account for some variance in center location 159 std::lock_guard lock{mutex};
152 // e.g. my device idled at 131 in X, 120 in Y, and full range of motion was in range 160 const auto origin_value = axis % 2 == 0 ? origin_value_x : origin_value_y;
153 // [20-230] 161 // division is not by a perfect 128 to account for some variance in center location
154 return (gcadapter->GetPadState()[port].axes.at(axis) - 128.0f) / 95.0f; 162 // e.g. my device idled at 131 in X, 120 in Y, and full range of motion was in range
163 // [20-230]
164 return (gcadapter->GetPadState()[port].axes.at(axis) - origin_value) / 95.0f;
165 }
166 return 0.0f;
155 } 167 }
156 168
157 std::pair<float, float> GetAnalog(int axis_x, int axis_y) const { 169 std::pair<float, float> GetAnalog(int axis_x, int axis_y) const {
@@ -201,8 +213,10 @@ private:
201 const int axis_x; 213 const int axis_x;
202 const int axis_y; 214 const int axis_y;
203 const float deadzone; 215 const float deadzone;
204 mutable std::mutex mutex;
205 GCAdapter::Adapter* gcadapter; 216 GCAdapter::Adapter* gcadapter;
217 const float origin_value_x;
218 const float origin_value_y;
219 mutable std::mutex mutex;
206}; 220};
207 221
208/// An analog device factory that creates analog devices from GC Adapter 222/// An analog device factory that creates analog devices from GC Adapter
@@ -249,7 +263,7 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() {
249 const u8 axis = static_cast<u8>(pad.axis); 263 const u8 axis = static_cast<u8>(pad.axis);
250 if (analog_x_axis == -1) { 264 if (analog_x_axis == -1) {
251 analog_x_axis = axis; 265 analog_x_axis = axis;
252 controller_number = port; 266 controller_number = static_cast<int>(port);
253 } else if (analog_y_axis == -1 && analog_x_axis != axis && controller_number == port) { 267 } else if (analog_y_axis == -1 && analog_x_axis != axis && controller_number == port) {
254 analog_y_axis = axis; 268 analog_y_axis = axis;
255 } 269 }
diff --git a/src/input_common/gcadapter/gc_poller.h b/src/input_common/gcadapter/gc_poller.h
index e96af7d51..0527f328f 100644
--- a/src/input_common/gcadapter/gc_poller.h
+++ b/src/input_common/gcadapter/gc_poller.h
@@ -25,7 +25,7 @@ public:
25 */ 25 */
26 std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override; 26 std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override;
27 27
28 Common::ParamPackage GetNextInput(); 28 Common::ParamPackage GetNextInput() const;
29 29
30 /// For device input configuration/polling 30 /// For device input configuration/polling
31 void BeginConfiguration(); 31 void BeginConfiguration();
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index fd0af1019..b9d5d0ec3 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -4,7 +4,6 @@
4 4
5#include <memory> 5#include <memory>
6#include <thread> 6#include <thread>
7#include <libusb.h>
8#include "common/param_package.h" 7#include "common/param_package.h"
9#include "input_common/analog_from_button.h" 8#include "input_common/analog_from_button.h"
10#include "input_common/gcadapter/gc_adapter.h" 9#include "input_common/gcadapter/gc_adapter.h"
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index da5227058..e63c73c4f 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -234,7 +234,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
234 std::function<void(Status)> status_callback, 234 std::function<void(Status)> status_callback,
235 std::function<void(u16, u16, u16, u16)> data_callback) { 235 std::function<void(u16, u16, u16, u16)> data_callback) {
236 236
237 std::thread([=] { 237 std::thread([=, this] {
238 constexpr u16 CALIBRATION_THRESHOLD = 100; 238 constexpr u16 CALIBRATION_THRESHOLD = 100;
239 239
240 u16 min_x{UINT16_MAX}; 240 u16 min_x{UINT16_MAX};
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index 01d7df405..a2d3d7823 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -14,50 +14,45 @@
14 14
15namespace Tegra::Engines { 15namespace Tegra::Engines {
16 16
17using namespace Texture;
18
17MaxwellDMA::MaxwellDMA(Core::System& system, MemoryManager& memory_manager) 19MaxwellDMA::MaxwellDMA(Core::System& system, MemoryManager& memory_manager)
18 : system{system}, memory_manager{memory_manager} {} 20 : system{system}, memory_manager{memory_manager} {}
19 21
20void MaxwellDMA::CallMethod(u32 method, u32 method_argument, bool is_last_call) { 22void MaxwellDMA::CallMethod(u32 method, u32 method_argument, bool is_last_call) {
21 ASSERT_MSG(method < Regs::NUM_REGS, 23 ASSERT_MSG(method < NUM_REGS, "Invalid MaxwellDMA register");
22 "Invalid MaxwellDMA register, increase the size of the Regs structure");
23 24
24 regs.reg_array[method] = method_argument; 25 regs.reg_array[method] = method_argument;
25 26
26#define MAXWELLDMA_REG_INDEX(field_name) \ 27 if (method == offsetof(Regs, launch_dma) / sizeof(u32)) {
27 (offsetof(Tegra::Engines::MaxwellDMA::Regs, field_name) / sizeof(u32)) 28 Launch();
28
29 switch (method) {
30 case MAXWELLDMA_REG_INDEX(exec): {
31 HandleCopy();
32 break;
33 }
34 } 29 }
35
36#undef MAXWELLDMA_REG_INDEX
37} 30}
38 31
39void MaxwellDMA::CallMultiMethod(u32 method, const u32* base_start, u32 amount, 32void MaxwellDMA::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
40 u32 methods_pending) { 33 u32 methods_pending) {
41 for (std::size_t i = 0; i < amount; i++) { 34 for (size_t i = 0; i < amount; ++i) {
42 CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1); 35 CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1);
43 } 36 }
44} 37}
45 38
46void MaxwellDMA::HandleCopy() { 39void MaxwellDMA::Launch() {
47 LOG_TRACE(HW_GPU, "Requested a DMA copy"); 40 LOG_TRACE(Render_OpenGL, "DMA copy 0x{:x} -> 0x{:x}", static_cast<GPUVAddr>(regs.offset_in),
48 41 static_cast<GPUVAddr>(regs.offset_out));
49 const GPUVAddr source = regs.src_address.Address();
50 const GPUVAddr dest = regs.dst_address.Address();
51 42
52 // TODO(Subv): Perform more research and implement all features of this engine. 43 // TODO(Subv): Perform more research and implement all features of this engine.
53 ASSERT(regs.exec.enable_swizzle == 0); 44 const LaunchDMA& launch = regs.launch_dma;
54 ASSERT(regs.exec.query_mode == Regs::QueryMode::None); 45 ASSERT(launch.remap_enable == 0);
55 ASSERT(regs.exec.query_intr == Regs::QueryIntr::None); 46 ASSERT(launch.semaphore_type == LaunchDMA::SemaphoreType::NONE);
56 ASSERT(regs.exec.copy_mode == Regs::CopyMode::Unk2); 47 ASSERT(launch.interrupt_type == LaunchDMA::InterruptType::NONE);
57 ASSERT(regs.dst_params.pos_x == 0); 48 ASSERT(launch.data_transfer_type == LaunchDMA::DataTransferType::NON_PIPELINED);
58 ASSERT(regs.dst_params.pos_y == 0); 49 ASSERT(regs.dst_params.origin.x == 0);
59 50 ASSERT(regs.dst_params.origin.y == 0);
60 if (!regs.exec.is_dst_linear && !regs.exec.is_src_linear) { 51
52 const bool is_src_pitch = launch.src_memory_layout == LaunchDMA::MemoryLayout::PITCH;
53 const bool is_dst_pitch = launch.dst_memory_layout == LaunchDMA::MemoryLayout::PITCH;
54
55 if (!is_src_pitch && !is_dst_pitch) {
61 // If both the source and the destination are in block layout, assert. 56 // If both the source and the destination are in block layout, assert.
62 UNREACHABLE_MSG("Tiled->Tiled DMA transfers are not yet implemented"); 57 UNREACHABLE_MSG("Tiled->Tiled DMA transfers are not yet implemented");
63 return; 58 return;
@@ -66,144 +61,161 @@ void MaxwellDMA::HandleCopy() {
66 // All copies here update the main memory, so mark all rasterizer states as invalid. 61 // All copies here update the main memory, so mark all rasterizer states as invalid.
67 system.GPU().Maxwell3D().OnMemoryWrite(); 62 system.GPU().Maxwell3D().OnMemoryWrite();
68 63
69 if (regs.exec.is_dst_linear && regs.exec.is_src_linear) { 64 if (is_src_pitch && is_dst_pitch) {
70 // When the enable_2d bit is disabled, the copy is performed as if we were copying a 1D 65 CopyPitchToPitch();
71 // buffer of length `x_count`, otherwise we copy a 2D image of dimensions (x_count, 66 } else {
72 // y_count). 67 ASSERT(launch.multi_line_enable == 1);
73 if (!regs.exec.enable_2d) {
74 memory_manager.CopyBlock(dest, source, regs.x_count);
75 return;
76 }
77 68
78 // If both the source and the destination are in linear layout, perform a line-by-line 69 if (!is_src_pitch && is_dst_pitch) {
79 // copy. We're going to take a subrect of size (x_count, y_count) from the source 70 CopyBlockLinearToPitch();
80 // rectangle. There is no need to manually flush/invalidate the regions because 71 } else {
81 // CopyBlock does that for us. 72 CopyPitchToBlockLinear();
82 for (u32 line = 0; line < regs.y_count; ++line) {
83 const GPUVAddr source_line = source + line * regs.src_pitch;
84 const GPUVAddr dest_line = dest + line * regs.dst_pitch;
85 memory_manager.CopyBlock(dest_line, source_line, regs.x_count);
86 } 73 }
87 return;
88 } 74 }
75}
89 76
90 ASSERT(regs.exec.enable_2d == 1); 77void MaxwellDMA::CopyPitchToPitch() {
91 78 // When `multi_line_enable` bit is disabled the copy is performed as if we were copying a 1D
92 if (regs.exec.is_dst_linear && !regs.exec.is_src_linear) { 79 // buffer of length `line_length_in`.
93 80 // Otherwise we copy a 2D image of dimensions (line_length_in, line_count).
94 ASSERT(regs.src_params.BlockDepth() == 0); 81 if (!regs.launch_dma.multi_line_enable) {
95 // Optimized path for micro copies. 82 memory_manager.CopyBlock(regs.offset_out, regs.offset_in, regs.line_length_in);
96 if (regs.dst_pitch * regs.y_count < Texture::GetGOBSize() && regs.dst_pitch <= 64) { 83 return;
97 const u32 bytes_per_pixel = regs.dst_pitch / regs.x_count; 84 }
98 const std::size_t src_size = Texture::GetGOBSize();
99 const std::size_t dst_size = regs.dst_pitch * regs.y_count;
100 u32 pos_x = regs.src_params.pos_x;
101 u32 pos_y = regs.src_params.pos_y;
102 const u64 offset =
103 Texture::GetGOBOffset(regs.src_params.size_x, regs.src_params.size_y, pos_x, pos_y,
104 regs.src_params.BlockDepth(), bytes_per_pixel);
105 const u32 x_in_gob = 64 / bytes_per_pixel;
106 pos_x = pos_x % x_in_gob;
107 pos_y = pos_y % 8;
108
109 if (read_buffer.size() < src_size) {
110 read_buffer.resize(src_size);
111 }
112
113 if (write_buffer.size() < dst_size) {
114 write_buffer.resize(dst_size);
115 }
116
117 if (Settings::IsGPULevelExtreme()) {
118 memory_manager.ReadBlock(source + offset, read_buffer.data(), src_size);
119 memory_manager.ReadBlock(dest, write_buffer.data(), dst_size);
120 } else {
121 memory_manager.ReadBlockUnsafe(source + offset, read_buffer.data(), src_size);
122 memory_manager.ReadBlockUnsafe(dest, write_buffer.data(), dst_size);
123 }
124
125 Texture::UnswizzleSubrect(regs.x_count, regs.y_count, regs.dst_pitch,
126 regs.src_params.size_x, bytes_per_pixel, read_buffer.data(),
127 write_buffer.data(), regs.src_params.BlockHeight(), pos_x,
128 pos_y);
129
130 memory_manager.WriteBlock(dest, write_buffer.data(), dst_size);
131
132 return;
133 }
134 // If the input is tiled and the output is linear, deswizzle the input and copy it over.
135 const u32 bytes_per_pixel = regs.dst_pitch / regs.x_count;
136 const std::size_t src_size = Texture::CalculateSize(
137 true, bytes_per_pixel, regs.src_params.size_x, regs.src_params.size_y,
138 regs.src_params.size_z, regs.src_params.BlockHeight(), regs.src_params.BlockDepth());
139
140 const std::size_t src_layer_size = Texture::CalculateSize(
141 true, bytes_per_pixel, regs.src_params.size_x, regs.src_params.size_y, 1,
142 regs.src_params.BlockHeight(), regs.src_params.BlockDepth());
143
144 const std::size_t dst_size = regs.dst_pitch * regs.y_count;
145 85
146 if (read_buffer.size() < src_size) { 86 // Perform a line-by-line copy.
147 read_buffer.resize(src_size); 87 // We're going to take a subrect of size (line_length_in, line_count) from the source rectangle.
148 } 88 // There is no need to manually flush/invalidate the regions because CopyBlock does that for us.
89 for (u32 line = 0; line < regs.line_count; ++line) {
90 const GPUVAddr source_line = regs.offset_in + static_cast<size_t>(line) * regs.pitch_in;
91 const GPUVAddr dest_line = regs.offset_out + static_cast<size_t>(line) * regs.pitch_out;
92 memory_manager.CopyBlock(dest_line, source_line, regs.line_length_in);
93 }
94}
149 95
150 if (write_buffer.size() < dst_size) { 96void MaxwellDMA::CopyBlockLinearToPitch() {
151 write_buffer.resize(dst_size); 97 ASSERT(regs.src_params.block_size.depth == 0);
152 }
153 98
154 if (Settings::IsGPULevelExtreme()) { 99 // Optimized path for micro copies.
155 memory_manager.ReadBlock(source, read_buffer.data(), src_size); 100 const size_t dst_size = static_cast<size_t>(regs.pitch_out) * regs.line_count;
156 memory_manager.ReadBlock(dest, write_buffer.data(), dst_size); 101 if (dst_size < GOB_SIZE && regs.pitch_out <= GOB_SIZE_X) {
157 } else { 102 FastCopyBlockLinearToPitch();
158 memory_manager.ReadBlockUnsafe(source, read_buffer.data(), src_size); 103 return;
159 memory_manager.ReadBlockUnsafe(dest, write_buffer.data(), dst_size); 104 }
160 }
161 105
162 Texture::UnswizzleSubrect( 106 // Deswizzle the input and copy it over.
163 regs.x_count, regs.y_count, regs.dst_pitch, regs.src_params.size_x, bytes_per_pixel, 107 const u32 bytes_per_pixel = regs.pitch_out / regs.line_length_in;
164 read_buffer.data() + src_layer_size * regs.src_params.pos_z, write_buffer.data(), 108 const Parameters& src_params = regs.src_params;
165 regs.src_params.BlockHeight(), regs.src_params.pos_x, regs.src_params.pos_y); 109 const u32 width = src_params.width;
110 const u32 height = src_params.height;
111 const u32 depth = src_params.depth;
112 const u32 block_height = src_params.block_size.height;
113 const u32 block_depth = src_params.block_size.depth;
114 const size_t src_size =
115 CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth);
116 const size_t src_layer_size =
117 CalculateSize(true, bytes_per_pixel, width, height, 1, block_height, block_depth);
118
119 if (read_buffer.size() < src_size) {
120 read_buffer.resize(src_size);
121 }
122 if (write_buffer.size() < dst_size) {
123 write_buffer.resize(dst_size);
124 }
166 125
167 memory_manager.WriteBlock(dest, write_buffer.data(), dst_size); 126 if (Settings::IsGPULevelExtreme()) {
127 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size);
128 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
168 } else { 129 } else {
169 ASSERT(regs.dst_params.BlockDepth() == 0); 130 memory_manager.ReadBlockUnsafe(regs.offset_in, read_buffer.data(), src_size);
131 memory_manager.ReadBlockUnsafe(regs.offset_out, write_buffer.data(), dst_size);
132 }
170 133
171 const u32 bytes_per_pixel = regs.src_pitch / regs.x_count; 134 UnswizzleSubrect(regs.line_length_in, regs.line_count, regs.pitch_out, width, bytes_per_pixel,
135 read_buffer.data() + src_layer_size * src_params.layer, write_buffer.data(),
136 block_height, src_params.origin.x, src_params.origin.y);
172 137
173 const std::size_t dst_size = Texture::CalculateSize( 138 memory_manager.WriteBlock(regs.offset_out, write_buffer.data(), dst_size);
174 true, bytes_per_pixel, regs.dst_params.size_x, regs.dst_params.size_y, 139}
175 regs.dst_params.size_z, regs.dst_params.BlockHeight(), regs.dst_params.BlockDepth());
176 140
177 const std::size_t dst_layer_size = Texture::CalculateSize( 141void MaxwellDMA::CopyPitchToBlockLinear() {
178 true, bytes_per_pixel, regs.dst_params.size_x, regs.dst_params.size_y, 1, 142 const auto& dst_params = regs.dst_params;
179 regs.dst_params.BlockHeight(), regs.dst_params.BlockDepth()); 143 const u32 bytes_per_pixel = regs.pitch_in / regs.line_length_in;
144 const u32 width = dst_params.width;
145 const u32 height = dst_params.height;
146 const u32 depth = dst_params.depth;
147 const u32 block_height = dst_params.block_size.height;
148 const u32 block_depth = dst_params.block_size.depth;
149 const size_t dst_size =
150 CalculateSize(true, bytes_per_pixel, width, height, depth, block_height, block_depth);
151 const size_t dst_layer_size =
152 CalculateSize(true, bytes_per_pixel, width, height, 1, block_height, block_depth);
153
154 const size_t src_size = static_cast<size_t>(regs.pitch_in) * regs.line_count;
155
156 if (read_buffer.size() < src_size) {
157 read_buffer.resize(src_size);
158 }
159 if (write_buffer.size() < dst_size) {
160 write_buffer.resize(dst_size);
161 }
180 162
181 const std::size_t src_size = regs.src_pitch * regs.y_count; 163 if (Settings::IsGPULevelExtreme()) {
164 memory_manager.ReadBlock(regs.offset_in, read_buffer.data(), src_size);
165 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
166 } else {
167 memory_manager.ReadBlockUnsafe(regs.offset_in, read_buffer.data(), src_size);
168 memory_manager.ReadBlockUnsafe(regs.offset_out, write_buffer.data(), dst_size);
169 }
182 170
183 if (read_buffer.size() < src_size) { 171 // If the input is linear and the output is tiled, swizzle the input and copy it over.
184 read_buffer.resize(src_size); 172 if (regs.dst_params.block_size.depth > 0) {
185 } 173 ASSERT(dst_params.layer == 0);
174 SwizzleSliceToVoxel(regs.line_length_in, regs.line_count, regs.pitch_in, width, height,
175 bytes_per_pixel, block_height, block_depth, dst_params.origin.x,
176 dst_params.origin.y, write_buffer.data(), read_buffer.data());
177 } else {
178 SwizzleSubrect(regs.line_length_in, regs.line_count, regs.pitch_in, width, bytes_per_pixel,
179 write_buffer.data() + dst_layer_size * dst_params.layer, read_buffer.data(),
180 block_height, dst_params.origin.x, dst_params.origin.y);
181 }
186 182
187 if (write_buffer.size() < dst_size) { 183 memory_manager.WriteBlock(regs.offset_out, write_buffer.data(), dst_size);
188 write_buffer.resize(dst_size); 184}
189 }
190 185
191 if (Settings::IsGPULevelExtreme()) { 186void MaxwellDMA::FastCopyBlockLinearToPitch() {
192 memory_manager.ReadBlock(source, read_buffer.data(), src_size); 187 const u32 bytes_per_pixel = regs.pitch_out / regs.line_length_in;
193 memory_manager.ReadBlock(dest, write_buffer.data(), dst_size); 188 const size_t src_size = GOB_SIZE;
194 } else { 189 const size_t dst_size = static_cast<size_t>(regs.pitch_out) * regs.line_count;
195 memory_manager.ReadBlockUnsafe(source, read_buffer.data(), src_size); 190 u32 pos_x = regs.src_params.origin.x;
196 memory_manager.ReadBlockUnsafe(dest, write_buffer.data(), dst_size); 191 u32 pos_y = regs.src_params.origin.y;
197 } 192 const u64 offset = GetGOBOffset(regs.src_params.width, regs.src_params.height, pos_x, pos_y,
193 regs.src_params.block_size.height, bytes_per_pixel);
194 const u32 x_in_gob = 64 / bytes_per_pixel;
195 pos_x = pos_x % x_in_gob;
196 pos_y = pos_y % 8;
197
198 if (read_buffer.size() < src_size) {
199 read_buffer.resize(src_size);
200 }
198 201
199 // If the input is linear and the output is tiled, swizzle the input and copy it over. 202 if (write_buffer.size() < dst_size) {
200 Texture::SwizzleSubrect( 203 write_buffer.resize(dst_size);
201 regs.x_count, regs.y_count, regs.src_pitch, regs.dst_params.size_x, bytes_per_pixel, 204 }
202 write_buffer.data() + dst_layer_size * regs.dst_params.pos_z, read_buffer.data(),
203 regs.dst_params.BlockHeight(), regs.dst_params.pos_x, regs.dst_params.pos_y);
204 205
205 memory_manager.WriteBlock(dest, write_buffer.data(), dst_size); 206 if (Settings::IsGPULevelExtreme()) {
207 memory_manager.ReadBlock(regs.offset_in + offset, read_buffer.data(), src_size);
208 memory_manager.ReadBlock(regs.offset_out, write_buffer.data(), dst_size);
209 } else {
210 memory_manager.ReadBlockUnsafe(regs.offset_in + offset, read_buffer.data(), src_size);
211 memory_manager.ReadBlockUnsafe(regs.offset_out, write_buffer.data(), dst_size);
206 } 212 }
213
214 UnswizzleSubrect(regs.line_length_in, regs.line_count, regs.pitch_out, regs.src_params.width,
215 bytes_per_pixel, read_buffer.data(), write_buffer.data(),
216 regs.src_params.block_size.height, pos_x, pos_y);
217
218 memory_manager.WriteBlock(regs.offset_out, write_buffer.data(), dst_size);
207} 219}
208 220
209} // namespace Tegra::Engines 221} // namespace Tegra::Engines
diff --git a/src/video_core/engines/maxwell_dma.h b/src/video_core/engines/maxwell_dma.h
index 502dd8509..50f445efc 100644
--- a/src/video_core/engines/maxwell_dma.h
+++ b/src/video_core/engines/maxwell_dma.h
@@ -24,160 +24,190 @@ class MemoryManager;
24namespace Tegra::Engines { 24namespace Tegra::Engines {
25 25
26/** 26/**
27 * This Engine is known as GK104_Copy. Documentation can be found in: 27 * This engine is known as gk104_copy. Documentation can be found in:
28 * https://github.com/NVIDIA/open-gpu-doc/blob/master/classes/dma-copy/clb0b5.h
28 * https://github.com/envytools/envytools/blob/master/rnndb/fifo/gk104_copy.xml 29 * https://github.com/envytools/envytools/blob/master/rnndb/fifo/gk104_copy.xml
29 */ 30 */
30 31
31class MaxwellDMA final : public EngineInterface { 32class MaxwellDMA final : public EngineInterface {
32public: 33public:
33 explicit MaxwellDMA(Core::System& system, MemoryManager& memory_manager); 34 struct PackedGPUVAddr {
34 ~MaxwellDMA() = default; 35 u32 upper;
35 36 u32 lower;
36 /// Write the value to the register identified by method. 37
37 void CallMethod(u32 method, u32 method_argument, bool is_last_call) override; 38 constexpr operator GPUVAddr() const noexcept {
38 39 return (static_cast<GPUVAddr>(upper & 0xff) << 32) | lower;
39 /// Write multiple values to the register identified by method. 40 }
40 void CallMultiMethod(u32 method, const u32* base_start, u32 amount, 41 };
41 u32 methods_pending) override; 42
43 union BlockSize {
44 BitField<0, 4, u32> width;
45 BitField<4, 4, u32> height;
46 BitField<8, 4, u32> depth;
47 BitField<12, 4, u32> gob_height;
48 };
49 static_assert(sizeof(BlockSize) == 4);
50
51 union Origin {
52 BitField<0, 16, u32> x;
53 BitField<16, 16, u32> y;
54 };
55 static_assert(sizeof(Origin) == 4);
56
57 struct Parameters {
58 BlockSize block_size;
59 u32 width;
60 u32 height;
61 u32 depth;
62 u32 layer;
63 Origin origin;
64 };
65 static_assert(sizeof(Parameters) == 24);
66
67 struct Semaphore {
68 PackedGPUVAddr address;
69 u32 payload;
70 };
71 static_assert(sizeof(Semaphore) == 12);
72
73 struct RenderEnable {
74 enum class Mode : u32 {
75 FALSE = 0,
76 TRUE = 1,
77 CONDITIONAL = 2,
78 RENDER_IF_EQUAL = 3,
79 RENDER_IF_NOT_EQUAL = 4,
80 };
42 81
43 struct Regs { 82 PackedGPUVAddr address;
44 static constexpr std::size_t NUM_REGS = 0x1D6; 83 BitField<0, 3, Mode> mode;
84 };
85 static_assert(sizeof(RenderEnable) == 12);
86
87 enum class PhysModeTarget : u32 {
88 LOCAL_FB = 0,
89 COHERENT_SYSMEM = 1,
90 NONCOHERENT_SYSMEM = 2,
91 };
92 using PhysMode = BitField<0, 2, PhysModeTarget>;
93
94 union LaunchDMA {
95 enum class DataTransferType : u32 {
96 NONE = 0,
97 PIPELINED = 1,
98 NON_PIPELINED = 2,
99 };
45 100
46 struct Parameters { 101 enum class SemaphoreType : u32 {
47 union { 102 NONE = 0,
48 BitField<0, 4, u32> block_depth; 103 RELEASE_ONE_WORD_SEMAPHORE = 1,
49 BitField<4, 4, u32> block_height; 104 RELEASE_FOUR_WORD_SEMAPHORE = 2,
50 BitField<8, 4, u32> block_width; 105 };
51 };
52 u32 size_x;
53 u32 size_y;
54 u32 size_z;
55 u32 pos_z;
56 union {
57 BitField<0, 16, u32> pos_x;
58 BitField<16, 16, u32> pos_y;
59 };
60 106
61 u32 BlockHeight() const { 107 enum class InterruptType : u32 {
62 return block_height.Value(); 108 NONE = 0,
63 } 109 BLOCKING = 1,
110 NON_BLOCKING = 2,
111 };
64 112
65 u32 BlockDepth() const { 113 enum class MemoryLayout : u32 {
66 return block_depth.Value(); 114 BLOCKLINEAR = 0,
67 } 115 PITCH = 1,
68 }; 116 };
69 117
70 static_assert(sizeof(Parameters) == 24, "Parameters has wrong size"); 118 enum class Type : u32 {
119 VIRTUAL = 0,
120 PHYSICAL = 1,
121 };
71 122
72 enum class ComponentMode : u32 { 123 enum class SemaphoreReduction : u32 {
73 Src0 = 0, 124 IMIN = 0,
74 Src1 = 1, 125 IMAX = 1,
75 Src2 = 2, 126 IXOR = 2,
76 Src3 = 3, 127 IAND = 3,
77 Const0 = 4, 128 IOR = 4,
78 Const1 = 5, 129 IADD = 5,
79 Zero = 6, 130 INC = 6,
131 DEC = 7,
132 FADD = 0xA,
80 }; 133 };
81 134
82 enum class CopyMode : u32 { 135 enum class SemaphoreReductionSign : u32 {
83 None = 0, 136 SIGNED = 0,
84 Unk1 = 1, 137 UNSIGNED = 1,
85 Unk2 = 2,
86 }; 138 };
87 139
88 enum class QueryMode : u32 { 140 enum class BypassL2 : u32 {
89 None = 0, 141 USE_PTE_SETTING = 0,
90 Short = 1, 142 FORCE_VOLATILE = 1,
91 Long = 2,
92 }; 143 };
93 144
94 enum class QueryIntr : u32 { 145 BitField<0, 2, DataTransferType> data_transfer_type;
95 None = 0, 146 BitField<2, 1, u32> flush_enable;
96 Block = 1, 147 BitField<3, 2, SemaphoreType> semaphore_type;
97 NonBlock = 2, 148 BitField<5, 2, InterruptType> interrupt_type;
149 BitField<7, 1, MemoryLayout> src_memory_layout;
150 BitField<8, 1, MemoryLayout> dst_memory_layout;
151 BitField<9, 1, u32> multi_line_enable;
152 BitField<10, 1, u32> remap_enable;
153 BitField<11, 1, u32> rmwdisable;
154 BitField<12, 1, Type> src_type;
155 BitField<13, 1, Type> dst_type;
156 BitField<14, 4, SemaphoreReduction> semaphore_reduction;
157 BitField<18, 1, SemaphoreReductionSign> semaphore_reduction_sign;
158 BitField<19, 1, u32> reduction_enable;
159 BitField<20, 1, BypassL2> bypass_l2;
160 };
161 static_assert(sizeof(LaunchDMA) == 4);
162
163 struct RemapConst {
164 enum Swizzle : u32 {
165 SRC_X = 0,
166 SRC_Y = 1,
167 SRC_Z = 2,
168 SRC_W = 3,
169 CONST_A = 4,
170 CONST_B = 5,
171 NO_WRITE = 6,
98 }; 172 };
99 173
100 union { 174 PackedGPUVAddr address;
101 struct {
102 INSERT_UNION_PADDING_WORDS(0xC0);
103
104 struct {
105 union {
106 BitField<0, 2, CopyMode> copy_mode;
107 BitField<2, 1, u32> flush;
108
109 BitField<3, 2, QueryMode> query_mode;
110 BitField<5, 2, QueryIntr> query_intr;
111
112 BitField<7, 1, u32> is_src_linear;
113 BitField<8, 1, u32> is_dst_linear;
114
115 BitField<9, 1, u32> enable_2d;
116 BitField<10, 1, u32> enable_swizzle;
117 };
118 } exec;
119
120 INSERT_UNION_PADDING_WORDS(0x3F);
121
122 struct {
123 u32 address_high;
124 u32 address_low;
125
126 GPUVAddr Address() const {
127 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
128 address_low);
129 }
130 } src_address;
131
132 struct {
133 u32 address_high;
134 u32 address_low;
135
136 GPUVAddr Address() const {
137 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
138 address_low);
139 }
140 } dst_address;
141
142 u32 src_pitch;
143 u32 dst_pitch;
144 u32 x_count;
145 u32 y_count;
146
147 INSERT_UNION_PADDING_WORDS(0xB8);
148
149 u32 const0;
150 u32 const1;
151 union {
152 BitField<0, 4, ComponentMode> component0;
153 BitField<4, 4, ComponentMode> component1;
154 BitField<8, 4, ComponentMode> component2;
155 BitField<12, 4, ComponentMode> component3;
156 BitField<16, 2, u32> component_size;
157 BitField<20, 3, u32> src_num_components;
158 BitField<24, 3, u32> dst_num_components;
159
160 u32 SrcBytePerPixel() const {
161 return src_num_components.Value() * component_size.Value();
162 }
163 u32 DstBytePerPixel() const {
164 return dst_num_components.Value() * component_size.Value();
165 }
166 } swizzle_config;
167 175
168 Parameters dst_params; 176 union {
177 BitField<0, 3, Swizzle> dst_x;
178 BitField<4, 3, Swizzle> dst_y;
179 BitField<8, 3, Swizzle> dst_z;
180 BitField<12, 3, Swizzle> dst_w;
181 BitField<16, 2, u32> component_size_minus_one;
182 BitField<20, 2, u32> num_src_components_minus_one;
183 BitField<24, 2, u32> num_dst_components_minus_one;
184 };
185 };
186 static_assert(sizeof(RemapConst) == 12);
169 187
170 INSERT_UNION_PADDING_WORDS(1); 188 explicit MaxwellDMA(Core::System& system, MemoryManager& memory_manager);
189 ~MaxwellDMA() = default;
171 190
172 Parameters src_params; 191 /// Write the value to the register identified by method.
192 void CallMethod(u32 method, u32 method_argument, bool is_last_call) override;
173 193
174 INSERT_UNION_PADDING_WORDS(0x13); 194 /// Write multiple values to the register identified by method.
175 }; 195 void CallMultiMethod(u32 method, const u32* base_start, u32 amount,
176 std::array<u32, NUM_REGS> reg_array; 196 u32 methods_pending) override;
177 };
178 } regs{};
179 197
180private: 198private:
199 /// Performs the copy from the source buffer to the destination buffer as configured in the
200 /// registers.
201 void Launch();
202
203 void CopyPitchToPitch();
204
205 void CopyBlockLinearToPitch();
206
207 void CopyPitchToBlockLinear();
208
209 void FastCopyBlockLinearToPitch();
210
181 Core::System& system; 211 Core::System& system;
182 212
183 MemoryManager& memory_manager; 213 MemoryManager& memory_manager;
@@ -185,28 +215,58 @@ private:
185 std::vector<u8> read_buffer; 215 std::vector<u8> read_buffer;
186 std::vector<u8> write_buffer; 216 std::vector<u8> write_buffer;
187 217
188 /// Performs the copy from the source buffer to the destination buffer as configured in the 218 static constexpr std::size_t NUM_REGS = 0x800;
189 /// registers. 219 struct Regs {
190 void HandleCopy(); 220 union {
191}; 221 struct {
222 u32 reserved[0x40];
223 u32 nop;
224 u32 reserved01[0xf];
225 u32 pm_trigger;
226 u32 reserved02[0x3f];
227 Semaphore semaphore;
228 u32 reserved03[0x2];
229 RenderEnable render_enable;
230 PhysMode src_phys_mode;
231 PhysMode dst_phys_mode;
232 u32 reserved04[0x26];
233 LaunchDMA launch_dma;
234 u32 reserved05[0x3f];
235 PackedGPUVAddr offset_in;
236 PackedGPUVAddr offset_out;
237 u32 pitch_in;
238 u32 pitch_out;
239 u32 line_length_in;
240 u32 line_count;
241 u32 reserved06[0xb8];
242 RemapConst remap_const;
243 Parameters dst_params;
244 u32 reserved07[0x1];
245 Parameters src_params;
246 u32 reserved08[0x275];
247 u32 pm_trigger_end;
248 u32 reserved09[0x3ba];
249 };
250 std::array<u32, NUM_REGS> reg_array;
251 };
252 } regs{};
192 253
193#define ASSERT_REG_POSITION(field_name, position) \ 254#define ASSERT_REG_POSITION(field_name, position) \
194 static_assert(offsetof(MaxwellDMA::Regs, field_name) == position * 4, \ 255 static_assert(offsetof(MaxwellDMA::Regs, field_name) == position * 4, \
195 "Field " #field_name " has invalid position") 256 "Field " #field_name " has invalid position")
196 257
197ASSERT_REG_POSITION(exec, 0xC0); 258 ASSERT_REG_POSITION(launch_dma, 0xC0);
198ASSERT_REG_POSITION(src_address, 0x100); 259 ASSERT_REG_POSITION(offset_in, 0x100);
199ASSERT_REG_POSITION(dst_address, 0x102); 260 ASSERT_REG_POSITION(offset_out, 0x102);
200ASSERT_REG_POSITION(src_pitch, 0x104); 261 ASSERT_REG_POSITION(pitch_in, 0x104);
201ASSERT_REG_POSITION(dst_pitch, 0x105); 262 ASSERT_REG_POSITION(pitch_out, 0x105);
202ASSERT_REG_POSITION(x_count, 0x106); 263 ASSERT_REG_POSITION(line_length_in, 0x106);
203ASSERT_REG_POSITION(y_count, 0x107); 264 ASSERT_REG_POSITION(line_count, 0x107);
204ASSERT_REG_POSITION(const0, 0x1C0); 265 ASSERT_REG_POSITION(remap_const, 0x1C0);
205ASSERT_REG_POSITION(const1, 0x1C1); 266 ASSERT_REG_POSITION(dst_params, 0x1C3);
206ASSERT_REG_POSITION(swizzle_config, 0x1C2); 267 ASSERT_REG_POSITION(src_params, 0x1CA);
207ASSERT_REG_POSITION(dst_params, 0x1C3);
208ASSERT_REG_POSITION(src_params, 0x1CA);
209 268
210#undef ASSERT_REG_POSITION 269#undef ASSERT_REG_POSITION
270};
211 271
212} // namespace Tegra::Engines 272} // namespace Tegra::Engines
diff --git a/src/video_core/macro/macro.h b/src/video_core/macro/macro.h
index 4d00b84b0..31ee3440a 100644
--- a/src/video_core/macro/macro.h
+++ b/src/video_core/macro/macro.h
@@ -103,8 +103,9 @@ public:
103 virtual ~CachedMacro() = default; 103 virtual ~CachedMacro() = default;
104 /** 104 /**
105 * Executes the macro code with the specified input parameters. 105 * Executes the macro code with the specified input parameters.
106 * @param code The macro byte code to execute 106 *
107 * @param parameters The parameters of the macro 107 * @param parameters The parameters of the macro
108 * @param method The method to execute
108 */ 109 */
109 virtual void Execute(const std::vector<u32>& parameters, u32 method) = 0; 110 virtual void Execute(const std::vector<u32>& parameters, u32 method) = 0;
110}; 111};
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp
index 410f99018..0c9ff59a4 100644
--- a/src/video_core/macro/macro_hle.cpp
+++ b/src/video_core/macro/macro_hle.cpp
@@ -12,13 +12,11 @@ namespace Tegra {
12 12
13namespace { 13namespace {
14// HLE'd functions 14// HLE'd functions
15static void HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d, 15void HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
16 const std::vector<u32>& parameters) {
17 const u32 instance_count = parameters[2] & maxwell3d.GetRegisterValue(0xD1B); 16 const u32 instance_count = parameters[2] & maxwell3d.GetRegisterValue(0xD1B);
18 17
19 maxwell3d.regs.draw.topology.Assign( 18 maxwell3d.regs.draw.topology.Assign(
20 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 19 static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] & 0x3ffffff));
21 ~(0x3ffffff << 26)));
22 maxwell3d.regs.vb_base_instance = parameters[5]; 20 maxwell3d.regs.vb_base_instance = parameters[5];
23 maxwell3d.mme_draw.instance_count = instance_count; 21 maxwell3d.mme_draw.instance_count = instance_count;
24 maxwell3d.regs.vb_element_base = parameters[3]; 22 maxwell3d.regs.vb_element_base = parameters[3];
@@ -33,8 +31,7 @@ static void HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d,
33 maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; 31 maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
34} 32}
35 33
36static void HLE_0D61FC9FAAC9FCAD(Engines::Maxwell3D& maxwell3d, 34void HLE_0D61FC9FAAC9FCAD(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
37 const std::vector<u32>& parameters) {
38 const u32 count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); 35 const u32 count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
39 36
40 maxwell3d.regs.vertex_buffer.first = parameters[3]; 37 maxwell3d.regs.vertex_buffer.first = parameters[3];
@@ -52,8 +49,7 @@ static void HLE_0D61FC9FAAC9FCAD(Engines::Maxwell3D& maxwell3d,
52 maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; 49 maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
53} 50}
54 51
55static void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, 52void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
56 const std::vector<u32>& parameters) {
57 const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]); 53 const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
58 const u32 element_base = parameters[4]; 54 const u32 element_base = parameters[4];
59 const u32 base_instance = parameters[5]; 55 const u32 base_instance = parameters[5];
@@ -81,12 +77,12 @@ static void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d,
81 maxwell3d.CallMethodFromMME(0x8e5, 0x0); 77 maxwell3d.CallMethodFromMME(0x8e5, 0x0);
82 maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined; 78 maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
83} 79}
84} // namespace 80} // Anonymous namespace
85 81
86constexpr std::array<std::pair<u64, HLEFunction>, 3> hle_funcs{{ 82constexpr std::array<std::pair<u64, HLEFunction>, 3> hle_funcs{{
87 std::make_pair<u64, HLEFunction>(0x771BB18C62444DA0, &HLE_771BB18C62444DA0), 83 {0x771BB18C62444DA0, &HLE_771BB18C62444DA0},
88 std::make_pair<u64, HLEFunction>(0x0D61FC9FAAC9FCAD, &HLE_0D61FC9FAAC9FCAD), 84 {0x0D61FC9FAAC9FCAD, &HLE_0D61FC9FAAC9FCAD},
89 std::make_pair<u64, HLEFunction>(0x0217920100488FF7, &HLE_0217920100488FF7), 85 {0x0217920100488FF7, &HLE_0217920100488FF7},
90}}; 86}};
91 87
92HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d) : maxwell3d(maxwell3d) {} 88HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d) : maxwell3d(maxwell3d) {}
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index fbd406f2b..866813465 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -141,24 +141,28 @@ struct ScreenRectVertex {
141 std::array<f32, 2> tex_coord; 141 std::array<f32, 2> tex_coord;
142 142
143 static VkVertexInputBindingDescription GetDescription() { 143 static VkVertexInputBindingDescription GetDescription() {
144 VkVertexInputBindingDescription description; 144 return {
145 description.binding = 0; 145 .binding = 0,
146 description.stride = sizeof(ScreenRectVertex); 146 .stride = sizeof(ScreenRectVertex),
147 description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; 147 .inputRate = VK_VERTEX_INPUT_RATE_VERTEX,
148 return description; 148 };
149 } 149 }
150 150
151 static std::array<VkVertexInputAttributeDescription, 2> GetAttributes() { 151 static std::array<VkVertexInputAttributeDescription, 2> GetAttributes() {
152 std::array<VkVertexInputAttributeDescription, 2> attributes; 152 return {{
153 attributes[0].location = 0; 153 {
154 attributes[0].binding = 0; 154 .location = 0,
155 attributes[0].format = VK_FORMAT_R32G32_SFLOAT; 155 .binding = 0,
156 attributes[0].offset = offsetof(ScreenRectVertex, position); 156 .format = VK_FORMAT_R32G32_SFLOAT,
157 attributes[1].location = 1; 157 .offset = offsetof(ScreenRectVertex, position),
158 attributes[1].binding = 0; 158 },
159 attributes[1].format = VK_FORMAT_R32G32_SFLOAT; 159 {
160 attributes[1].offset = offsetof(ScreenRectVertex, tex_coord); 160 .location = 1,
161 return attributes; 161 .binding = 0,
162 .format = VK_FORMAT_R32G32_SFLOAT,
163 .offset = offsetof(ScreenRectVertex, tex_coord),
164 },
165 }};
162 } 166 }
163}; 167};
164 168
@@ -267,20 +271,25 @@ std::tuple<VKFence&, VkSemaphore> VKBlitScreen::Draw(const Tegra::FramebufferCon
267 blit_image->Transition(0, 1, 0, 1, VK_PIPELINE_STAGE_TRANSFER_BIT, 271 blit_image->Transition(0, 1, 0, 1, VK_PIPELINE_STAGE_TRANSFER_BIT,
268 VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); 272 VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
269 273
270 VkBufferImageCopy copy; 274 const VkBufferImageCopy copy{
271 copy.bufferOffset = image_offset; 275 .bufferOffset = image_offset,
272 copy.bufferRowLength = 0; 276 .bufferRowLength = 0,
273 copy.bufferImageHeight = 0; 277 .bufferImageHeight = 0,
274 copy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 278 .imageSubresource =
275 copy.imageSubresource.mipLevel = 0; 279 {
276 copy.imageSubresource.baseArrayLayer = 0; 280 .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
277 copy.imageSubresource.layerCount = 1; 281 .mipLevel = 0,
278 copy.imageOffset.x = 0; 282 .baseArrayLayer = 0,
279 copy.imageOffset.y = 0; 283 .layerCount = 1,
280 copy.imageOffset.z = 0; 284 },
281 copy.imageExtent.width = framebuffer.width; 285 .imageOffset = {.x = 0, .y = 0, .z = 0},
282 copy.imageExtent.height = framebuffer.height; 286 .imageExtent =
283 copy.imageExtent.depth = 1; 287 {
288 .width = framebuffer.width,
289 .height = framebuffer.height,
290 .depth = 1,
291 },
292 };
284 scheduler.Record( 293 scheduler.Record(
285 [buffer = *buffer, image = *blit_image->GetHandle(), copy](vk::CommandBuffer cmdbuf) { 294 [buffer = *buffer, image = *blit_image->GetHandle(), copy](vk::CommandBuffer cmdbuf) {
286 cmdbuf.CopyBufferToImage(buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copy); 295 cmdbuf.CopyBufferToImage(buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, copy);
@@ -295,11 +304,9 @@ std::tuple<VKFence&, VkSemaphore> VKBlitScreen::Draw(const Tegra::FramebufferCon
295 descriptor_set = descriptor_sets[image_index], buffer = *buffer, 304 descriptor_set = descriptor_sets[image_index], buffer = *buffer,
296 size = swapchain.GetSize(), pipeline = *pipeline, 305 size = swapchain.GetSize(), pipeline = *pipeline,
297 layout = *pipeline_layout](vk::CommandBuffer cmdbuf) { 306 layout = *pipeline_layout](vk::CommandBuffer cmdbuf) {
298 VkClearValue clear_color; 307 const VkClearValue clear_color{
299 clear_color.color.float32[0] = 0.0f; 308 .color = {.float32 = {0.0f, 0.0f, 0.0f, 0.0f}},
300 clear_color.color.float32[1] = 0.0f; 309 };
301 clear_color.color.float32[2] = 0.0f;
302 clear_color.color.float32[3] = 0.0f;
303 310
304 VkRenderPassBeginInfo renderpass_bi; 311 VkRenderPassBeginInfo renderpass_bi;
305 renderpass_bi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 312 renderpass_bi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
@@ -379,93 +386,109 @@ void VKBlitScreen::CreateSemaphores() {
379} 386}
380 387
381void VKBlitScreen::CreateDescriptorPool() { 388void VKBlitScreen::CreateDescriptorPool() {
382 std::array<VkDescriptorPoolSize, 2> pool_sizes; 389 const std::array<VkDescriptorPoolSize, 2> pool_sizes{{
383 pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 390 {
384 pool_sizes[0].descriptorCount = static_cast<u32>(image_count); 391 .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
385 pool_sizes[1].type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 392 .descriptorCount = static_cast<u32>(image_count),
386 pool_sizes[1].descriptorCount = static_cast<u32>(image_count); 393 },
387 394 {
388 VkDescriptorPoolCreateInfo ci; 395 .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
389 ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; 396 .descriptorCount = static_cast<u32>(image_count),
390 ci.pNext = nullptr; 397 },
391 ci.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; 398 }};
392 ci.maxSets = static_cast<u32>(image_count); 399
393 ci.poolSizeCount = static_cast<u32>(pool_sizes.size()); 400 const VkDescriptorPoolCreateInfo ci{
394 ci.pPoolSizes = pool_sizes.data(); 401 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
402 .pNext = nullptr,
403 .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
404 .maxSets = static_cast<u32>(image_count),
405 .poolSizeCount = static_cast<u32>(pool_sizes.size()),
406 .pPoolSizes = pool_sizes.data(),
407 };
395 descriptor_pool = device.GetLogical().CreateDescriptorPool(ci); 408 descriptor_pool = device.GetLogical().CreateDescriptorPool(ci);
396} 409}
397 410
398void VKBlitScreen::CreateRenderPass() { 411void VKBlitScreen::CreateRenderPass() {
399 VkAttachmentDescription color_attachment; 412 const VkAttachmentDescription color_attachment{
400 color_attachment.flags = 0; 413 .flags = 0,
401 color_attachment.format = swapchain.GetImageFormat(); 414 .format = swapchain.GetImageFormat(),
402 color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; 415 .samples = VK_SAMPLE_COUNT_1_BIT,
403 color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; 416 .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
404 color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 417 .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
405 color_attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; 418 .stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE,
406 color_attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; 419 .stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE,
407 color_attachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 420 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
408 color_attachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; 421 .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
409 422 };
410 VkAttachmentReference color_attachment_ref; 423
411 color_attachment_ref.attachment = 0; 424 const VkAttachmentReference color_attachment_ref{
412 color_attachment_ref.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; 425 .attachment = 0,
413 426 .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
414 VkSubpassDescription subpass_description; 427 };
415 subpass_description.flags = 0; 428
416 subpass_description.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 429 const VkSubpassDescription subpass_description{
417 subpass_description.inputAttachmentCount = 0; 430 .flags = 0,
418 subpass_description.pInputAttachments = nullptr; 431 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
419 subpass_description.colorAttachmentCount = 1; 432 .inputAttachmentCount = 0,
420 subpass_description.pColorAttachments = &color_attachment_ref; 433 .pInputAttachments = nullptr,
421 subpass_description.pResolveAttachments = nullptr; 434 .colorAttachmentCount = 1,
422 subpass_description.pDepthStencilAttachment = nullptr; 435 .pColorAttachments = &color_attachment_ref,
423 subpass_description.preserveAttachmentCount = 0; 436 .pResolveAttachments = nullptr,
424 subpass_description.pPreserveAttachments = nullptr; 437 .pDepthStencilAttachment = nullptr,
425 438 .preserveAttachmentCount = 0,
426 VkSubpassDependency dependency; 439 .pPreserveAttachments = nullptr,
427 dependency.srcSubpass = VK_SUBPASS_EXTERNAL; 440 };
428 dependency.dstSubpass = 0; 441
429 dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 442 const VkSubpassDependency dependency{
430 dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 443 .srcSubpass = VK_SUBPASS_EXTERNAL,
431 dependency.srcAccessMask = 0; 444 .dstSubpass = 0,
432 dependency.dstAccessMask = 445 .srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
433 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; 446 .dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
434 dependency.dependencyFlags = 0; 447 .srcAccessMask = 0,
435 448 .dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
436 VkRenderPassCreateInfo renderpass_ci; 449 .dependencyFlags = 0,
437 renderpass_ci.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; 450 };
438 renderpass_ci.pNext = nullptr; 451
439 renderpass_ci.flags = 0; 452 const VkRenderPassCreateInfo renderpass_ci{
440 renderpass_ci.attachmentCount = 1; 453 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
441 renderpass_ci.pAttachments = &color_attachment; 454 .pNext = nullptr,
442 renderpass_ci.subpassCount = 1; 455 .flags = 0,
443 renderpass_ci.pSubpasses = &subpass_description; 456 .attachmentCount = 1,
444 renderpass_ci.dependencyCount = 1; 457 .pAttachments = &color_attachment,
445 renderpass_ci.pDependencies = &dependency; 458 .subpassCount = 1,
459 .pSubpasses = &subpass_description,
460 .dependencyCount = 1,
461 .pDependencies = &dependency,
462 };
446 463
447 renderpass = device.GetLogical().CreateRenderPass(renderpass_ci); 464 renderpass = device.GetLogical().CreateRenderPass(renderpass_ci);
448} 465}
449 466
450void VKBlitScreen::CreateDescriptorSetLayout() { 467void VKBlitScreen::CreateDescriptorSetLayout() {
451 std::array<VkDescriptorSetLayoutBinding, 2> layout_bindings; 468 const std::array<VkDescriptorSetLayoutBinding, 2> layout_bindings{{
452 layout_bindings[0].binding = 0; 469 {
453 layout_bindings[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 470 .binding = 0,
454 layout_bindings[0].descriptorCount = 1; 471 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
455 layout_bindings[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; 472 .descriptorCount = 1,
456 layout_bindings[0].pImmutableSamplers = nullptr; 473 .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
457 layout_bindings[1].binding = 1; 474 .pImmutableSamplers = nullptr,
458 layout_bindings[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 475 },
459 layout_bindings[1].descriptorCount = 1; 476 {
460 layout_bindings[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; 477 .binding = 1,
461 layout_bindings[1].pImmutableSamplers = nullptr; 478 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
462 479 .descriptorCount = 1,
463 VkDescriptorSetLayoutCreateInfo ci; 480 .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
464 ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 481 .pImmutableSamplers = nullptr,
465 ci.pNext = nullptr; 482 },
466 ci.flags = 0; 483 }};
467 ci.bindingCount = static_cast<u32>(layout_bindings.size()); 484
468 ci.pBindings = layout_bindings.data(); 485 const VkDescriptorSetLayoutCreateInfo ci{
486 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
487 .pNext = nullptr,
488 .flags = 0,
489 .bindingCount = static_cast<u32>(layout_bindings.size()),
490 .pBindings = layout_bindings.data(),
491 };
469 492
470 descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(ci); 493 descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout(ci);
471} 494}
@@ -473,175 +496,192 @@ void VKBlitScreen::CreateDescriptorSetLayout() {
473void VKBlitScreen::CreateDescriptorSets() { 496void VKBlitScreen::CreateDescriptorSets() {
474 const std::vector layouts(image_count, *descriptor_set_layout); 497 const std::vector layouts(image_count, *descriptor_set_layout);
475 498
476 VkDescriptorSetAllocateInfo ai; 499 const VkDescriptorSetAllocateInfo ai{
477 ai.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; 500 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
478 ai.pNext = nullptr; 501 .pNext = nullptr,
479 ai.descriptorPool = *descriptor_pool; 502 .descriptorPool = *descriptor_pool,
480 ai.descriptorSetCount = static_cast<u32>(image_count); 503 .descriptorSetCount = static_cast<u32>(image_count),
481 ai.pSetLayouts = layouts.data(); 504 .pSetLayouts = layouts.data(),
505 };
506
482 descriptor_sets = descriptor_pool.Allocate(ai); 507 descriptor_sets = descriptor_pool.Allocate(ai);
483} 508}
484 509
485void VKBlitScreen::CreatePipelineLayout() { 510void VKBlitScreen::CreatePipelineLayout() {
486 VkPipelineLayoutCreateInfo ci; 511 const VkPipelineLayoutCreateInfo ci{
487 ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 512 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
488 ci.pNext = nullptr; 513 .pNext = nullptr,
489 ci.flags = 0; 514 .flags = 0,
490 ci.setLayoutCount = 1; 515 .setLayoutCount = 1,
491 ci.pSetLayouts = descriptor_set_layout.address(); 516 .pSetLayouts = descriptor_set_layout.address(),
492 ci.pushConstantRangeCount = 0; 517 .pushConstantRangeCount = 0,
493 ci.pPushConstantRanges = nullptr; 518 .pPushConstantRanges = nullptr,
519 };
494 pipeline_layout = device.GetLogical().CreatePipelineLayout(ci); 520 pipeline_layout = device.GetLogical().CreatePipelineLayout(ci);
495} 521}
496 522
497void VKBlitScreen::CreateGraphicsPipeline() { 523void VKBlitScreen::CreateGraphicsPipeline() {
498 std::array<VkPipelineShaderStageCreateInfo, 2> shader_stages; 524 const std::array<VkPipelineShaderStageCreateInfo, 2> shader_stages{{
499 shader_stages[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 525 {
500 shader_stages[0].pNext = nullptr; 526 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
501 shader_stages[0].flags = 0; 527 .pNext = nullptr,
502 shader_stages[0].stage = VK_SHADER_STAGE_VERTEX_BIT; 528 .flags = 0,
503 shader_stages[0].module = *vertex_shader; 529 .stage = VK_SHADER_STAGE_VERTEX_BIT,
504 shader_stages[0].pName = "main"; 530 .module = *vertex_shader,
505 shader_stages[0].pSpecializationInfo = nullptr; 531 .pName = "main",
506 shader_stages[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 532 .pSpecializationInfo = nullptr,
507 shader_stages[1].pNext = nullptr; 533 },
508 shader_stages[1].flags = 0; 534 {
509 shader_stages[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; 535 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
510 shader_stages[1].module = *fragment_shader; 536 .pNext = nullptr,
511 shader_stages[1].pName = "main"; 537 .flags = 0,
512 shader_stages[1].pSpecializationInfo = nullptr; 538 .stage = VK_SHADER_STAGE_FRAGMENT_BIT,
539 .module = *fragment_shader,
540 .pName = "main",
541 .pSpecializationInfo = nullptr,
542 },
543 }};
513 544
514 const auto vertex_binding_description = ScreenRectVertex::GetDescription(); 545 const auto vertex_binding_description = ScreenRectVertex::GetDescription();
515 const auto vertex_attrs_description = ScreenRectVertex::GetAttributes(); 546 const auto vertex_attrs_description = ScreenRectVertex::GetAttributes();
516 547
517 VkPipelineVertexInputStateCreateInfo vertex_input_ci; 548 const VkPipelineVertexInputStateCreateInfo vertex_input_ci{
518 vertex_input_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 549 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
519 vertex_input_ci.pNext = nullptr; 550 .pNext = nullptr,
520 vertex_input_ci.flags = 0; 551 .flags = 0,
521 vertex_input_ci.vertexBindingDescriptionCount = 1; 552 .vertexBindingDescriptionCount = 1,
522 vertex_input_ci.pVertexBindingDescriptions = &vertex_binding_description; 553 .pVertexBindingDescriptions = &vertex_binding_description,
523 vertex_input_ci.vertexAttributeDescriptionCount = u32{vertex_attrs_description.size()}; 554 .vertexAttributeDescriptionCount = u32{vertex_attrs_description.size()},
524 vertex_input_ci.pVertexAttributeDescriptions = vertex_attrs_description.data(); 555 .pVertexAttributeDescriptions = vertex_attrs_description.data(),
525 556 };
526 VkPipelineInputAssemblyStateCreateInfo input_assembly_ci; 557
527 input_assembly_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 558 const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci{
528 input_assembly_ci.pNext = nullptr; 559 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
529 input_assembly_ci.flags = 0; 560 .pNext = nullptr,
530 input_assembly_ci.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP; 561 .flags = 0,
531 input_assembly_ci.primitiveRestartEnable = VK_FALSE; 562 .topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
532 563 .primitiveRestartEnable = VK_FALSE,
533 VkPipelineViewportStateCreateInfo viewport_state_ci; 564 };
534 viewport_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 565
535 viewport_state_ci.pNext = nullptr; 566 const VkPipelineViewportStateCreateInfo viewport_state_ci{
536 viewport_state_ci.flags = 0; 567 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
537 viewport_state_ci.viewportCount = 1; 568 .pNext = nullptr,
538 viewport_state_ci.pViewports = nullptr; 569 .flags = 0,
539 viewport_state_ci.scissorCount = 1; 570 .viewportCount = 1,
540 viewport_state_ci.pScissors = nullptr; 571 .pViewports = nullptr,
541 572 .scissorCount = 1,
542 VkPipelineRasterizationStateCreateInfo rasterization_ci; 573 .pScissors = nullptr,
543 rasterization_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 574 };
544 rasterization_ci.pNext = nullptr; 575
545 rasterization_ci.flags = 0; 576 const VkPipelineRasterizationStateCreateInfo rasterization_ci{
546 rasterization_ci.depthClampEnable = VK_FALSE; 577 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
547 rasterization_ci.rasterizerDiscardEnable = VK_FALSE; 578 .pNext = nullptr,
548 rasterization_ci.polygonMode = VK_POLYGON_MODE_FILL; 579 .flags = 0,
549 rasterization_ci.cullMode = VK_CULL_MODE_NONE; 580 .depthClampEnable = VK_FALSE,
550 rasterization_ci.frontFace = VK_FRONT_FACE_CLOCKWISE; 581 .rasterizerDiscardEnable = VK_FALSE,
551 rasterization_ci.depthBiasEnable = VK_FALSE; 582 .polygonMode = VK_POLYGON_MODE_FILL,
552 rasterization_ci.depthBiasConstantFactor = 0.0f; 583 .cullMode = VK_CULL_MODE_NONE,
553 rasterization_ci.depthBiasClamp = 0.0f; 584 .frontFace = VK_FRONT_FACE_CLOCKWISE,
554 rasterization_ci.depthBiasSlopeFactor = 0.0f; 585 .depthBiasEnable = VK_FALSE,
555 rasterization_ci.lineWidth = 1.0f; 586 .depthBiasConstantFactor = 0.0f,
556 587 .depthBiasClamp = 0.0f,
557 VkPipelineMultisampleStateCreateInfo multisampling_ci; 588 .depthBiasSlopeFactor = 0.0f,
558 multisampling_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 589 .lineWidth = 1.0f,
559 multisampling_ci.pNext = nullptr; 590 };
560 multisampling_ci.flags = 0; 591
561 multisampling_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 592 const VkPipelineMultisampleStateCreateInfo multisampling_ci{
562 multisampling_ci.sampleShadingEnable = VK_FALSE; 593 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
563 multisampling_ci.minSampleShading = 0.0f; 594 .pNext = nullptr,
564 multisampling_ci.pSampleMask = nullptr; 595 .flags = 0,
565 multisampling_ci.alphaToCoverageEnable = VK_FALSE; 596 .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
566 multisampling_ci.alphaToOneEnable = VK_FALSE; 597 .sampleShadingEnable = VK_FALSE,
567 598 .minSampleShading = 0.0f,
568 VkPipelineColorBlendAttachmentState color_blend_attachment; 599 .pSampleMask = nullptr,
569 color_blend_attachment.blendEnable = VK_FALSE; 600 .alphaToCoverageEnable = VK_FALSE,
570 color_blend_attachment.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO; 601 .alphaToOneEnable = VK_FALSE,
571 color_blend_attachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; 602 };
572 color_blend_attachment.colorBlendOp = VK_BLEND_OP_ADD; 603
573 color_blend_attachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; 604 const VkPipelineColorBlendAttachmentState color_blend_attachment{
574 color_blend_attachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; 605 .blendEnable = VK_FALSE,
575 color_blend_attachment.alphaBlendOp = VK_BLEND_OP_ADD; 606 .srcColorBlendFactor = VK_BLEND_FACTOR_ZERO,
576 color_blend_attachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | 607 .dstColorBlendFactor = VK_BLEND_FACTOR_ZERO,
577 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 608 .colorBlendOp = VK_BLEND_OP_ADD,
578 609 .srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
579 VkPipelineColorBlendStateCreateInfo color_blend_ci; 610 .dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO,
580 color_blend_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 611 .alphaBlendOp = VK_BLEND_OP_ADD,
581 color_blend_ci.flags = 0; 612 .colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT |
582 color_blend_ci.pNext = nullptr; 613 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT,
583 color_blend_ci.logicOpEnable = VK_FALSE; 614 };
584 color_blend_ci.logicOp = VK_LOGIC_OP_COPY; 615
585 color_blend_ci.attachmentCount = 1; 616 const VkPipelineColorBlendStateCreateInfo color_blend_ci{
586 color_blend_ci.pAttachments = &color_blend_attachment; 617 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
587 color_blend_ci.blendConstants[0] = 0.0f; 618 .pNext = nullptr,
588 color_blend_ci.blendConstants[1] = 0.0f; 619 .flags = 0,
589 color_blend_ci.blendConstants[2] = 0.0f; 620 .logicOpEnable = VK_FALSE,
590 color_blend_ci.blendConstants[3] = 0.0f; 621 .logicOp = VK_LOGIC_OP_COPY,
591 622 .attachmentCount = 1,
592 static constexpr std::array dynamic_states = {VK_DYNAMIC_STATE_VIEWPORT, 623 .pAttachments = &color_blend_attachment,
593 VK_DYNAMIC_STATE_SCISSOR}; 624 .blendConstants = {0.0f, 0.0f, 0.0f, 0.0f},
594 VkPipelineDynamicStateCreateInfo dynamic_state_ci; 625 };
595 dynamic_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 626
596 dynamic_state_ci.pNext = nullptr; 627 static constexpr std::array dynamic_states{
597 dynamic_state_ci.flags = 0; 628 VK_DYNAMIC_STATE_VIEWPORT,
598 dynamic_state_ci.dynamicStateCount = static_cast<u32>(dynamic_states.size()); 629 VK_DYNAMIC_STATE_SCISSOR,
599 dynamic_state_ci.pDynamicStates = dynamic_states.data(); 630 };
600 631 const VkPipelineDynamicStateCreateInfo dynamic_state_ci{
601 VkGraphicsPipelineCreateInfo pipeline_ci; 632 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
602 pipeline_ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 633 .pNext = nullptr,
603 pipeline_ci.pNext = nullptr; 634 .flags = 0,
604 pipeline_ci.flags = 0; 635 .dynamicStateCount = static_cast<u32>(dynamic_states.size()),
605 pipeline_ci.stageCount = static_cast<u32>(shader_stages.size()); 636 .pDynamicStates = dynamic_states.data(),
606 pipeline_ci.pStages = shader_stages.data(); 637 };
607 pipeline_ci.pVertexInputState = &vertex_input_ci; 638
608 pipeline_ci.pInputAssemblyState = &input_assembly_ci; 639 const VkGraphicsPipelineCreateInfo pipeline_ci{
609 pipeline_ci.pTessellationState = nullptr; 640 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
610 pipeline_ci.pViewportState = &viewport_state_ci; 641 .pNext = nullptr,
611 pipeline_ci.pRasterizationState = &rasterization_ci; 642 .flags = 0,
612 pipeline_ci.pMultisampleState = &multisampling_ci; 643 .stageCount = static_cast<u32>(shader_stages.size()),
613 pipeline_ci.pDepthStencilState = nullptr; 644 .pStages = shader_stages.data(),
614 pipeline_ci.pColorBlendState = &color_blend_ci; 645 .pVertexInputState = &vertex_input_ci,
615 pipeline_ci.pDynamicState = &dynamic_state_ci; 646 .pInputAssemblyState = &input_assembly_ci,
616 pipeline_ci.layout = *pipeline_layout; 647 .pTessellationState = nullptr,
617 pipeline_ci.renderPass = *renderpass; 648 .pViewportState = &viewport_state_ci,
618 pipeline_ci.subpass = 0; 649 .pRasterizationState = &rasterization_ci,
619 pipeline_ci.basePipelineHandle = 0; 650 .pMultisampleState = &multisampling_ci,
620 pipeline_ci.basePipelineIndex = 0; 651 .pDepthStencilState = nullptr,
652 .pColorBlendState = &color_blend_ci,
653 .pDynamicState = &dynamic_state_ci,
654 .layout = *pipeline_layout,
655 .renderPass = *renderpass,
656 .subpass = 0,
657 .basePipelineHandle = 0,
658 .basePipelineIndex = 0,
659 };
621 660
622 pipeline = device.GetLogical().CreateGraphicsPipeline(pipeline_ci); 661 pipeline = device.GetLogical().CreateGraphicsPipeline(pipeline_ci);
623} 662}
624 663
625void VKBlitScreen::CreateSampler() { 664void VKBlitScreen::CreateSampler() {
626 VkSamplerCreateInfo ci; 665 const VkSamplerCreateInfo ci{
627 ci.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; 666 .sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
628 ci.pNext = nullptr; 667 .pNext = nullptr,
629 ci.flags = 0; 668 .flags = 0,
630 ci.magFilter = VK_FILTER_LINEAR; 669 .magFilter = VK_FILTER_LINEAR,
631 ci.minFilter = VK_FILTER_NEAREST; 670 .minFilter = VK_FILTER_NEAREST,
632 ci.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; 671 .mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR,
633 ci.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; 672 .addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
634 ci.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; 673 .addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
635 ci.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER; 674 .addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER,
636 ci.mipLodBias = 0.0f; 675 .mipLodBias = 0.0f,
637 ci.anisotropyEnable = VK_FALSE; 676 .anisotropyEnable = VK_FALSE,
638 ci.maxAnisotropy = 0.0f; 677 .maxAnisotropy = 0.0f,
639 ci.compareEnable = VK_FALSE; 678 .compareEnable = VK_FALSE,
640 ci.compareOp = VK_COMPARE_OP_NEVER; 679 .compareOp = VK_COMPARE_OP_NEVER,
641 ci.minLod = 0.0f; 680 .minLod = 0.0f,
642 ci.maxLod = 0.0f; 681 .maxLod = 0.0f,
643 ci.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK; 682 .borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK,
644 ci.unnormalizedCoordinates = VK_FALSE; 683 .unnormalizedCoordinates = VK_FALSE,
684 };
645 685
646 sampler = device.GetLogical().CreateSampler(ci); 686 sampler = device.GetLogical().CreateSampler(ci);
647} 687}
@@ -650,15 +690,16 @@ void VKBlitScreen::CreateFramebuffers() {
650 const VkExtent2D size{swapchain.GetSize()}; 690 const VkExtent2D size{swapchain.GetSize()};
651 framebuffers.resize(image_count); 691 framebuffers.resize(image_count);
652 692
653 VkFramebufferCreateInfo ci; 693 VkFramebufferCreateInfo ci{
654 ci.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 694 .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
655 ci.pNext = nullptr; 695 .pNext = nullptr,
656 ci.flags = 0; 696 .flags = 0,
657 ci.renderPass = *renderpass; 697 .renderPass = *renderpass,
658 ci.attachmentCount = 1; 698 .attachmentCount = 1,
659 ci.width = size.width; 699 .width = size.width,
660 ci.height = size.height; 700 .height = size.height,
661 ci.layers = 1; 701 .layers = 1,
702 };
662 703
663 for (std::size_t i = 0; i < image_count; ++i) { 704 for (std::size_t i = 0; i < image_count; ++i) {
664 const VkImageView image_view{swapchain.GetImageViewIndex(i)}; 705 const VkImageView image_view{swapchain.GetImageViewIndex(i)};
@@ -678,16 +719,17 @@ void VKBlitScreen::ReleaseRawImages() {
678} 719}
679 720
680void VKBlitScreen::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer) { 721void VKBlitScreen::CreateStagingBuffer(const Tegra::FramebufferConfig& framebuffer) {
681 VkBufferCreateInfo ci; 722 const VkBufferCreateInfo ci{
682 ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; 723 .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
683 ci.pNext = nullptr; 724 .pNext = nullptr,
684 ci.flags = 0; 725 .flags = 0,
685 ci.size = CalculateBufferSize(framebuffer); 726 .size = CalculateBufferSize(framebuffer),
686 ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | 727 .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
687 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT; 728 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
688 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 729 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
689 ci.queueFamilyIndexCount = 0; 730 .queueFamilyIndexCount = 0,
690 ci.pQueueFamilyIndices = nullptr; 731 .pQueueFamilyIndices = nullptr,
732 };
691 733
692 buffer = device.GetLogical().CreateBuffer(ci); 734 buffer = device.GetLogical().CreateBuffer(ci);
693 buffer_commit = memory_manager.Commit(buffer, true); 735 buffer_commit = memory_manager.Commit(buffer, true);
@@ -697,24 +739,28 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer)
697 raw_images.resize(image_count); 739 raw_images.resize(image_count);
698 raw_buffer_commits.resize(image_count); 740 raw_buffer_commits.resize(image_count);
699 741
700 VkImageCreateInfo ci; 742 const VkImageCreateInfo ci{
701 ci.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; 743 .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
702 ci.pNext = nullptr; 744 .pNext = nullptr,
703 ci.flags = 0; 745 .flags = 0,
704 ci.imageType = VK_IMAGE_TYPE_2D; 746 .imageType = VK_IMAGE_TYPE_2D,
705 ci.format = GetFormat(framebuffer); 747 .format = GetFormat(framebuffer),
706 ci.extent.width = framebuffer.width; 748 .extent =
707 ci.extent.height = framebuffer.height; 749 {
708 ci.extent.depth = 1; 750 .width = framebuffer.width,
709 ci.mipLevels = 1; 751 .height = framebuffer.height,
710 ci.arrayLayers = 1; 752 .depth = 1,
711 ci.samples = VK_SAMPLE_COUNT_1_BIT; 753 },
712 ci.tiling = VK_IMAGE_TILING_LINEAR; 754 .mipLevels = 1,
713 ci.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; 755 .arrayLayers = 1,
714 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 756 .samples = VK_SAMPLE_COUNT_1_BIT,
715 ci.queueFamilyIndexCount = 0; 757 .tiling = VK_IMAGE_TILING_LINEAR,
716 ci.pQueueFamilyIndices = nullptr; 758 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
717 ci.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; 759 .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
760 .queueFamilyIndexCount = 0,
761 .pQueueFamilyIndices = nullptr,
762 .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
763 };
718 764
719 for (std::size_t i = 0; i < image_count; ++i) { 765 for (std::size_t i = 0; i < image_count; ++i) {
720 raw_images[i] = std::make_unique<VKImage>(device, scheduler, ci, VK_IMAGE_ASPECT_COLOR_BIT); 766 raw_images[i] = std::make_unique<VKImage>(device, scheduler, ci, VK_IMAGE_ASPECT_COLOR_BIT);
@@ -723,39 +769,43 @@ void VKBlitScreen::CreateRawImages(const Tegra::FramebufferConfig& framebuffer)
723} 769}
724 770
725void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const { 771void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const {
726 VkDescriptorBufferInfo buffer_info; 772 const VkDescriptorBufferInfo buffer_info{
727 buffer_info.buffer = *buffer; 773 .buffer = *buffer,
728 buffer_info.offset = offsetof(BufferData, uniform); 774 .offset = offsetof(BufferData, uniform),
729 buffer_info.range = sizeof(BufferData::uniform); 775 .range = sizeof(BufferData::uniform),
730 776 };
731 VkWriteDescriptorSet ubo_write; 777
732 ubo_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 778 const VkWriteDescriptorSet ubo_write{
733 ubo_write.pNext = nullptr; 779 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
734 ubo_write.dstSet = descriptor_sets[image_index]; 780 .pNext = nullptr,
735 ubo_write.dstBinding = 0; 781 .dstSet = descriptor_sets[image_index],
736 ubo_write.dstArrayElement = 0; 782 .dstBinding = 0,
737 ubo_write.descriptorCount = 1; 783 .dstArrayElement = 0,
738 ubo_write.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; 784 .descriptorCount = 1,
739 ubo_write.pImageInfo = nullptr; 785 .descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
740 ubo_write.pBufferInfo = &buffer_info; 786 .pImageInfo = nullptr,
741 ubo_write.pTexelBufferView = nullptr; 787 .pBufferInfo = &buffer_info,
742 788 .pTexelBufferView = nullptr,
743 VkDescriptorImageInfo image_info; 789 };
744 image_info.sampler = *sampler; 790
745 image_info.imageView = image_view; 791 const VkDescriptorImageInfo image_info{
746 image_info.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; 792 .sampler = *sampler,
747 793 .imageView = image_view,
748 VkWriteDescriptorSet sampler_write; 794 .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
749 sampler_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; 795 };
750 sampler_write.pNext = nullptr; 796
751 sampler_write.dstSet = descriptor_sets[image_index]; 797 const VkWriteDescriptorSet sampler_write{
752 sampler_write.dstBinding = 1; 798 .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
753 sampler_write.dstArrayElement = 0; 799 .pNext = nullptr,
754 sampler_write.descriptorCount = 1; 800 .dstSet = descriptor_sets[image_index],
755 sampler_write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; 801 .dstBinding = 1,
756 sampler_write.pImageInfo = &image_info; 802 .dstArrayElement = 0,
757 sampler_write.pBufferInfo = nullptr; 803 .descriptorCount = 1,
758 sampler_write.pTexelBufferView = nullptr; 804 .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
805 .pImageInfo = &image_info,
806 .pBufferInfo = nullptr,
807 .pTexelBufferView = nullptr,
808 };
759 809
760 device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {}); 810 device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {});
761} 811}
diff --git a/src/video_core/renderer_vulkan/vk_device.cpp b/src/video_core/renderer_vulkan/vk_device.cpp
index fdaea4210..9226e591c 100644
--- a/src/video_core/renderer_vulkan/vk_device.cpp
+++ b/src/video_core/renderer_vulkan/vk_device.cpp
@@ -22,14 +22,21 @@ namespace {
22 22
23namespace Alternatives { 23namespace Alternatives {
24 24
25constexpr std::array Depth24UnormS8_UINT = {VK_FORMAT_D32_SFLOAT_S8_UINT, 25constexpr std::array Depth24UnormS8_UINT{
26 VK_FORMAT_D16_UNORM_S8_UINT, VkFormat{}}; 26 VK_FORMAT_D32_SFLOAT_S8_UINT,
27constexpr std::array Depth16UnormS8_UINT = {VK_FORMAT_D24_UNORM_S8_UINT, 27 VK_FORMAT_D16_UNORM_S8_UINT,
28 VK_FORMAT_D32_SFLOAT_S8_UINT, VkFormat{}}; 28 VkFormat{},
29};
30
31constexpr std::array Depth16UnormS8_UINT{
32 VK_FORMAT_D24_UNORM_S8_UINT,
33 VK_FORMAT_D32_SFLOAT_S8_UINT,
34 VkFormat{},
35};
29 36
30} // namespace Alternatives 37} // namespace Alternatives
31 38
32constexpr std::array REQUIRED_EXTENSIONS = { 39constexpr std::array REQUIRED_EXTENSIONS{
33 VK_KHR_SWAPCHAIN_EXTENSION_NAME, 40 VK_KHR_SWAPCHAIN_EXTENSION_NAME,
34 VK_KHR_16BIT_STORAGE_EXTENSION_NAME, 41 VK_KHR_16BIT_STORAGE_EXTENSION_NAME,
35 VK_KHR_8BIT_STORAGE_EXTENSION_NAME, 42 VK_KHR_8BIT_STORAGE_EXTENSION_NAME,
@@ -169,97 +176,104 @@ bool VKDevice::Create() {
169 const auto queue_cis = GetDeviceQueueCreateInfos(); 176 const auto queue_cis = GetDeviceQueueCreateInfos();
170 const std::vector extensions = LoadExtensions(); 177 const std::vector extensions = LoadExtensions();
171 178
172 VkPhysicalDeviceFeatures2 features2; 179 VkPhysicalDeviceFeatures2 features2{
173 features2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2; 180 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
174 features2.pNext = nullptr; 181 .pNext = nullptr,
182 };
175 const void* first_next = &features2; 183 const void* first_next = &features2;
176 void** next = &features2.pNext; 184 void** next = &features2.pNext;
177 185
178 auto& features = features2.features; 186 features2.features = {
179 features.robustBufferAccess = false; 187 .robustBufferAccess = false,
180 features.fullDrawIndexUint32 = false; 188 .fullDrawIndexUint32 = false,
181 features.imageCubeArray = false; 189 .imageCubeArray = false,
182 features.independentBlend = true; 190 .independentBlend = true,
183 features.geometryShader = true; 191 .geometryShader = true,
184 features.tessellationShader = true; 192 .tessellationShader = true,
185 features.sampleRateShading = false; 193 .sampleRateShading = false,
186 features.dualSrcBlend = false; 194 .dualSrcBlend = false,
187 features.logicOp = false; 195 .logicOp = false,
188 features.multiDrawIndirect = false; 196 .multiDrawIndirect = false,
189 features.drawIndirectFirstInstance = false; 197 .drawIndirectFirstInstance = false,
190 features.depthClamp = true; 198 .depthClamp = true,
191 features.depthBiasClamp = true; 199 .depthBiasClamp = true,
192 features.fillModeNonSolid = false; 200 .fillModeNonSolid = false,
193 features.depthBounds = false; 201 .depthBounds = false,
194 features.wideLines = false; 202 .wideLines = false,
195 features.largePoints = true; 203 .largePoints = true,
196 features.alphaToOne = false; 204 .alphaToOne = false,
197 features.multiViewport = true; 205 .multiViewport = true,
198 features.samplerAnisotropy = true; 206 .samplerAnisotropy = true,
199 features.textureCompressionETC2 = false; 207 .textureCompressionETC2 = false,
200 features.textureCompressionASTC_LDR = is_optimal_astc_supported; 208 .textureCompressionASTC_LDR = is_optimal_astc_supported,
201 features.textureCompressionBC = false; 209 .textureCompressionBC = false,
202 features.occlusionQueryPrecise = true; 210 .occlusionQueryPrecise = true,
203 features.pipelineStatisticsQuery = false; 211 .pipelineStatisticsQuery = false,
204 features.vertexPipelineStoresAndAtomics = true; 212 .vertexPipelineStoresAndAtomics = true,
205 features.fragmentStoresAndAtomics = true; 213 .fragmentStoresAndAtomics = true,
206 features.shaderTessellationAndGeometryPointSize = false; 214 .shaderTessellationAndGeometryPointSize = false,
207 features.shaderImageGatherExtended = true; 215 .shaderImageGatherExtended = true,
208 features.shaderStorageImageExtendedFormats = false; 216 .shaderStorageImageExtendedFormats = false,
209 features.shaderStorageImageMultisample = false; 217 .shaderStorageImageMultisample = false,
210 features.shaderStorageImageReadWithoutFormat = is_formatless_image_load_supported; 218 .shaderStorageImageReadWithoutFormat = is_formatless_image_load_supported,
211 features.shaderStorageImageWriteWithoutFormat = true; 219 .shaderStorageImageWriteWithoutFormat = true,
212 features.shaderUniformBufferArrayDynamicIndexing = false; 220 .shaderUniformBufferArrayDynamicIndexing = false,
213 features.shaderSampledImageArrayDynamicIndexing = false; 221 .shaderSampledImageArrayDynamicIndexing = false,
214 features.shaderStorageBufferArrayDynamicIndexing = false; 222 .shaderStorageBufferArrayDynamicIndexing = false,
215 features.shaderStorageImageArrayDynamicIndexing = false; 223 .shaderStorageImageArrayDynamicIndexing = false,
216 features.shaderClipDistance = false; 224 .shaderClipDistance = false,
217 features.shaderCullDistance = false; 225 .shaderCullDistance = false,
218 features.shaderFloat64 = false; 226 .shaderFloat64 = false,
219 features.shaderInt64 = false; 227 .shaderInt64 = false,
220 features.shaderInt16 = false; 228 .shaderInt16 = false,
221 features.shaderResourceResidency = false; 229 .shaderResourceResidency = false,
222 features.shaderResourceMinLod = false; 230 .shaderResourceMinLod = false,
223 features.sparseBinding = false; 231 .sparseBinding = false,
224 features.sparseResidencyBuffer = false; 232 .sparseResidencyBuffer = false,
225 features.sparseResidencyImage2D = false; 233 .sparseResidencyImage2D = false,
226 features.sparseResidencyImage3D = false; 234 .sparseResidencyImage3D = false,
227 features.sparseResidency2Samples = false; 235 .sparseResidency2Samples = false,
228 features.sparseResidency4Samples = false; 236 .sparseResidency4Samples = false,
229 features.sparseResidency8Samples = false; 237 .sparseResidency8Samples = false,
230 features.sparseResidency16Samples = false; 238 .sparseResidency16Samples = false,
231 features.sparseResidencyAliased = false; 239 .sparseResidencyAliased = false,
232 features.variableMultisampleRate = false; 240 .variableMultisampleRate = false,
233 features.inheritedQueries = false; 241 .inheritedQueries = false,
234 242 };
235 VkPhysicalDevice16BitStorageFeaturesKHR bit16_storage; 243
236 bit16_storage.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR; 244 VkPhysicalDevice16BitStorageFeaturesKHR bit16_storage{
237 bit16_storage.pNext = nullptr; 245 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR,
238 bit16_storage.storageBuffer16BitAccess = false; 246 .pNext = nullptr,
239 bit16_storage.uniformAndStorageBuffer16BitAccess = true; 247 .storageBuffer16BitAccess = false,
240 bit16_storage.storagePushConstant16 = false; 248 .uniformAndStorageBuffer16BitAccess = true,
241 bit16_storage.storageInputOutput16 = false; 249 .storagePushConstant16 = false,
250 .storageInputOutput16 = false,
251 };
242 SetNext(next, bit16_storage); 252 SetNext(next, bit16_storage);
243 253
244 VkPhysicalDevice8BitStorageFeaturesKHR bit8_storage; 254 VkPhysicalDevice8BitStorageFeaturesKHR bit8_storage{
245 bit8_storage.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR; 255 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR,
246 bit8_storage.pNext = nullptr; 256 .pNext = nullptr,
247 bit8_storage.storageBuffer8BitAccess = false; 257 .storageBuffer8BitAccess = false,
248 bit8_storage.uniformAndStorageBuffer8BitAccess = true; 258 .uniformAndStorageBuffer8BitAccess = true,
249 bit8_storage.storagePushConstant8 = false; 259 .storagePushConstant8 = false,
260 };
250 SetNext(next, bit8_storage); 261 SetNext(next, bit8_storage);
251 262
252 VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset; 263 VkPhysicalDeviceHostQueryResetFeaturesEXT host_query_reset{
253 host_query_reset.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT; 264 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_QUERY_RESET_FEATURES_EXT,
254 host_query_reset.hostQueryReset = true; 265 .hostQueryReset = true,
266 };
255 SetNext(next, host_query_reset); 267 SetNext(next, host_query_reset);
256 268
257 VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8; 269 VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8;
258 if (is_float16_supported) { 270 if (is_float16_supported) {
259 float16_int8.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR; 271 float16_int8 = {
260 float16_int8.pNext = nullptr; 272 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR,
261 float16_int8.shaderFloat16 = true; 273 .pNext = nullptr,
262 float16_int8.shaderInt8 = false; 274 .shaderFloat16 = true,
275 .shaderInt8 = false,
276 };
263 SetNext(next, float16_int8); 277 SetNext(next, float16_int8);
264 } else { 278 } else {
265 LOG_INFO(Render_Vulkan, "Device doesn't support float16 natively"); 279 LOG_INFO(Render_Vulkan, "Device doesn't support float16 natively");
@@ -271,10 +285,11 @@ bool VKDevice::Create() {
271 285
272 VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout; 286 VkPhysicalDeviceUniformBufferStandardLayoutFeaturesKHR std430_layout;
273 if (khr_uniform_buffer_standard_layout) { 287 if (khr_uniform_buffer_standard_layout) {
274 std430_layout.sType = 288 std430_layout = {
275 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR; 289 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_UNIFORM_BUFFER_STANDARD_LAYOUT_FEATURES_KHR,
276 std430_layout.pNext = nullptr; 290 .pNext = nullptr,
277 std430_layout.uniformBufferStandardLayout = true; 291 .uniformBufferStandardLayout = true,
292 };
278 SetNext(next, std430_layout); 293 SetNext(next, std430_layout);
279 } else { 294 } else {
280 LOG_INFO(Render_Vulkan, "Device doesn't support packed UBOs"); 295 LOG_INFO(Render_Vulkan, "Device doesn't support packed UBOs");
@@ -282,9 +297,11 @@ bool VKDevice::Create() {
282 297
283 VkPhysicalDeviceIndexTypeUint8FeaturesEXT index_type_uint8; 298 VkPhysicalDeviceIndexTypeUint8FeaturesEXT index_type_uint8;
284 if (ext_index_type_uint8) { 299 if (ext_index_type_uint8) {
285 index_type_uint8.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT; 300 index_type_uint8 = {
286 index_type_uint8.pNext = nullptr; 301 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INDEX_TYPE_UINT8_FEATURES_EXT,
287 index_type_uint8.indexTypeUint8 = true; 302 .pNext = nullptr,
303 .indexTypeUint8 = true,
304 };
288 SetNext(next, index_type_uint8); 305 SetNext(next, index_type_uint8);
289 } else { 306 } else {
290 LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes"); 307 LOG_INFO(Render_Vulkan, "Device doesn't support uint8 indexes");
@@ -292,11 +309,12 @@ bool VKDevice::Create() {
292 309
293 VkPhysicalDeviceTransformFeedbackFeaturesEXT transform_feedback; 310 VkPhysicalDeviceTransformFeedbackFeaturesEXT transform_feedback;
294 if (ext_transform_feedback) { 311 if (ext_transform_feedback) {
295 transform_feedback.sType = 312 transform_feedback = {
296 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT; 313 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT,
297 transform_feedback.pNext = nullptr; 314 .pNext = nullptr,
298 transform_feedback.transformFeedback = true; 315 .transformFeedback = true,
299 transform_feedback.geometryStreams = true; 316 .geometryStreams = true,
317 };
300 SetNext(next, transform_feedback); 318 SetNext(next, transform_feedback);
301 } else { 319 } else {
302 LOG_INFO(Render_Vulkan, "Device doesn't support transform feedbacks"); 320 LOG_INFO(Render_Vulkan, "Device doesn't support transform feedbacks");
@@ -304,10 +322,12 @@ bool VKDevice::Create() {
304 322
305 VkPhysicalDeviceCustomBorderColorFeaturesEXT custom_border; 323 VkPhysicalDeviceCustomBorderColorFeaturesEXT custom_border;
306 if (ext_custom_border_color) { 324 if (ext_custom_border_color) {
307 custom_border.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT; 325 custom_border = {
308 custom_border.pNext = nullptr; 326 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT,
309 custom_border.customBorderColors = VK_TRUE; 327 .pNext = nullptr,
310 custom_border.customBorderColorWithoutFormat = VK_TRUE; 328 .customBorderColors = VK_TRUE,
329 .customBorderColorWithoutFormat = VK_TRUE,
330 };
311 SetNext(next, custom_border); 331 SetNext(next, custom_border);
312 } else { 332 } else {
313 LOG_INFO(Render_Vulkan, "Device doesn't support custom border colors"); 333 LOG_INFO(Render_Vulkan, "Device doesn't support custom border colors");
@@ -315,9 +335,11 @@ bool VKDevice::Create() {
315 335
316 VkPhysicalDeviceExtendedDynamicStateFeaturesEXT dynamic_state; 336 VkPhysicalDeviceExtendedDynamicStateFeaturesEXT dynamic_state;
317 if (ext_extended_dynamic_state) { 337 if (ext_extended_dynamic_state) {
318 dynamic_state.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT; 338 dynamic_state = {
319 dynamic_state.pNext = nullptr; 339 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTENDED_DYNAMIC_STATE_FEATURES_EXT,
320 dynamic_state.extendedDynamicState = VK_TRUE; 340 .pNext = nullptr,
341 .extendedDynamicState = VK_TRUE,
342 };
321 SetNext(next, dynamic_state); 343 SetNext(next, dynamic_state);
322 } else { 344 } else {
323 LOG_INFO(Render_Vulkan, "Device doesn't support extended dynamic state"); 345 LOG_INFO(Render_Vulkan, "Device doesn't support extended dynamic state");
@@ -331,11 +353,13 @@ bool VKDevice::Create() {
331 if (nv_device_diagnostics_config) { 353 if (nv_device_diagnostics_config) {
332 nsight_aftermath_tracker.Initialize(); 354 nsight_aftermath_tracker.Initialize();
333 355
334 diagnostics_nv.sType = VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV; 356 diagnostics_nv = {
335 diagnostics_nv.pNext = &features2; 357 .sType = VK_STRUCTURE_TYPE_DEVICE_DIAGNOSTICS_CONFIG_CREATE_INFO_NV,
336 diagnostics_nv.flags = VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV | 358 .pNext = &features2,
337 VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV | 359 .flags = VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV |
338 VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV; 360 VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_RESOURCE_TRACKING_BIT_NV |
361 VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_AUTOMATIC_CHECKPOINTS_BIT_NV,
362 };
339 first_next = &diagnostics_nv; 363 first_next = &diagnostics_nv;
340 } 364 }
341 365
@@ -704,13 +728,15 @@ void VKDevice::SetupFeatures() {
704} 728}
705 729
706void VKDevice::CollectTelemetryParameters() { 730void VKDevice::CollectTelemetryParameters() {
707 VkPhysicalDeviceDriverPropertiesKHR driver; 731 VkPhysicalDeviceDriverPropertiesKHR driver{
708 driver.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR; 732 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR,
709 driver.pNext = nullptr; 733 .pNext = nullptr,
734 };
710 735
711 VkPhysicalDeviceProperties2KHR properties; 736 VkPhysicalDeviceProperties2KHR properties{
712 properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; 737 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR,
713 properties.pNext = &driver; 738 .pNext = &driver,
739 };
714 physical.GetProperties2KHR(properties); 740 physical.GetProperties2KHR(properties);
715 741
716 driver_id = driver.driverID; 742 driver_id = driver.driverID;
@@ -719,24 +745,26 @@ void VKDevice::CollectTelemetryParameters() {
719 const std::vector extensions = physical.EnumerateDeviceExtensionProperties(); 745 const std::vector extensions = physical.EnumerateDeviceExtensionProperties();
720 reported_extensions.reserve(std::size(extensions)); 746 reported_extensions.reserve(std::size(extensions));
721 for (const auto& extension : extensions) { 747 for (const auto& extension : extensions) {
722 reported_extensions.push_back(extension.extensionName); 748 reported_extensions.emplace_back(extension.extensionName);
723 } 749 }
724} 750}
725 751
726std::vector<VkDeviceQueueCreateInfo> VKDevice::GetDeviceQueueCreateInfos() const { 752std::vector<VkDeviceQueueCreateInfo> VKDevice::GetDeviceQueueCreateInfos() const {
727 static constexpr float QUEUE_PRIORITY = 1.0f; 753 static constexpr float QUEUE_PRIORITY = 1.0f;
728 754
729 std::unordered_set<u32> unique_queue_families = {graphics_family, present_family}; 755 std::unordered_set<u32> unique_queue_families{graphics_family, present_family};
730 std::vector<VkDeviceQueueCreateInfo> queue_cis; 756 std::vector<VkDeviceQueueCreateInfo> queue_cis;
757 queue_cis.reserve(unique_queue_families.size());
731 758
732 for (const u32 queue_family : unique_queue_families) { 759 for (const u32 queue_family : unique_queue_families) {
733 VkDeviceQueueCreateInfo& ci = queue_cis.emplace_back(); 760 queue_cis.push_back({
734 ci.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; 761 .sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
735 ci.pNext = nullptr; 762 .pNext = nullptr,
736 ci.flags = 0; 763 .flags = 0,
737 ci.queueFamilyIndex = queue_family; 764 .queueFamilyIndex = queue_family,
738 ci.queueCount = 1; 765 .queueCount = 1,
739 ci.pQueuePriorities = &QUEUE_PRIORITY; 766 .pQueuePriorities = &QUEUE_PRIORITY,
767 });
740 } 768 }
741 769
742 return queue_cis; 770 return queue_cis;
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 844445105..aaf930b90 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -28,15 +28,15 @@ namespace {
28 28
29template <class StencilFace> 29template <class StencilFace>
30VkStencilOpState GetStencilFaceState(const StencilFace& face) { 30VkStencilOpState GetStencilFaceState(const StencilFace& face) {
31 VkStencilOpState state; 31 return {
32 state.failOp = MaxwellToVK::StencilOp(face.ActionStencilFail()); 32 .failOp = MaxwellToVK::StencilOp(face.ActionStencilFail()),
33 state.passOp = MaxwellToVK::StencilOp(face.ActionDepthPass()); 33 .passOp = MaxwellToVK::StencilOp(face.ActionDepthPass()),
34 state.depthFailOp = MaxwellToVK::StencilOp(face.ActionDepthFail()); 34 .depthFailOp = MaxwellToVK::StencilOp(face.ActionDepthFail()),
35 state.compareOp = MaxwellToVK::ComparisonOp(face.TestFunc()); 35 .compareOp = MaxwellToVK::ComparisonOp(face.TestFunc()),
36 state.compareMask = 0; 36 .compareMask = 0,
37 state.writeMask = 0; 37 .writeMask = 0,
38 state.reference = 0; 38 .reference = 0,
39 return state; 39 };
40} 40}
41 41
42bool SupportsPrimitiveRestart(VkPrimitiveTopology topology) { 42bool SupportsPrimitiveRestart(VkPrimitiveTopology topology) {
@@ -52,20 +52,21 @@ bool SupportsPrimitiveRestart(VkPrimitiveTopology topology) {
52} 52}
53 53
54VkViewportSwizzleNV UnpackViewportSwizzle(u16 swizzle) { 54VkViewportSwizzleNV UnpackViewportSwizzle(u16 swizzle) {
55 union { 55 union Swizzle {
56 u32 raw; 56 u32 raw;
57 BitField<0, 3, Maxwell::ViewportSwizzle> x; 57 BitField<0, 3, Maxwell::ViewportSwizzle> x;
58 BitField<4, 3, Maxwell::ViewportSwizzle> y; 58 BitField<4, 3, Maxwell::ViewportSwizzle> y;
59 BitField<8, 3, Maxwell::ViewportSwizzle> z; 59 BitField<8, 3, Maxwell::ViewportSwizzle> z;
60 BitField<12, 3, Maxwell::ViewportSwizzle> w; 60 BitField<12, 3, Maxwell::ViewportSwizzle> w;
61 } const unpacked{swizzle}; 61 };
62 62 const Swizzle unpacked{swizzle};
63 VkViewportSwizzleNV result; 63
64 result.x = MaxwellToVK::ViewportSwizzle(unpacked.x); 64 return {
65 result.y = MaxwellToVK::ViewportSwizzle(unpacked.y); 65 .x = MaxwellToVK::ViewportSwizzle(unpacked.x),
66 result.z = MaxwellToVK::ViewportSwizzle(unpacked.z); 66 .y = MaxwellToVK::ViewportSwizzle(unpacked.y),
67 result.w = MaxwellToVK::ViewportSwizzle(unpacked.w); 67 .z = MaxwellToVK::ViewportSwizzle(unpacked.z),
68 return result; 68 .w = MaxwellToVK::ViewportSwizzle(unpacked.w),
69 };
69} 70}
70 71
71} // Anonymous namespace 72} // Anonymous namespace
@@ -100,24 +101,26 @@ VkDescriptorSet VKGraphicsPipeline::CommitDescriptorSet() {
100 101
101vk::DescriptorSetLayout VKGraphicsPipeline::CreateDescriptorSetLayout( 102vk::DescriptorSetLayout VKGraphicsPipeline::CreateDescriptorSetLayout(
102 vk::Span<VkDescriptorSetLayoutBinding> bindings) const { 103 vk::Span<VkDescriptorSetLayoutBinding> bindings) const {
103 VkDescriptorSetLayoutCreateInfo ci; 104 const VkDescriptorSetLayoutCreateInfo ci{
104 ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; 105 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
105 ci.pNext = nullptr; 106 .pNext = nullptr,
106 ci.flags = 0; 107 .flags = 0,
107 ci.bindingCount = bindings.size(); 108 .bindingCount = bindings.size(),
108 ci.pBindings = bindings.data(); 109 .pBindings = bindings.data(),
110 };
109 return device.GetLogical().CreateDescriptorSetLayout(ci); 111 return device.GetLogical().CreateDescriptorSetLayout(ci);
110} 112}
111 113
112vk::PipelineLayout VKGraphicsPipeline::CreatePipelineLayout() const { 114vk::PipelineLayout VKGraphicsPipeline::CreatePipelineLayout() const {
113 VkPipelineLayoutCreateInfo ci; 115 const VkPipelineLayoutCreateInfo ci{
114 ci.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; 116 .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
115 ci.pNext = nullptr; 117 .pNext = nullptr,
116 ci.flags = 0; 118 .flags = 0,
117 ci.setLayoutCount = 1; 119 .setLayoutCount = 1,
118 ci.pSetLayouts = descriptor_set_layout.address(); 120 .pSetLayouts = descriptor_set_layout.address(),
119 ci.pushConstantRangeCount = 0; 121 .pushConstantRangeCount = 0,
120 ci.pPushConstantRanges = nullptr; 122 .pPushConstantRanges = nullptr,
123 };
121 return device.GetLogical().CreatePipelineLayout(ci); 124 return device.GetLogical().CreatePipelineLayout(ci);
122} 125}
123 126
@@ -136,26 +139,28 @@ vk::DescriptorUpdateTemplateKHR VKGraphicsPipeline::CreateDescriptorUpdateTempla
136 return {}; 139 return {};
137 } 140 }
138 141
139 VkDescriptorUpdateTemplateCreateInfoKHR ci; 142 const VkDescriptorUpdateTemplateCreateInfoKHR ci{
140 ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR; 143 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
141 ci.pNext = nullptr; 144 .pNext = nullptr,
142 ci.flags = 0; 145 .flags = 0,
143 ci.descriptorUpdateEntryCount = static_cast<u32>(template_entries.size()); 146 .descriptorUpdateEntryCount = static_cast<u32>(template_entries.size()),
144 ci.pDescriptorUpdateEntries = template_entries.data(); 147 .pDescriptorUpdateEntries = template_entries.data(),
145 ci.templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR; 148 .templateType = VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
146 ci.descriptorSetLayout = *descriptor_set_layout; 149 .descriptorSetLayout = *descriptor_set_layout,
147 ci.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS; 150 .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
148 ci.pipelineLayout = *layout; 151 .pipelineLayout = *layout,
149 ci.set = DESCRIPTOR_SET; 152 .set = DESCRIPTOR_SET,
153 };
150 return device.GetLogical().CreateDescriptorUpdateTemplateKHR(ci); 154 return device.GetLogical().CreateDescriptorUpdateTemplateKHR(ci);
151} 155}
152 156
153std::vector<vk::ShaderModule> VKGraphicsPipeline::CreateShaderModules( 157std::vector<vk::ShaderModule> VKGraphicsPipeline::CreateShaderModules(
154 const SPIRVProgram& program) const { 158 const SPIRVProgram& program) const {
155 VkShaderModuleCreateInfo ci; 159 VkShaderModuleCreateInfo ci{
156 ci.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; 160 .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
157 ci.pNext = nullptr; 161 .pNext = nullptr,
158 ci.flags = 0; 162 .flags = 0,
163 };
159 164
160 std::vector<vk::ShaderModule> modules; 165 std::vector<vk::ShaderModule> modules;
161 modules.reserve(Maxwell::MaxShaderStage); 166 modules.reserve(Maxwell::MaxShaderStage);
@@ -204,15 +209,17 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
204 const bool instanced = state.binding_divisors[index] != 0; 209 const bool instanced = state.binding_divisors[index] != 0;
205 const auto rate = instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX; 210 const auto rate = instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX;
206 211
207 auto& vertex_binding = vertex_bindings.emplace_back(); 212 vertex_bindings.push_back({
208 vertex_binding.binding = static_cast<u32>(index); 213 .binding = static_cast<u32>(index),
209 vertex_binding.stride = binding.stride; 214 .stride = binding.stride,
210 vertex_binding.inputRate = rate; 215 .inputRate = rate,
216 });
211 217
212 if (instanced) { 218 if (instanced) {
213 auto& binding_divisor = vertex_binding_divisors.emplace_back(); 219 vertex_binding_divisors.push_back({
214 binding_divisor.binding = static_cast<u32>(index); 220 .binding = static_cast<u32>(index),
215 binding_divisor.divisor = state.binding_divisors[index]; 221 .divisor = state.binding_divisors[index],
222 });
216 } 223 }
217 } 224 }
218 225
@@ -227,116 +234,132 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
227 // Skip attributes not used by the vertex shaders. 234 // Skip attributes not used by the vertex shaders.
228 continue; 235 continue;
229 } 236 }
230 auto& vertex_attribute = vertex_attributes.emplace_back(); 237 vertex_attributes.push_back({
231 vertex_attribute.location = static_cast<u32>(index); 238 .location = static_cast<u32>(index),
232 vertex_attribute.binding = attribute.buffer; 239 .binding = attribute.buffer,
233 vertex_attribute.format = MaxwellToVK::VertexFormat(attribute.Type(), attribute.Size()); 240 .format = MaxwellToVK::VertexFormat(attribute.Type(), attribute.Size()),
234 vertex_attribute.offset = attribute.offset; 241 .offset = attribute.offset,
242 });
235 } 243 }
236 244
237 VkPipelineVertexInputStateCreateInfo vertex_input_ci; 245 VkPipelineVertexInputStateCreateInfo vertex_input_ci{
238 vertex_input_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; 246 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
239 vertex_input_ci.pNext = nullptr; 247 .pNext = nullptr,
240 vertex_input_ci.flags = 0; 248 .flags = 0,
241 vertex_input_ci.vertexBindingDescriptionCount = static_cast<u32>(vertex_bindings.size()); 249 .vertexBindingDescriptionCount = static_cast<u32>(vertex_bindings.size()),
242 vertex_input_ci.pVertexBindingDescriptions = vertex_bindings.data(); 250 .pVertexBindingDescriptions = vertex_bindings.data(),
243 vertex_input_ci.vertexAttributeDescriptionCount = static_cast<u32>(vertex_attributes.size()); 251 .vertexAttributeDescriptionCount = static_cast<u32>(vertex_attributes.size()),
244 vertex_input_ci.pVertexAttributeDescriptions = vertex_attributes.data(); 252 .pVertexAttributeDescriptions = vertex_attributes.data(),
245 253 };
246 VkPipelineVertexInputDivisorStateCreateInfoEXT input_divisor_ci; 254
247 input_divisor_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT; 255 const VkPipelineVertexInputDivisorStateCreateInfoEXT input_divisor_ci{
248 input_divisor_ci.pNext = nullptr; 256 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT,
249 input_divisor_ci.vertexBindingDivisorCount = static_cast<u32>(vertex_binding_divisors.size()); 257 .pNext = nullptr,
250 input_divisor_ci.pVertexBindingDivisors = vertex_binding_divisors.data(); 258 .vertexBindingDivisorCount = static_cast<u32>(vertex_binding_divisors.size()),
259 .pVertexBindingDivisors = vertex_binding_divisors.data(),
260 };
251 if (!vertex_binding_divisors.empty()) { 261 if (!vertex_binding_divisors.empty()) {
252 vertex_input_ci.pNext = &input_divisor_ci; 262 vertex_input_ci.pNext = &input_divisor_ci;
253 } 263 }
254 264
255 VkPipelineInputAssemblyStateCreateInfo input_assembly_ci; 265 const auto input_assembly_topology = MaxwellToVK::PrimitiveTopology(device, dynamic.Topology());
256 input_assembly_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; 266 const VkPipelineInputAssemblyStateCreateInfo input_assembly_ci{
257 input_assembly_ci.pNext = nullptr; 267 .sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
258 input_assembly_ci.flags = 0; 268 .pNext = nullptr,
259 input_assembly_ci.topology = MaxwellToVK::PrimitiveTopology(device, dynamic.Topology()); 269 .flags = 0,
260 input_assembly_ci.primitiveRestartEnable = 270 .topology = MaxwellToVK::PrimitiveTopology(device, dynamic.Topology()),
261 state.primitive_restart_enable != 0 && SupportsPrimitiveRestart(input_assembly_ci.topology); 271 .primitiveRestartEnable = state.primitive_restart_enable != 0 &&
262 272 SupportsPrimitiveRestart(input_assembly_topology),
263 VkPipelineTessellationStateCreateInfo tessellation_ci; 273 };
264 tessellation_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; 274
265 tessellation_ci.pNext = nullptr; 275 const VkPipelineTessellationStateCreateInfo tessellation_ci{
266 tessellation_ci.flags = 0; 276 .sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
267 tessellation_ci.patchControlPoints = state.patch_control_points_minus_one.Value() + 1; 277 .pNext = nullptr,
268 278 .flags = 0,
269 VkPipelineViewportStateCreateInfo viewport_ci; 279 .patchControlPoints = state.patch_control_points_minus_one.Value() + 1,
270 viewport_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; 280 };
271 viewport_ci.pNext = nullptr; 281
272 viewport_ci.flags = 0; 282 VkPipelineViewportStateCreateInfo viewport_ci{
273 viewport_ci.viewportCount = Maxwell::NumViewports; 283 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
274 viewport_ci.pViewports = nullptr; 284 .pNext = nullptr,
275 viewport_ci.scissorCount = Maxwell::NumViewports; 285 .flags = 0,
276 viewport_ci.pScissors = nullptr; 286 .viewportCount = Maxwell::NumViewports,
287 .pViewports = nullptr,
288 .scissorCount = Maxwell::NumViewports,
289 .pScissors = nullptr,
290 };
277 291
278 std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles; 292 std::array<VkViewportSwizzleNV, Maxwell::NumViewports> swizzles;
279 std::transform(viewport_swizzles.begin(), viewport_swizzles.end(), swizzles.begin(), 293 std::transform(viewport_swizzles.begin(), viewport_swizzles.end(), swizzles.begin(),
280 UnpackViewportSwizzle); 294 UnpackViewportSwizzle);
281 VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci; 295 VkPipelineViewportSwizzleStateCreateInfoNV swizzle_ci{
282 swizzle_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV; 296 .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV,
283 swizzle_ci.pNext = nullptr; 297 .pNext = nullptr,
284 swizzle_ci.flags = 0; 298 .flags = 0,
285 swizzle_ci.viewportCount = Maxwell::NumViewports; 299 .viewportCount = Maxwell::NumViewports,
286 swizzle_ci.pViewportSwizzles = swizzles.data(); 300 .pViewportSwizzles = swizzles.data(),
301 };
287 if (device.IsNvViewportSwizzleSupported()) { 302 if (device.IsNvViewportSwizzleSupported()) {
288 viewport_ci.pNext = &swizzle_ci; 303 viewport_ci.pNext = &swizzle_ci;
289 } 304 }
290 305
291 VkPipelineRasterizationStateCreateInfo rasterization_ci; 306 const VkPipelineRasterizationStateCreateInfo rasterization_ci{
292 rasterization_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; 307 .sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
293 rasterization_ci.pNext = nullptr; 308 .pNext = nullptr,
294 rasterization_ci.flags = 0; 309 .flags = 0,
295 rasterization_ci.depthClampEnable = state.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE; 310 .depthClampEnable =
296 rasterization_ci.rasterizerDiscardEnable = state.rasterize_enable == 0 ? VK_TRUE : VK_FALSE; 311 static_cast<VkBool32>(state.depth_clamp_disabled == 0 ? VK_TRUE : VK_FALSE),
297 rasterization_ci.polygonMode = VK_POLYGON_MODE_FILL; 312 .rasterizerDiscardEnable =
298 rasterization_ci.cullMode = 313 static_cast<VkBool32>(state.rasterize_enable == 0 ? VK_TRUE : VK_FALSE),
299 dynamic.cull_enable ? MaxwellToVK::CullFace(dynamic.CullFace()) : VK_CULL_MODE_NONE; 314 .polygonMode = VK_POLYGON_MODE_FILL,
300 rasterization_ci.frontFace = MaxwellToVK::FrontFace(dynamic.FrontFace()); 315 .cullMode =
301 rasterization_ci.depthBiasEnable = state.depth_bias_enable; 316 dynamic.cull_enable ? MaxwellToVK::CullFace(dynamic.CullFace()) : VK_CULL_MODE_NONE,
302 rasterization_ci.depthBiasConstantFactor = 0.0f; 317 .frontFace = MaxwellToVK::FrontFace(dynamic.FrontFace()),
303 rasterization_ci.depthBiasClamp = 0.0f; 318 .depthBiasEnable = state.depth_bias_enable,
304 rasterization_ci.depthBiasSlopeFactor = 0.0f; 319 .depthBiasConstantFactor = 0.0f,
305 rasterization_ci.lineWidth = 1.0f; 320 .depthBiasClamp = 0.0f,
306 321 .depthBiasSlopeFactor = 0.0f,
307 VkPipelineMultisampleStateCreateInfo multisample_ci; 322 .lineWidth = 1.0f,
308 multisample_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; 323 };
309 multisample_ci.pNext = nullptr; 324
310 multisample_ci.flags = 0; 325 const VkPipelineMultisampleStateCreateInfo multisample_ci{
311 multisample_ci.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT; 326 .sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
312 multisample_ci.sampleShadingEnable = VK_FALSE; 327 .pNext = nullptr,
313 multisample_ci.minSampleShading = 0.0f; 328 .flags = 0,
314 multisample_ci.pSampleMask = nullptr; 329 .rasterizationSamples = VK_SAMPLE_COUNT_1_BIT,
315 multisample_ci.alphaToCoverageEnable = VK_FALSE; 330 .sampleShadingEnable = VK_FALSE,
316 multisample_ci.alphaToOneEnable = VK_FALSE; 331 .minSampleShading = 0.0f,
317 332 .pSampleMask = nullptr,
318 VkPipelineDepthStencilStateCreateInfo depth_stencil_ci; 333 .alphaToCoverageEnable = VK_FALSE,
319 depth_stencil_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; 334 .alphaToOneEnable = VK_FALSE,
320 depth_stencil_ci.pNext = nullptr; 335 };
321 depth_stencil_ci.flags = 0; 336
322 depth_stencil_ci.depthTestEnable = dynamic.depth_test_enable; 337 const VkPipelineDepthStencilStateCreateInfo depth_stencil_ci{
323 depth_stencil_ci.depthWriteEnable = dynamic.depth_write_enable; 338 .sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
324 depth_stencil_ci.depthCompareOp = dynamic.depth_test_enable 339 .pNext = nullptr,
325 ? MaxwellToVK::ComparisonOp(dynamic.DepthTestFunc()) 340 .flags = 0,
326 : VK_COMPARE_OP_ALWAYS; 341 .depthTestEnable = dynamic.depth_test_enable,
327 depth_stencil_ci.depthBoundsTestEnable = dynamic.depth_bounds_enable; 342 .depthWriteEnable = dynamic.depth_write_enable,
328 depth_stencil_ci.stencilTestEnable = dynamic.stencil_enable; 343 .depthCompareOp = dynamic.depth_test_enable
329 depth_stencil_ci.front = GetStencilFaceState(dynamic.front); 344 ? MaxwellToVK::ComparisonOp(dynamic.DepthTestFunc())
330 depth_stencil_ci.back = GetStencilFaceState(dynamic.back); 345 : VK_COMPARE_OP_ALWAYS,
331 depth_stencil_ci.minDepthBounds = 0.0f; 346 .depthBoundsTestEnable = dynamic.depth_bounds_enable,
332 depth_stencil_ci.maxDepthBounds = 0.0f; 347 .stencilTestEnable = dynamic.stencil_enable,
348 .front = GetStencilFaceState(dynamic.front),
349 .back = GetStencilFaceState(dynamic.back),
350 .minDepthBounds = 0.0f,
351 .maxDepthBounds = 0.0f,
352 };
333 353
334 std::array<VkPipelineColorBlendAttachmentState, Maxwell::NumRenderTargets> cb_attachments; 354 std::array<VkPipelineColorBlendAttachmentState, Maxwell::NumRenderTargets> cb_attachments;
335 const auto num_attachments = static_cast<std::size_t>(renderpass_params.num_color_attachments); 355 const auto num_attachments = static_cast<std::size_t>(renderpass_params.num_color_attachments);
336 for (std::size_t index = 0; index < num_attachments; ++index) { 356 for (std::size_t index = 0; index < num_attachments; ++index) {
337 static constexpr std::array COMPONENT_TABLE = { 357 static constexpr std::array COMPONENT_TABLE{
338 VK_COLOR_COMPONENT_R_BIT, VK_COLOR_COMPONENT_G_BIT, VK_COLOR_COMPONENT_B_BIT, 358 VK_COLOR_COMPONENT_R_BIT,
339 VK_COLOR_COMPONENT_A_BIT}; 359 VK_COLOR_COMPONENT_G_BIT,
360 VK_COLOR_COMPONENT_B_BIT,
361 VK_COLOR_COMPONENT_A_BIT,
362 };
340 const auto& blend = state.attachments[index]; 363 const auto& blend = state.attachments[index];
341 364
342 VkColorComponentFlags color_components = 0; 365 VkColorComponentFlags color_components = 0;
@@ -346,35 +369,36 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
346 } 369 }
347 } 370 }
348 371
349 VkPipelineColorBlendAttachmentState& attachment = cb_attachments[index]; 372 cb_attachments[index] = {
350 attachment.blendEnable = blend.enable != 0; 373 .blendEnable = blend.enable != 0,
351 attachment.srcColorBlendFactor = MaxwellToVK::BlendFactor(blend.SourceRGBFactor()); 374 .srcColorBlendFactor = MaxwellToVK::BlendFactor(blend.SourceRGBFactor()),
352 attachment.dstColorBlendFactor = MaxwellToVK::BlendFactor(blend.DestRGBFactor()); 375 .dstColorBlendFactor = MaxwellToVK::BlendFactor(blend.DestRGBFactor()),
353 attachment.colorBlendOp = MaxwellToVK::BlendEquation(blend.EquationRGB()); 376 .colorBlendOp = MaxwellToVK::BlendEquation(blend.EquationRGB()),
354 attachment.srcAlphaBlendFactor = MaxwellToVK::BlendFactor(blend.SourceAlphaFactor()); 377 .srcAlphaBlendFactor = MaxwellToVK::BlendFactor(blend.SourceAlphaFactor()),
355 attachment.dstAlphaBlendFactor = MaxwellToVK::BlendFactor(blend.DestAlphaFactor()); 378 .dstAlphaBlendFactor = MaxwellToVK::BlendFactor(blend.DestAlphaFactor()),
356 attachment.alphaBlendOp = MaxwellToVK::BlendEquation(blend.EquationAlpha()); 379 .alphaBlendOp = MaxwellToVK::BlendEquation(blend.EquationAlpha()),
357 attachment.colorWriteMask = color_components; 380 .colorWriteMask = color_components,
381 };
358 } 382 }
359 383
360 VkPipelineColorBlendStateCreateInfo color_blend_ci; 384 const VkPipelineColorBlendStateCreateInfo color_blend_ci{
361 color_blend_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO; 385 .sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
362 color_blend_ci.pNext = nullptr; 386 .pNext = nullptr,
363 color_blend_ci.flags = 0; 387 .flags = 0,
364 color_blend_ci.logicOpEnable = VK_FALSE; 388 .logicOpEnable = VK_FALSE,
365 color_blend_ci.logicOp = VK_LOGIC_OP_COPY; 389 .logicOp = VK_LOGIC_OP_COPY,
366 color_blend_ci.attachmentCount = static_cast<u32>(num_attachments); 390 .attachmentCount = static_cast<u32>(num_attachments),
367 color_blend_ci.pAttachments = cb_attachments.data(); 391 .pAttachments = cb_attachments.data(),
368 std::memset(color_blend_ci.blendConstants, 0, sizeof(color_blend_ci.blendConstants)); 392 };
369 393
370 std::vector dynamic_states = { 394 std::vector dynamic_states{
371 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR, 395 VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR,
372 VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS, 396 VK_DYNAMIC_STATE_DEPTH_BIAS, VK_DYNAMIC_STATE_BLEND_CONSTANTS,
373 VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK, 397 VK_DYNAMIC_STATE_DEPTH_BOUNDS, VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
374 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE, 398 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK, VK_DYNAMIC_STATE_STENCIL_REFERENCE,
375 }; 399 };
376 if (device.IsExtExtendedDynamicStateSupported()) { 400 if (device.IsExtExtendedDynamicStateSupported()) {
377 static constexpr std::array extended = { 401 static constexpr std::array extended{
378 VK_DYNAMIC_STATE_CULL_MODE_EXT, 402 VK_DYNAMIC_STATE_CULL_MODE_EXT,
379 VK_DYNAMIC_STATE_FRONT_FACE_EXT, 403 VK_DYNAMIC_STATE_FRONT_FACE_EXT,
380 VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT, 404 VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
@@ -389,18 +413,19 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
389 dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end()); 413 dynamic_states.insert(dynamic_states.end(), extended.begin(), extended.end());
390 } 414 }
391 415
392 VkPipelineDynamicStateCreateInfo dynamic_state_ci; 416 const VkPipelineDynamicStateCreateInfo dynamic_state_ci{
393 dynamic_state_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO; 417 .sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
394 dynamic_state_ci.pNext = nullptr; 418 .pNext = nullptr,
395 dynamic_state_ci.flags = 0; 419 .flags = 0,
396 dynamic_state_ci.dynamicStateCount = static_cast<u32>(dynamic_states.size()); 420 .dynamicStateCount = static_cast<u32>(dynamic_states.size()),
397 dynamic_state_ci.pDynamicStates = dynamic_states.data(); 421 .pDynamicStates = dynamic_states.data(),
422 };
398 423
399 VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_ci; 424 const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_ci{
400 subgroup_size_ci.sType = 425 .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT,
401 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT; 426 .pNext = nullptr,
402 subgroup_size_ci.pNext = nullptr; 427 .requiredSubgroupSize = GuestWarpSize,
403 subgroup_size_ci.requiredSubgroupSize = GuestWarpSize; 428 };
404 429
405 std::vector<VkPipelineShaderStageCreateInfo> shader_stages; 430 std::vector<VkPipelineShaderStageCreateInfo> shader_stages;
406 std::size_t module_index = 0; 431 std::size_t module_index = 0;
@@ -408,6 +433,7 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
408 if (!program[stage]) { 433 if (!program[stage]) {
409 continue; 434 continue;
410 } 435 }
436
411 VkPipelineShaderStageCreateInfo& stage_ci = shader_stages.emplace_back(); 437 VkPipelineShaderStageCreateInfo& stage_ci = shader_stages.emplace_back();
412 stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; 438 stage_ci.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
413 stage_ci.pNext = nullptr; 439 stage_ci.pNext = nullptr;
@@ -422,26 +448,27 @@ vk::Pipeline VKGraphicsPipeline::CreatePipeline(const RenderPassParams& renderpa
422 } 448 }
423 } 449 }
424 450
425 VkGraphicsPipelineCreateInfo ci; 451 const VkGraphicsPipelineCreateInfo ci{
426 ci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; 452 .sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
427 ci.pNext = nullptr; 453 .pNext = nullptr,
428 ci.flags = 0; 454 .flags = 0,
429 ci.stageCount = static_cast<u32>(shader_stages.size()); 455 .stageCount = static_cast<u32>(shader_stages.size()),
430 ci.pStages = shader_stages.data(); 456 .pStages = shader_stages.data(),
431 ci.pVertexInputState = &vertex_input_ci; 457 .pVertexInputState = &vertex_input_ci,
432 ci.pInputAssemblyState = &input_assembly_ci; 458 .pInputAssemblyState = &input_assembly_ci,
433 ci.pTessellationState = &tessellation_ci; 459 .pTessellationState = &tessellation_ci,
434 ci.pViewportState = &viewport_ci; 460 .pViewportState = &viewport_ci,
435 ci.pRasterizationState = &rasterization_ci; 461 .pRasterizationState = &rasterization_ci,
436 ci.pMultisampleState = &multisample_ci; 462 .pMultisampleState = &multisample_ci,
437 ci.pDepthStencilState = &depth_stencil_ci; 463 .pDepthStencilState = &depth_stencil_ci,
438 ci.pColorBlendState = &color_blend_ci; 464 .pColorBlendState = &color_blend_ci,
439 ci.pDynamicState = &dynamic_state_ci; 465 .pDynamicState = &dynamic_state_ci,
440 ci.layout = *layout; 466 .layout = *layout,
441 ci.renderPass = renderpass; 467 .renderPass = renderpass,
442 ci.subpass = 0; 468 .subpass = 0,
443 ci.basePipelineHandle = nullptr; 469 .basePipelineHandle = nullptr,
444 ci.basePipelineIndex = 0; 470 .basePipelineIndex = 0,
471 };
445 return device.GetLogical().CreateGraphicsPipeline(ci); 472 return device.GetLogical().CreateGraphicsPipeline(ci);
446} 473}
447 474
diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
index 430031665..bd93dcf20 100644
--- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp
@@ -281,12 +281,10 @@ void CachedSurface::UploadBuffer(const std::vector<u8>& staging_buffer) {
281 VkBufferMemoryBarrier barrier; 281 VkBufferMemoryBarrier barrier;
282 barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER; 282 barrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
283 barrier.pNext = nullptr; 283 barrier.pNext = nullptr;
284 barrier.srcAccessMask = VK_PIPELINE_STAGE_TRANSFER_BIT; 284 barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
285 barrier.dstAccessMask = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT; 285 barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
286 barrier.srcQueueFamilyIndex = VK_ACCESS_TRANSFER_WRITE_BIT; 286 barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // They'll be ignored anyway
287 barrier.dstQueueFamilyIndex = VK_ACCESS_SHADER_READ_BIT; 287 barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
288 barrier.srcQueueFamilyIndex = 0;
289 barrier.dstQueueFamilyIndex = 0;
290 barrier.buffer = dst_buffer; 288 barrier.buffer = dst_buffer;
291 barrier.offset = 0; 289 barrier.offset = 0;
292 barrier.size = size; 290 barrier.size = size;
diff --git a/src/video_core/shader_cache.h b/src/video_core/shader_cache.h
index b7608fc7b..015a789d6 100644
--- a/src/video_core/shader_cache.h
+++ b/src/video_core/shader_cache.h
@@ -209,11 +209,11 @@ private:
209 } 209 }
210 210
211 // Remove them from the cache 211 // Remove them from the cache
212 const auto is_removed = [&removed_shaders](std::unique_ptr<T>& shader) { 212 const auto is_removed = [&removed_shaders](const std::unique_ptr<T>& shader) {
213 return std::find(removed_shaders.begin(), removed_shaders.end(), shader.get()) != 213 return std::find(removed_shaders.begin(), removed_shaders.end(), shader.get()) !=
214 removed_shaders.end(); 214 removed_shaders.end();
215 }; 215 };
216 storage.erase(std::remove_if(storage.begin(), storage.end(), is_removed), storage.end()); 216 std::erase_if(storage, is_removed);
217 } 217 }
218 218
219 /// @brief Creates a new entry in the lookup cache and returns its pointer 219 /// @brief Creates a new entry in the lookup cache and returns its pointer
diff --git a/src/video_core/texture_cache/surface_params.cpp b/src/video_core/texture_cache/surface_params.cpp
index 0b2b2b8c4..921562c1f 100644
--- a/src/video_core/texture_cache/surface_params.cpp
+++ b/src/video_core/texture_cache/surface_params.cpp
@@ -343,8 +343,7 @@ std::size_t SurfaceParams::GetLayerSize(bool as_host_size, bool uncompressed) co
343 size += GetInnerMipmapMemorySize(level, as_host_size, uncompressed); 343 size += GetInnerMipmapMemorySize(level, as_host_size, uncompressed);
344 } 344 }
345 if (is_tiled && is_layered) { 345 if (is_tiled && is_layered) {
346 return Common::AlignBits(size, 346 return Common::AlignBits(size, Tegra::Texture::GOB_SIZE_SHIFT + block_height + block_depth);
347 Tegra::Texture::GetGOBSizeShift() + block_height + block_depth);
348 } 347 }
349 return size; 348 return size;
350} 349}
@@ -418,7 +417,7 @@ std::tuple<u32, u32, u32> SurfaceParams::GetBlockOffsetXYZ(u32 offset) const {
418 const u32 block_size = GetBlockSize(); 417 const u32 block_size = GetBlockSize();
419 const u32 block_index = offset / block_size; 418 const u32 block_index = offset / block_size;
420 const u32 gob_offset = offset % block_size; 419 const u32 gob_offset = offset % block_size;
421 const u32 gob_index = gob_offset / static_cast<u32>(Tegra::Texture::GetGOBSize()); 420 const u32 gob_index = gob_offset / static_cast<u32>(Tegra::Texture::GOB_SIZE);
422 const u32 x_gob_pixels = 64U / GetBytesPerPixel(); 421 const u32 x_gob_pixels = 64U / GetBytesPerPixel();
423 const u32 x_block_pixels = x_gob_pixels << block_width; 422 const u32 x_block_pixels = x_gob_pixels << block_width;
424 const u32 y_block_pixels = 8U << block_height; 423 const u32 y_block_pixels = 8U << block_height;
diff --git a/src/video_core/texture_cache/surface_params.h b/src/video_core/texture_cache/surface_params.h
index 24957df8d..118aa689e 100644
--- a/src/video_core/texture_cache/surface_params.h
+++ b/src/video_core/texture_cache/surface_params.h
@@ -204,7 +204,7 @@ public:
204 static std::size_t AlignLayered(const std::size_t out_size, const u32 block_height, 204 static std::size_t AlignLayered(const std::size_t out_size, const u32 block_height,
205 const u32 block_depth) { 205 const u32 block_depth) {
206 return Common::AlignBits(out_size, 206 return Common::AlignBits(out_size,
207 Tegra::Texture::GetGOBSizeShift() + block_height + block_depth); 207 Tegra::Texture::GOB_SIZE_SHIFT + block_height + block_depth);
208 } 208 }
209 209
210 /// Converts a width from a type of surface into another. This helps represent the 210 /// Converts a width from a type of surface into another. This helps represent the
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp
index 548e4c3fe..98beabef1 100644
--- a/src/video_core/textures/decoders.cpp
+++ b/src/video_core/textures/decoders.cpp
@@ -6,6 +6,7 @@
6#include <cstring> 6#include <cstring>
7#include "common/alignment.h" 7#include "common/alignment.h"
8#include "common/assert.h" 8#include "common/assert.h"
9#include "common/bit_util.h"
9#include "video_core/gpu.h" 10#include "video_core/gpu.h"
10#include "video_core/textures/decoders.h" 11#include "video_core/textures/decoders.h"
11#include "video_core/textures/texture.h" 12#include "video_core/textures/texture.h"
@@ -37,20 +38,10 @@ struct alignas(64) SwizzleTable {
37 std::array<std::array<u16, M>, N> values{}; 38 std::array<std::array<u16, M>, N> values{};
38}; 39};
39 40
40constexpr u32 gob_size_x_shift = 6; 41constexpr u32 FAST_SWIZZLE_ALIGN = 16;
41constexpr u32 gob_size_y_shift = 3;
42constexpr u32 gob_size_z_shift = 0;
43constexpr u32 gob_size_shift = gob_size_x_shift + gob_size_y_shift + gob_size_z_shift;
44 42
45constexpr u32 gob_size_x = 1U << gob_size_x_shift; 43constexpr auto LEGACY_SWIZZLE_TABLE = SwizzleTable<GOB_SIZE_X, GOB_SIZE_X, GOB_SIZE_Z>();
46constexpr u32 gob_size_y = 1U << gob_size_y_shift; 44constexpr auto FAST_SWIZZLE_TABLE = SwizzleTable<GOB_SIZE_Y, 4, FAST_SWIZZLE_ALIGN>();
47constexpr u32 gob_size_z = 1U << gob_size_z_shift;
48constexpr u32 gob_size = 1U << gob_size_shift;
49
50constexpr u32 fast_swizzle_align = 16;
51
52constexpr auto legacy_swizzle_table = SwizzleTable<gob_size_y, gob_size_x, gob_size_z>();
53constexpr auto fast_swizzle_table = SwizzleTable<gob_size_y, 4, fast_swizzle_align>();
54 45
55/** 46/**
56 * This function manages ALL the GOBs(Group of Bytes) Inside a single block. 47 * This function manages ALL the GOBs(Group of Bytes) Inside a single block.
@@ -69,17 +60,17 @@ void PreciseProcessBlock(u8* const swizzled_data, u8* const unswizzled_data, con
69 u32 y_address = z_address; 60 u32 y_address = z_address;
70 u32 pixel_base = layer_z * z + y_start * stride_x; 61 u32 pixel_base = layer_z * z + y_start * stride_x;
71 for (u32 y = y_start; y < y_end; y++) { 62 for (u32 y = y_start; y < y_end; y++) {
72 const auto& table = legacy_swizzle_table[y % gob_size_y]; 63 const auto& table = LEGACY_SWIZZLE_TABLE[y % GOB_SIZE_Y];
73 for (u32 x = x_start; x < x_end; x++) { 64 for (u32 x = x_start; x < x_end; x++) {
74 const u32 swizzle_offset{y_address + table[x * bytes_per_pixel % gob_size_x]}; 65 const u32 swizzle_offset{y_address + table[x * bytes_per_pixel % GOB_SIZE_X]};
75 const u32 pixel_index{x * out_bytes_per_pixel + pixel_base}; 66 const u32 pixel_index{x * out_bytes_per_pixel + pixel_base};
76 data_ptrs[unswizzle] = swizzled_data + swizzle_offset; 67 data_ptrs[unswizzle] = swizzled_data + swizzle_offset;
77 data_ptrs[!unswizzle] = unswizzled_data + pixel_index; 68 data_ptrs[!unswizzle] = unswizzled_data + pixel_index;
78 std::memcpy(data_ptrs[0], data_ptrs[1], bytes_per_pixel); 69 std::memcpy(data_ptrs[0], data_ptrs[1], bytes_per_pixel);
79 } 70 }
80 pixel_base += stride_x; 71 pixel_base += stride_x;
81 if ((y + 1) % gob_size_y == 0) 72 if ((y + 1) % GOB_SIZE_Y == 0)
82 y_address += gob_size; 73 y_address += GOB_SIZE;
83 } 74 }
84 z_address += xy_block_size; 75 z_address += xy_block_size;
85 } 76 }
@@ -104,18 +95,18 @@ void FastProcessBlock(u8* const swizzled_data, u8* const unswizzled_data, const
104 u32 y_address = z_address; 95 u32 y_address = z_address;
105 u32 pixel_base = layer_z * z + y_start * stride_x; 96 u32 pixel_base = layer_z * z + y_start * stride_x;
106 for (u32 y = y_start; y < y_end; y++) { 97 for (u32 y = y_start; y < y_end; y++) {
107 const auto& table = fast_swizzle_table[y % gob_size_y]; 98 const auto& table = FAST_SWIZZLE_TABLE[y % GOB_SIZE_Y];
108 for (u32 xb = x_startb; xb < x_endb; xb += fast_swizzle_align) { 99 for (u32 xb = x_startb; xb < x_endb; xb += FAST_SWIZZLE_ALIGN) {
109 const u32 swizzle_offset{y_address + table[(xb / fast_swizzle_align) % 4]}; 100 const u32 swizzle_offset{y_address + table[(xb / FAST_SWIZZLE_ALIGN) % 4]};
110 const u32 out_x = xb * out_bytes_per_pixel / bytes_per_pixel; 101 const u32 out_x = xb * out_bytes_per_pixel / bytes_per_pixel;
111 const u32 pixel_index{out_x + pixel_base}; 102 const u32 pixel_index{out_x + pixel_base};
112 data_ptrs[unswizzle ? 1 : 0] = swizzled_data + swizzle_offset; 103 data_ptrs[unswizzle ? 1 : 0] = swizzled_data + swizzle_offset;
113 data_ptrs[unswizzle ? 0 : 1] = unswizzled_data + pixel_index; 104 data_ptrs[unswizzle ? 0 : 1] = unswizzled_data + pixel_index;
114 std::memcpy(data_ptrs[0], data_ptrs[1], fast_swizzle_align); 105 std::memcpy(data_ptrs[0], data_ptrs[1], FAST_SWIZZLE_ALIGN);
115 } 106 }
116 pixel_base += stride_x; 107 pixel_base += stride_x;
117 if ((y + 1) % gob_size_y == 0) 108 if ((y + 1) % GOB_SIZE_Y == 0)
118 y_address += gob_size; 109 y_address += GOB_SIZE;
119 } 110 }
120 z_address += xy_block_size; 111 z_address += xy_block_size;
121 } 112 }
@@ -138,9 +129,9 @@ void SwizzledData(u8* const swizzled_data, u8* const unswizzled_data, const bool
138 auto div_ceil = [](const u32 x, const u32 y) { return ((x + y - 1) / y); }; 129 auto div_ceil = [](const u32 x, const u32 y) { return ((x + y - 1) / y); };
139 const u32 stride_x = width * out_bytes_per_pixel; 130 const u32 stride_x = width * out_bytes_per_pixel;
140 const u32 layer_z = height * stride_x; 131 const u32 layer_z = height * stride_x;
141 const u32 gob_elements_x = gob_size_x / bytes_per_pixel; 132 const u32 gob_elements_x = GOB_SIZE_X / bytes_per_pixel;
142 constexpr u32 gob_elements_y = gob_size_y; 133 constexpr u32 gob_elements_y = GOB_SIZE_Y;
143 constexpr u32 gob_elements_z = gob_size_z; 134 constexpr u32 gob_elements_z = GOB_SIZE_Z;
144 const u32 block_x_elements = gob_elements_x; 135 const u32 block_x_elements = gob_elements_x;
145 const u32 block_y_elements = gob_elements_y * block_height; 136 const u32 block_y_elements = gob_elements_y * block_height;
146 const u32 block_z_elements = gob_elements_z * block_depth; 137 const u32 block_z_elements = gob_elements_z * block_depth;
@@ -148,7 +139,7 @@ void SwizzledData(u8* const swizzled_data, u8* const unswizzled_data, const bool
148 const u32 blocks_on_x = div_ceil(aligned_width, block_x_elements); 139 const u32 blocks_on_x = div_ceil(aligned_width, block_x_elements);
149 const u32 blocks_on_y = div_ceil(height, block_y_elements); 140 const u32 blocks_on_y = div_ceil(height, block_y_elements);
150 const u32 blocks_on_z = div_ceil(depth, block_z_elements); 141 const u32 blocks_on_z = div_ceil(depth, block_z_elements);
151 const u32 xy_block_size = gob_size * block_height; 142 const u32 xy_block_size = GOB_SIZE * block_height;
152 const u32 block_size = xy_block_size * block_depth; 143 const u32 block_size = xy_block_size * block_depth;
153 u32 tile_offset = 0; 144 u32 tile_offset = 0;
154 for (u32 zb = 0; zb < blocks_on_z; zb++) { 145 for (u32 zb = 0; zb < blocks_on_z; zb++) {
@@ -182,7 +173,7 @@ void CopySwizzledData(u32 width, u32 height, u32 depth, u32 bytes_per_pixel,
182 bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing) { 173 bool unswizzle, u32 block_height, u32 block_depth, u32 width_spacing) {
183 const u32 block_height_size{1U << block_height}; 174 const u32 block_height_size{1U << block_height};
184 const u32 block_depth_size{1U << block_depth}; 175 const u32 block_depth_size{1U << block_depth};
185 if (bytes_per_pixel % 3 != 0 && (width * bytes_per_pixel) % fast_swizzle_align == 0) { 176 if (bytes_per_pixel % 3 != 0 && (width * bytes_per_pixel) % FAST_SWIZZLE_ALIGN == 0) {
186 SwizzledData<true>(swizzled_data, unswizzled_data, unswizzle, width, height, depth, 177 SwizzledData<true>(swizzled_data, unswizzled_data, unswizzle, width, height, depth,
187 bytes_per_pixel, out_bytes_per_pixel, block_height_size, 178 bytes_per_pixel, out_bytes_per_pixel, block_height_size,
188 block_depth_size, width_spacing); 179 block_depth_size, width_spacing);
@@ -259,25 +250,26 @@ std::vector<u8> UnswizzleTexture(u8* address, u32 tile_size_x, u32 tile_size_y,
259} 250}
260 251
261void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, 252void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width,
262 u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, 253 u32 bytes_per_pixel, u8* swizzled_data, const u8* unswizzled_data,
263 u32 block_height_bit, u32 offset_x, u32 offset_y) { 254 u32 block_height_bit, u32 offset_x, u32 offset_y) {
264 const u32 block_height = 1U << block_height_bit; 255 const u32 block_height = 1U << block_height_bit;
265 const u32 image_width_in_gobs{(swizzled_width * bytes_per_pixel + (gob_size_x - 1)) / 256 const u32 image_width_in_gobs =
266 gob_size_x}; 257 (swizzled_width * bytes_per_pixel + (GOB_SIZE_X - 1)) / GOB_SIZE_X;
267 for (u32 line = 0; line < subrect_height; ++line) { 258 for (u32 line = 0; line < subrect_height; ++line) {
268 const u32 dst_y = line + offset_y; 259 const u32 dst_y = line + offset_y;
269 const u32 gob_address_y = 260 const u32 gob_address_y =
270 (dst_y / (gob_size_y * block_height)) * gob_size * block_height * image_width_in_gobs + 261 (dst_y / (GOB_SIZE_Y * block_height)) * GOB_SIZE * block_height * image_width_in_gobs +
271 ((dst_y % (gob_size_y * block_height)) / gob_size_y) * gob_size; 262 ((dst_y % (GOB_SIZE_Y * block_height)) / GOB_SIZE_Y) * GOB_SIZE;
272 const auto& table = legacy_swizzle_table[dst_y % gob_size_y]; 263 const auto& table = LEGACY_SWIZZLE_TABLE[dst_y % GOB_SIZE_Y];
273 for (u32 x = 0; x < subrect_width; ++x) { 264 for (u32 x = 0; x < subrect_width; ++x) {
274 const u32 dst_x = x + offset_x; 265 const u32 dst_x = x + offset_x;
275 const u32 gob_address = 266 const u32 gob_address =
276 gob_address_y + (dst_x * bytes_per_pixel / gob_size_x) * gob_size * block_height; 267 gob_address_y + (dst_x * bytes_per_pixel / GOB_SIZE_X) * GOB_SIZE * block_height;
277 const u32 swizzled_offset = gob_address + table[(dst_x * bytes_per_pixel) % gob_size_x]; 268 const u32 swizzled_offset = gob_address + table[(dst_x * bytes_per_pixel) % GOB_SIZE_X];
278 u8* source_line = unswizzled_data + line * source_pitch + x * bytes_per_pixel; 269 const u32 unswizzled_offset = line * source_pitch + x * bytes_per_pixel;
279 u8* dest_addr = swizzled_data + swizzled_offset;
280 270
271 const u8* const source_line = unswizzled_data + unswizzled_offset;
272 u8* const dest_addr = swizzled_data + swizzled_offset;
281 std::memcpy(dest_addr, source_line, bytes_per_pixel); 273 std::memcpy(dest_addr, source_line, bytes_per_pixel);
282 } 274 }
283 } 275 }
@@ -289,14 +281,15 @@ void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32
289 const u32 block_height = 1U << block_height_bit; 281 const u32 block_height = 1U << block_height_bit;
290 for (u32 line = 0; line < subrect_height; ++line) { 282 for (u32 line = 0; line < subrect_height; ++line) {
291 const u32 y2 = line + offset_y; 283 const u32 y2 = line + offset_y;
292 const u32 gob_address_y = (y2 / (gob_size_y * block_height)) * gob_size * block_height + 284 const u32 gob_address_y = (y2 / (GOB_SIZE_Y * block_height)) * GOB_SIZE * block_height +
293 ((y2 % (gob_size_y * block_height)) / gob_size_y) * gob_size; 285 ((y2 % (GOB_SIZE_Y * block_height)) / GOB_SIZE_Y) * GOB_SIZE;
294 const auto& table = legacy_swizzle_table[y2 % gob_size_y]; 286 const auto& table = LEGACY_SWIZZLE_TABLE[y2 % GOB_SIZE_Y];
295 for (u32 x = 0; x < subrect_width; ++x) { 287 for (u32 x = 0; x < subrect_width; ++x) {
296 const u32 x2 = (x + offset_x) * bytes_per_pixel; 288 const u32 x2 = (x + offset_x) * bytes_per_pixel;
297 const u32 gob_address = gob_address_y + (x2 / gob_size_x) * gob_size * block_height; 289 const u32 gob_address = gob_address_y + (x2 / GOB_SIZE_X) * GOB_SIZE * block_height;
298 const u32 swizzled_offset = gob_address + table[x2 % gob_size_x]; 290 const u32 swizzled_offset = gob_address + table[x2 % GOB_SIZE_X];
299 u8* dest_line = unswizzled_data + line * dest_pitch + x * bytes_per_pixel; 291 const u32 unswizzled_offset = line * dest_pitch + x * bytes_per_pixel;
292 u8* dest_line = unswizzled_data + unswizzled_offset;
300 u8* source_addr = swizzled_data + swizzled_offset; 293 u8* source_addr = swizzled_data + swizzled_offset;
301 294
302 std::memcpy(dest_line, source_addr, bytes_per_pixel); 295 std::memcpy(dest_line, source_addr, bytes_per_pixel);
@@ -304,21 +297,48 @@ void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32
304 } 297 }
305} 298}
306 299
300void SwizzleSliceToVoxel(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 height,
301 u32 bytes_per_pixel, u32 block_height, u32 block_depth, u32 origin_x,
302 u32 origin_y, u8* output, const u8* input) {
303 UNIMPLEMENTED_IF(origin_x > 0);
304 UNIMPLEMENTED_IF(origin_y > 0);
305
306 const u32 stride = width * bytes_per_pixel;
307 const u32 gobs_in_x = (stride + GOB_SIZE_X - 1) / GOB_SIZE_X;
308 const u32 block_size = gobs_in_x << (GOB_SIZE_SHIFT + block_height + block_depth);
309
310 const u32 block_height_mask = (1U << block_height) - 1;
311 const u32 x_shift = Common::CountTrailingZeroes32(GOB_SIZE << (block_height + block_depth));
312
313 for (u32 line = 0; line < line_count; ++line) {
314 const auto& table = LEGACY_SWIZZLE_TABLE[line % GOB_SIZE_Y];
315 const u32 block_y = line / GOB_SIZE_Y;
316 const u32 dst_offset_y =
317 (block_y >> block_height) * block_size + (block_y & block_height_mask) * GOB_SIZE;
318 for (u32 x = 0; x < line_length_in; ++x) {
319 const u32 dst_offset =
320 ((x / GOB_SIZE_X) << x_shift) + dst_offset_y + table[x % GOB_SIZE_X];
321 const u32 src_offset = x * bytes_per_pixel + line * pitch;
322 std::memcpy(output + dst_offset, input + src_offset, bytes_per_pixel);
323 }
324 }
325}
326
307void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32 dst_y, 327void SwizzleKepler(const u32 width, const u32 height, const u32 dst_x, const u32 dst_y,
308 const u32 block_height_bit, const std::size_t copy_size, const u8* source_data, 328 const u32 block_height_bit, const std::size_t copy_size, const u8* source_data,
309 u8* swizzle_data) { 329 u8* swizzle_data) {
310 const u32 block_height = 1U << block_height_bit; 330 const u32 block_height = 1U << block_height_bit;
311 const u32 image_width_in_gobs{(width + gob_size_x - 1) / gob_size_x}; 331 const u32 image_width_in_gobs{(width + GOB_SIZE_X - 1) / GOB_SIZE_X};
312 std::size_t count = 0; 332 std::size_t count = 0;
313 for (std::size_t y = dst_y; y < height && count < copy_size; ++y) { 333 for (std::size_t y = dst_y; y < height && count < copy_size; ++y) {
314 const std::size_t gob_address_y = 334 const std::size_t gob_address_y =
315 (y / (gob_size_y * block_height)) * gob_size * block_height * image_width_in_gobs + 335 (y / (GOB_SIZE_Y * block_height)) * GOB_SIZE * block_height * image_width_in_gobs +
316 ((y % (gob_size_y * block_height)) / gob_size_y) * gob_size; 336 ((y % (GOB_SIZE_Y * block_height)) / GOB_SIZE_Y) * GOB_SIZE;
317 const auto& table = legacy_swizzle_table[y % gob_size_y]; 337 const auto& table = LEGACY_SWIZZLE_TABLE[y % GOB_SIZE_Y];
318 for (std::size_t x = dst_x; x < width && count < copy_size; ++x) { 338 for (std::size_t x = dst_x; x < width && count < copy_size; ++x) {
319 const std::size_t gob_address = 339 const std::size_t gob_address =
320 gob_address_y + (x / gob_size_x) * gob_size * block_height; 340 gob_address_y + (x / GOB_SIZE_X) * GOB_SIZE * block_height;
321 const std::size_t swizzled_offset = gob_address + table[x % gob_size_x]; 341 const std::size_t swizzled_offset = gob_address + table[x % GOB_SIZE_X];
322 const u8* source_line = source_data + count; 342 const u8* source_line = source_data + count;
323 u8* dest_addr = swizzle_data + swizzled_offset; 343 u8* dest_addr = swizzle_data + swizzled_offset;
324 count++; 344 count++;
@@ -373,9 +393,9 @@ std::vector<u8> DecodeTexture(const std::vector<u8>& texture_data, TextureFormat
373std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth, 393std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height, u32 depth,
374 u32 block_height, u32 block_depth) { 394 u32 block_height, u32 block_depth) {
375 if (tiled) { 395 if (tiled) {
376 const u32 aligned_width = Common::AlignBits(width * bytes_per_pixel, gob_size_x_shift); 396 const u32 aligned_width = Common::AlignBits(width * bytes_per_pixel, GOB_SIZE_X_SHIFT);
377 const u32 aligned_height = Common::AlignBits(height, gob_size_y_shift + block_height); 397 const u32 aligned_height = Common::AlignBits(height, GOB_SIZE_Y_SHIFT + block_height);
378 const u32 aligned_depth = Common::AlignBits(depth, gob_size_z_shift + block_depth); 398 const u32 aligned_depth = Common::AlignBits(depth, GOB_SIZE_Z_SHIFT + block_depth);
379 return aligned_width * aligned_height * aligned_depth; 399 return aligned_width * aligned_height * aligned_depth;
380 } else { 400 } else {
381 return width * height * depth * bytes_per_pixel; 401 return width * height * depth * bytes_per_pixel;
@@ -386,14 +406,14 @@ u64 GetGOBOffset(u32 width, u32 height, u32 dst_x, u32 dst_y, u32 block_height,
386 u32 bytes_per_pixel) { 406 u32 bytes_per_pixel) {
387 auto div_ceil = [](const u32 x, const u32 y) { return ((x + y - 1) / y); }; 407 auto div_ceil = [](const u32 x, const u32 y) { return ((x + y - 1) / y); };
388 const u32 gobs_in_block = 1 << block_height; 408 const u32 gobs_in_block = 1 << block_height;
389 const u32 y_blocks = gob_size_y << block_height; 409 const u32 y_blocks = GOB_SIZE_Y << block_height;
390 const u32 x_per_gob = gob_size_x / bytes_per_pixel; 410 const u32 x_per_gob = GOB_SIZE_X / bytes_per_pixel;
391 const u32 x_blocks = div_ceil(width, x_per_gob); 411 const u32 x_blocks = div_ceil(width, x_per_gob);
392 const u32 block_size = gob_size * gobs_in_block; 412 const u32 block_size = GOB_SIZE * gobs_in_block;
393 const u32 stride = block_size * x_blocks; 413 const u32 stride = block_size * x_blocks;
394 const u32 base = (dst_y / y_blocks) * stride + (dst_x / x_per_gob) * block_size; 414 const u32 base = (dst_y / y_blocks) * stride + (dst_x / x_per_gob) * block_size;
395 const u32 relative_y = dst_y % y_blocks; 415 const u32 relative_y = dst_y % y_blocks;
396 return base + (relative_y / gob_size_y) * gob_size; 416 return base + (relative_y / GOB_SIZE_Y) * GOB_SIZE;
397} 417}
398 418
399} // namespace Tegra::Texture 419} // namespace Tegra::Texture
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h
index 06f3ebf87..232b696b3 100644
--- a/src/video_core/textures/decoders.h
+++ b/src/video_core/textures/decoders.h
@@ -10,15 +10,15 @@
10 10
11namespace Tegra::Texture { 11namespace Tegra::Texture {
12 12
13// GOBSize constant. Calculated by 64 bytes in x multiplied by 8 y coords, represents 13constexpr u32 GOB_SIZE_X = 64;
14// an small rect of (64/bytes_per_pixel)X8. 14constexpr u32 GOB_SIZE_Y = 8;
15inline std::size_t GetGOBSize() { 15constexpr u32 GOB_SIZE_Z = 1;
16 return 512; 16constexpr u32 GOB_SIZE = GOB_SIZE_X * GOB_SIZE_Y * GOB_SIZE_Z;
17}
18 17
19inline std::size_t GetGOBSizeShift() { 18constexpr std::size_t GOB_SIZE_X_SHIFT = 6;
20 return 9; 19constexpr std::size_t GOB_SIZE_Y_SHIFT = 3;
21} 20constexpr std::size_t GOB_SIZE_Z_SHIFT = 0;
21constexpr std::size_t GOB_SIZE_SHIFT = GOB_SIZE_X_SHIFT + GOB_SIZE_Y_SHIFT + GOB_SIZE_Z_SHIFT;
22 22
23/// Unswizzles a swizzled texture without changing its format. 23/// Unswizzles a swizzled texture without changing its format.
24void UnswizzleTexture(u8* unswizzled_data, u8* address, u32 tile_size_x, u32 tile_size_y, 24void UnswizzleTexture(u8* unswizzled_data, u8* address, u32 tile_size_x, u32 tile_size_y,
@@ -48,14 +48,32 @@ std::size_t CalculateSize(bool tiled, u32 bytes_per_pixel, u32 width, u32 height
48 48
49/// Copies an untiled subrectangle into a tiled surface. 49/// Copies an untiled subrectangle into a tiled surface.
50void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width, 50void SwizzleSubrect(u32 subrect_width, u32 subrect_height, u32 source_pitch, u32 swizzled_width,
51 u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height, 51 u32 bytes_per_pixel, u8* swizzled_data, const u8* unswizzled_data,
52 u32 offset_x, u32 offset_y); 52 u32 block_height_bit, u32 offset_x, u32 offset_y);
53 53
54/// Copies a tiled subrectangle into a linear surface. 54/// Copies a tiled subrectangle into a linear surface.
55void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width, 55void UnswizzleSubrect(u32 subrect_width, u32 subrect_height, u32 dest_pitch, u32 swizzled_width,
56 u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height, 56 u32 bytes_per_pixel, u8* swizzled_data, u8* unswizzled_data, u32 block_height,
57 u32 offset_x, u32 offset_y); 57 u32 offset_x, u32 offset_y);
58 58
59/// @brief Swizzles a 2D array of pixels into a 3D texture
60/// @param line_length_in Number of pixels per line
61/// @param line_count Number of lines
62/// @param pitch Number of bytes per line
63/// @param width Width of the swizzled texture
64/// @param height Height of the swizzled texture
65/// @param bytes_per_pixel Number of bytes used per pixel
66/// @param block_height Block height shift
67/// @param block_depth Block depth shift
68/// @param origin_x Column offset in pixels of the swizzled texture
69/// @param origin_y Row offset in pixels of the swizzled texture
70/// @param output Pointer to the pixels of the swizzled texture
71/// @param input Pointer to the 2D array of pixels used as input
72/// @pre input and output points to an array large enough to hold the number of bytes used
73void SwizzleSliceToVoxel(u32 line_length_in, u32 line_count, u32 pitch, u32 width, u32 height,
74 u32 bytes_per_pixel, u32 block_height, u32 block_depth, u32 origin_x,
75 u32 origin_y, u8* output, const u8* input);
76
59void SwizzleKepler(u32 width, u32 height, u32 dst_x, u32 dst_y, u32 block_height, 77void SwizzleKepler(u32 width, u32 height, u32 dst_x, u32 dst_y, u32 block_height,
60 std::size_t copy_size, const u8* source_data, u8* swizzle_data); 78 std::size_t copy_size, const u8* source_data, u8* swizzle_data);
61 79
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index ff7d9c1fa..a862b2610 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -30,6 +30,12 @@ add_executable(yuzu
30 configuration/configure_audio.cpp 30 configuration/configure_audio.cpp
31 configuration/configure_audio.h 31 configuration/configure_audio.h
32 configuration/configure_audio.ui 32 configuration/configure_audio.ui
33 configuration/configure_cpu.cpp
34 configuration/configure_cpu.h
35 configuration/configure_cpu.ui
36 configuration/configure_cpu_debug.cpp
37 configuration/configure_cpu_debug.h
38 configuration/configure_cpu_debug.ui
33 configuration/configure_debug.cpp 39 configuration/configure_debug.cpp
34 configuration/configure_debug.h 40 configuration/configure_debug.h
35 configuration/configure_debug.ui 41 configuration/configure_debug.ui
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 1b2b1b2bb..d25b99a32 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -505,22 +505,6 @@ void Config::ReadDataStorageValues() {
505 ReadSetting(QStringLiteral("gamecard_current_game"), false).toBool(); 505 ReadSetting(QStringLiteral("gamecard_current_game"), false).toBool();
506 Settings::values.gamecard_path = 506 Settings::values.gamecard_path =
507 ReadSetting(QStringLiteral("gamecard_path"), QStringLiteral("")).toString().toStdString(); 507 ReadSetting(QStringLiteral("gamecard_path"), QStringLiteral("")).toString().toStdString();
508 Settings::values.nand_total_size = static_cast<Settings::NANDTotalSize>(
509 ReadSetting(QStringLiteral("nand_total_size"),
510 QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDTotalSize::S29_1GB)))
511 .toULongLong());
512 Settings::values.nand_user_size = static_cast<Settings::NANDUserSize>(
513 ReadSetting(QStringLiteral("nand_user_size"),
514 QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDUserSize::S26GB)))
515 .toULongLong());
516 Settings::values.nand_system_size = static_cast<Settings::NANDSystemSize>(
517 ReadSetting(QStringLiteral("nand_system_size"),
518 QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDSystemSize::S2_5GB)))
519 .toULongLong());
520 Settings::values.sdmc_size = static_cast<Settings::SDMCSize>(
521 ReadSetting(QStringLiteral("sdmc_size"),
522 QVariant::fromValue<u64>(static_cast<u64>(Settings::SDMCSize::S16GB)))
523 .toULongLong());
524 508
525 qt_config->endGroup(); 509 qt_config->endGroup();
526} 510}
@@ -540,8 +524,6 @@ void Config::ReadDebuggingValues() {
540 Settings::values.reporting_services = 524 Settings::values.reporting_services =
541 ReadSetting(QStringLiteral("reporting_services"), false).toBool(); 525 ReadSetting(QStringLiteral("reporting_services"), false).toBool();
542 Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool(); 526 Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool();
543 Settings::values.disable_cpu_opt =
544 ReadSetting(QStringLiteral("disable_cpu_opt"), false).toBool();
545 Settings::values.disable_macro_jit = 527 Settings::values.disable_macro_jit =
546 ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool(); 528 ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool();
547 529
@@ -633,6 +615,34 @@ void Config::ReadPathValues() {
633 qt_config->endGroup(); 615 qt_config->endGroup();
634} 616}
635 617
618void Config::ReadCpuValues() {
619 qt_config->beginGroup(QStringLiteral("Cpu"));
620
621 if (global) {
622 Settings::values.cpu_accuracy = static_cast<Settings::CPUAccuracy>(
623 ReadSetting(QStringLiteral("cpu_accuracy"), 0).toInt());
624
625 Settings::values.cpuopt_page_tables =
626 ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool();
627 Settings::values.cpuopt_block_linking =
628 ReadSetting(QStringLiteral("cpuopt_block_linking"), true).toBool();
629 Settings::values.cpuopt_return_stack_buffer =
630 ReadSetting(QStringLiteral("cpuopt_return_stack_buffer"), true).toBool();
631 Settings::values.cpuopt_fast_dispatcher =
632 ReadSetting(QStringLiteral("cpuopt_fast_dispatcher"), true).toBool();
633 Settings::values.cpuopt_context_elimination =
634 ReadSetting(QStringLiteral("cpuopt_context_elimination"), true).toBool();
635 Settings::values.cpuopt_const_prop =
636 ReadSetting(QStringLiteral("cpuopt_const_prop"), true).toBool();
637 Settings::values.cpuopt_misc_ir =
638 ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
639 Settings::values.cpuopt_reduce_misalign_checks =
640 ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
641 }
642
643 qt_config->endGroup();
644}
645
636void Config::ReadRendererValues() { 646void Config::ReadRendererValues() {
637 qt_config->beginGroup(QStringLiteral("Renderer")); 647 qt_config->beginGroup(QStringLiteral("Renderer"));
638 648
@@ -829,6 +839,7 @@ void Config::ReadValues() {
829 ReadMiscellaneousValues(); 839 ReadMiscellaneousValues();
830 } 840 }
831 ReadCoreValues(); 841 ReadCoreValues();
842 ReadCpuValues();
832 ReadRendererValues(); 843 ReadRendererValues();
833 ReadAudioValues(); 844 ReadAudioValues();
834 ReadSystemValues(); 845 ReadSystemValues();
@@ -929,6 +940,7 @@ void Config::SaveValues() {
929 SaveMiscellaneousValues(); 940 SaveMiscellaneousValues();
930 } 941 }
931 SaveCoreValues(); 942 SaveCoreValues();
943 SaveCpuValues();
932 SaveRendererValues(); 944 SaveRendererValues();
933 SaveAudioValues(); 945 SaveAudioValues();
934 SaveSystemValues(); 946 SaveSystemValues();
@@ -1006,18 +1018,7 @@ void Config::SaveDataStorageValues() {
1006 false); 1018 false);
1007 WriteSetting(QStringLiteral("gamecard_path"), 1019 WriteSetting(QStringLiteral("gamecard_path"),
1008 QString::fromStdString(Settings::values.gamecard_path), QStringLiteral("")); 1020 QString::fromStdString(Settings::values.gamecard_path), QStringLiteral(""));
1009 WriteSetting(QStringLiteral("nand_total_size"), 1021
1010 QVariant::fromValue<u64>(static_cast<u64>(Settings::values.nand_total_size)),
1011 QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDTotalSize::S29_1GB)));
1012 WriteSetting(QStringLiteral("nand_user_size"),
1013 QVariant::fromValue<u64>(static_cast<u64>(Settings::values.nand_user_size)),
1014 QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDUserSize::S26GB)));
1015 WriteSetting(QStringLiteral("nand_system_size"),
1016 QVariant::fromValue<u64>(static_cast<u64>(Settings::values.nand_system_size)),
1017 QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDSystemSize::S2_5GB)));
1018 WriteSetting(QStringLiteral("sdmc_size"),
1019 QVariant::fromValue<u64>(static_cast<u64>(Settings::values.sdmc_size)),
1020 QVariant::fromValue<u64>(static_cast<u64>(Settings::SDMCSize::S16GB)));
1021 qt_config->endGroup(); 1022 qt_config->endGroup();
1022} 1023}
1023 1024
@@ -1033,7 +1034,6 @@ void Config::SaveDebuggingValues() {
1033 WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false); 1034 WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false);
1034 WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false); 1035 WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false);
1035 WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false); 1036 WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false);
1036 WriteSetting(QStringLiteral("disable_cpu_opt"), Settings::values.disable_cpu_opt, false);
1037 WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false); 1037 WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false);
1038 1038
1039 qt_config->endGroup(); 1039 qt_config->endGroup();
@@ -1097,6 +1097,32 @@ void Config::SavePathValues() {
1097 qt_config->endGroup(); 1097 qt_config->endGroup();
1098} 1098}
1099 1099
1100void Config::SaveCpuValues() {
1101 qt_config->beginGroup(QStringLiteral("Cpu"));
1102
1103 if (global) {
1104 WriteSetting(QStringLiteral("cpu_accuracy"),
1105 static_cast<int>(Settings::values.cpu_accuracy), 0);
1106
1107 WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables,
1108 true);
1109 WriteSetting(QStringLiteral("cpuopt_block_linking"), Settings::values.cpuopt_block_linking,
1110 true);
1111 WriteSetting(QStringLiteral("cpuopt_return_stack_buffer"),
1112 Settings::values.cpuopt_return_stack_buffer, true);
1113 WriteSetting(QStringLiteral("cpuopt_fast_dispatcher"),
1114 Settings::values.cpuopt_fast_dispatcher, true);
1115 WriteSetting(QStringLiteral("cpuopt_context_elimination"),
1116 Settings::values.cpuopt_context_elimination, true);
1117 WriteSetting(QStringLiteral("cpuopt_const_prop"), Settings::values.cpuopt_const_prop, true);
1118 WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
1119 WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
1120 Settings::values.cpuopt_reduce_misalign_checks, true);
1121 }
1122
1123 qt_config->endGroup();
1124}
1125
1100void Config::SaveRendererValues() { 1126void Config::SaveRendererValues() {
1101 qt_config->beginGroup(QStringLiteral("Renderer")); 1127 qt_config->beginGroup(QStringLiteral("Renderer"));
1102 1128
@@ -1342,11 +1368,13 @@ void Config::WriteSettingGlobal(const QString& name, const QVariant& value, bool
1342 1368
1343void Config::Reload() { 1369void Config::Reload() {
1344 ReadValues(); 1370 ReadValues();
1371 Settings::Sanitize();
1345 // To apply default value changes 1372 // To apply default value changes
1346 SaveValues(); 1373 SaveValues();
1347 Settings::Apply(); 1374 Settings::Apply();
1348} 1375}
1349 1376
1350void Config::Save() { 1377void Config::Save() {
1378 Settings::Sanitize();
1351 SaveValues(); 1379 SaveValues();
1352} 1380}
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index 681f0bca5..8e815f829 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -49,6 +49,7 @@ private:
49 void ReadDisabledAddOnValues(); 49 void ReadDisabledAddOnValues();
50 void ReadMiscellaneousValues(); 50 void ReadMiscellaneousValues();
51 void ReadPathValues(); 51 void ReadPathValues();
52 void ReadCpuValues();
52 void ReadRendererValues(); 53 void ReadRendererValues();
53 void ReadShortcutValues(); 54 void ReadShortcutValues();
54 void ReadSystemValues(); 55 void ReadSystemValues();
@@ -73,6 +74,7 @@ private:
73 void SaveDisabledAddOnValues(); 74 void SaveDisabledAddOnValues();
74 void SaveMiscellaneousValues(); 75 void SaveMiscellaneousValues();
75 void SavePathValues(); 76 void SavePathValues();
77 void SaveCpuValues();
76 void SaveRendererValues(); 78 void SaveRendererValues();
77 void SaveShortcutValues(); 79 void SaveShortcutValues();
78 void SaveSystemValues(); 80 void SaveSystemValues();
diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui
index 9aec1bd09..5f5d8e571 100644
--- a/src/yuzu/configuration/configure.ui
+++ b/src/yuzu/configuration/configure.ui
@@ -78,6 +78,16 @@
78 <string>Hotkeys</string> 78 <string>Hotkeys</string>
79 </attribute> 79 </attribute>
80 </widget> 80 </widget>
81 <widget class="ConfigureCpu" name="cpuTab">
82 <attribute name="title">
83 <string>CPU</string>
84 </attribute>
85 </widget>
86 <widget class="ConfigureCpuDebug" name="cpuDebugTab">
87 <attribute name="title">
88 <string>Debug</string>
89 </attribute>
90 </widget>
81 <widget class="ConfigureGraphics" name="graphicsTab"> 91 <widget class="ConfigureGraphics" name="graphicsTab">
82 <attribute name="title"> 92 <attribute name="title">
83 <string>Graphics</string> 93 <string>Graphics</string>
@@ -159,6 +169,18 @@
159 <container>1</container> 169 <container>1</container>
160 </customwidget> 170 </customwidget>
161 <customwidget> 171 <customwidget>
172 <class>ConfigureCpu</class>
173 <extends>QWidget</extends>
174 <header>configuration/configure_cpu.h</header>
175 <container>1</container>
176 </customwidget>
177 <customwidget>
178 <class>ConfigureCpuDebug</class>
179 <extends>QWidget</extends>
180 <header>configuration/configure_cpu_debug.h</header>
181 <container>1</container>
182 </customwidget>
183 <customwidget>
162 <class>ConfigureGraphics</class> 184 <class>ConfigureGraphics</class>
163 <extends>QWidget</extends> 185 <extends>QWidget</extends>
164 <header>configuration/configure_graphics.h</header> 186 <header>configuration/configure_graphics.h</header>
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
new file mode 100644
index 000000000..7493e5ffb
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -0,0 +1,61 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <QComboBox>
6#include <QMessageBox>
7
8#include "common/common_types.h"
9#include "common/logging/log.h"
10#include "core/core.h"
11#include "core/settings.h"
12#include "ui_configure_cpu.h"
13#include "yuzu/configuration/configure_cpu.h"
14
15ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureCpu) {
16 ui->setupUi(this);
17
18 SetConfiguration();
19
20 connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this,
21 &ConfigureCpu::AccuracyUpdated);
22}
23
24ConfigureCpu::~ConfigureCpu() = default;
25
26void ConfigureCpu::SetConfiguration() {
27 const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
28
29 ui->accuracy->setEnabled(runtime_lock);
30 ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy));
31}
32
33void ConfigureCpu::AccuracyUpdated(int index) {
34 if (static_cast<Settings::CPUAccuracy>(index) == Settings::CPUAccuracy::DebugMode) {
35 const auto result = QMessageBox::warning(this, tr("Setting CPU to Debug Mode"),
36 tr("CPU Debug Mode is only intended for developer "
37 "use. Are you sure you want to enable this?"),
38 QMessageBox::Yes | QMessageBox::No);
39 if (result == QMessageBox::No) {
40 ui->accuracy->setCurrentIndex(static_cast<int>(Settings::CPUAccuracy::Accurate));
41 return;
42 }
43 }
44}
45
46void ConfigureCpu::ApplyConfiguration() {
47 Settings::values.cpu_accuracy =
48 static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex());
49}
50
51void ConfigureCpu::changeEvent(QEvent* event) {
52 if (event->type() == QEvent::LanguageChange) {
53 RetranslateUI();
54 }
55
56 QWidget::changeEvent(event);
57}
58
59void ConfigureCpu::RetranslateUI() {
60 ui->retranslateUi(this);
61}
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
new file mode 100644
index 000000000..e4741d3a4
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -0,0 +1,33 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <QWidget>
9#include "core/settings.h"
10
11namespace Ui {
12class ConfigureCpu;
13}
14
15class ConfigureCpu : public QWidget {
16 Q_OBJECT
17
18public:
19 explicit ConfigureCpu(QWidget* parent = nullptr);
20 ~ConfigureCpu() override;
21
22 void ApplyConfiguration();
23
24private:
25 void changeEvent(QEvent* event) override;
26 void RetranslateUI();
27
28 void AccuracyUpdated(int index);
29
30 void SetConfiguration();
31
32 std::unique_ptr<Ui::ConfigureCpu> ui;
33};
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
new file mode 100644
index 000000000..bf6ea79bb
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -0,0 +1,92 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigureCpu</class>
4 <widget class="QWidget" name="ConfigureCpu">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>400</width>
10 <height>321</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <layout class="QVBoxLayout">
17 <item>
18 <layout class="QVBoxLayout">
19 <item>
20 <widget class="QGroupBox">
21 <property name="title">
22 <string>General</string>
23 </property>
24 <layout class="QVBoxLayout">
25 <item>
26 <layout class="QHBoxLayout">
27 <item>
28 <widget class="QLabel">
29 <property name="text">
30 <string>Accuracy:</string>
31 </property>
32 </widget>
33 </item>
34 <item>
35 <widget class="QComboBox" name="accuracy">
36 <item>
37 <property name="text">
38 <string>Accurate</string>
39 </property>
40 </item>
41 <item>
42 <property name="text">
43 <string>Enable Debug Mode</string>
44 </property>
45 </item>
46 </widget>
47 </item>
48 </layout>
49 </item>
50 <item>
51 <widget class="QLabel">
52 <property name="wordWrap">
53 <bool>1</bool>
54 </property>
55 <property name="text">
56 <string>We recommend setting accuracy to "Accurate".</string>
57 </property>
58 </widget>
59 </item>
60 </layout>
61 </widget>
62 </item>
63 </layout>
64 </item>
65 <item>
66 <spacer name="verticalSpacer">
67 <property name="orientation">
68 <enum>Qt::Vertical</enum>
69 </property>
70 <property name="sizeHint" stdset="0">
71 <size>
72 <width>20</width>
73 <height>40</height>
74 </size>
75 </property>
76 </spacer>
77 </item>
78 <item>
79 <widget class="QLabel" name="label_disable_info">
80 <property name="text">
81 <string>CPU settings are available only when game is not running.</string>
82 </property>
83 <property name="wordWrap">
84 <bool>true</bool>
85 </property>
86 </widget>
87 </item>
88 </layout>
89 </widget>
90 <resources/>
91 <connections/>
92</ui>
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
new file mode 100644
index 000000000..3385b2cf6
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -0,0 +1,65 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <QComboBox>
6
7#include "common/common_types.h"
8#include "common/logging/log.h"
9#include "core/core.h"
10#include "core/settings.h"
11#include "ui_configure_cpu_debug.h"
12#include "yuzu/configuration/configure_cpu_debug.h"
13
14ConfigureCpuDebug::ConfigureCpuDebug(QWidget* parent)
15 : QWidget(parent), ui(new Ui::ConfigureCpuDebug) {
16 ui->setupUi(this);
17
18 SetConfiguration();
19}
20
21ConfigureCpuDebug::~ConfigureCpuDebug() = default;
22
23void ConfigureCpuDebug::SetConfiguration() {
24 const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
25
26 ui->cpuopt_page_tables->setEnabled(runtime_lock);
27 ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables);
28 ui->cpuopt_block_linking->setEnabled(runtime_lock);
29 ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking);
30 ui->cpuopt_return_stack_buffer->setEnabled(runtime_lock);
31 ui->cpuopt_return_stack_buffer->setChecked(Settings::values.cpuopt_return_stack_buffer);
32 ui->cpuopt_fast_dispatcher->setEnabled(runtime_lock);
33 ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher);
34 ui->cpuopt_context_elimination->setEnabled(runtime_lock);
35 ui->cpuopt_context_elimination->setChecked(Settings::values.cpuopt_context_elimination);
36 ui->cpuopt_const_prop->setEnabled(runtime_lock);
37 ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop);
38 ui->cpuopt_misc_ir->setEnabled(runtime_lock);
39 ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir);
40 ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock);
41 ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks);
42}
43
44void ConfigureCpuDebug::ApplyConfiguration() {
45 Settings::values.cpuopt_page_tables = ui->cpuopt_page_tables->isChecked();
46 Settings::values.cpuopt_block_linking = ui->cpuopt_block_linking->isChecked();
47 Settings::values.cpuopt_return_stack_buffer = ui->cpuopt_return_stack_buffer->isChecked();
48 Settings::values.cpuopt_fast_dispatcher = ui->cpuopt_fast_dispatcher->isChecked();
49 Settings::values.cpuopt_context_elimination = ui->cpuopt_context_elimination->isChecked();
50 Settings::values.cpuopt_const_prop = ui->cpuopt_const_prop->isChecked();
51 Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked();
52 Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked();
53}
54
55void ConfigureCpuDebug::changeEvent(QEvent* event) {
56 if (event->type() == QEvent::LanguageChange) {
57 RetranslateUI();
58 }
59
60 QWidget::changeEvent(event);
61}
62
63void ConfigureCpuDebug::RetranslateUI() {
64 ui->retranslateUi(this);
65}
diff --git a/src/yuzu/configuration/configure_cpu_debug.h b/src/yuzu/configuration/configure_cpu_debug.h
new file mode 100644
index 000000000..c9941ef3b
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu_debug.h
@@ -0,0 +1,31 @@
1// Copyright 2020 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <QWidget>
9#include "core/settings.h"
10
11namespace Ui {
12class ConfigureCpuDebug;
13}
14
15class ConfigureCpuDebug : public QWidget {
16 Q_OBJECT
17
18public:
19 explicit ConfigureCpuDebug(QWidget* parent = nullptr);
20 ~ConfigureCpuDebug() override;
21
22 void ApplyConfiguration();
23
24private:
25 void changeEvent(QEvent* event) override;
26 void RetranslateUI();
27
28 void SetConfiguration();
29
30 std::unique_ptr<Ui::ConfigureCpuDebug> ui;
31};
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
new file mode 100644
index 000000000..a90dc64fe
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -0,0 +1,174 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConfigureCpuDebug</class>
4 <widget class="QWidget" name="ConfigureCpuDebug">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>400</width>
10 <height>321</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <layout class="QVBoxLayout">
17 <item>
18 <layout class="QVBoxLayout">
19 <item>
20 <widget class="QGroupBox">
21 <property name="title">
22 <string>Toggle CPU Optimizations</string>
23 </property>
24 <layout class="QVBoxLayout">
25 <item>
26 <widget class="QLabel">
27 <property name="wordWrap">
28 <bool>1</bool>
29 </property>
30 <property name="text">
31 <string>
32 &lt;div&gt;
33 &lt;b&gt;For debugging only.&lt;/b&gt;
34 &lt;br&gt;
35 If you're not sure what these do, keep all of these enabled.
36 &lt;br&gt;
37 These settings only take effect when CPU Accuracy is "Debug Mode".
38 &lt;/div&gt;
39 </string>
40 </property>
41 </widget>
42 </item>
43 <item>
44 <widget class="QCheckBox" name="cpuopt_page_tables">
45 <property name="text">
46 <string>Enable inline page tables</string>
47 </property>
48 <property name="toolTip">
49 <string>
50 &lt;div style="white-space: nowrap"&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
51 &lt;div style="white-space: nowrap"&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt;
52 &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt;
53 </string>
54 </property>
55 </widget>
56 </item>
57 <item>
58 <widget class="QCheckBox" name="cpuopt_block_linking">
59 <property name="text">
60 <string>Enable block linking</string>
61 </property>
62 <property name="toolTip">
63 <string>
64 &lt;div&gt;This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.&lt;/div&gt;
65 </string>
66 </property>
67 </widget>
68 </item>
69 <item>
70 <widget class="QCheckBox" name="cpuopt_return_stack_buffer">
71 <property name="text">
72 <string>Enable return stack buffer</string>
73 </property>
74 <property name="toolTip">
75 <string>
76 &lt;div&gt;This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.&lt;/div&gt;
77 </string>
78 </property>
79 </widget>
80 </item>
81 <item>
82 <widget class="QCheckBox" name="cpuopt_fast_dispatcher">
83 <property name="text">
84 <string>Enable fast dispatcher</string>
85 </property>
86 <property name="toolTip">
87 <string>
88 &lt;div&gt;Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.&lt;/div&gt;
89 </string>
90 </property>
91 </widget>
92 </item>
93 <item>
94 <widget class="QCheckBox" name="cpuopt_context_elimination">
95 <property name="text">
96 <string>Enable context elimination</string>
97 </property>
98 <property name="toolTip">
99 <string>
100 &lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt;
101 </string>
102 </property>
103 </widget>
104 </item>
105 <item>
106 <widget class="QCheckBox" name="cpuopt_const_prop">
107 <property name="text">
108 <string>Enable constant propagation</string>
109 </property>
110 <property name="toolTip">
111 <string>
112 &lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
113 </string>
114 </property>
115 </widget>
116 </item>
117 <item>
118 <widget class="QCheckBox" name="cpuopt_misc_ir">
119 <property name="text">
120 <string>Enable miscellaneous optimizations</string>
121 </property>
122 <property name="toolTip">
123 <string>
124 &lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt;
125 </string>
126 </property>
127 </widget>
128 </item>
129 <item>
130 <widget class="QCheckBox" name="cpuopt_reduce_misalign_checks">
131 <property name="text">
132 <string>Enable misalignment check reduction</string>
133 </property>
134 <property name="toolTip">
135 <string>
136 &lt;div style="white-space: nowrap"&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt;
137 &lt;div style="white-space: nowrap"&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt;
138 </string>
139 </property>
140 </widget>
141 </item>
142 </layout>
143 </widget>
144 </item>
145 </layout>
146 </item>
147 <item>
148 <spacer name="verticalSpacer">
149 <property name="orientation">
150 <enum>Qt::Vertical</enum>
151 </property>
152 <property name="sizeHint" stdset="0">
153 <size>
154 <width>20</width>
155 <height>40</height>
156 </size>
157 </property>
158 </spacer>
159 </item>
160 <item>
161 <widget class="QLabel" name="label_disable_info">
162 <property name="text">
163 <string>CPU settings are available only when game is not running.</string>
164 </property>
165 <property name="wordWrap">
166 <bool>true</bool>
167 </property>
168 </widget>
169 </item>
170 </layout>
171 </widget>
172 <resources/>
173 <connections/>
174</ui>
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 2c77441fd..d0e71dd60 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -36,7 +36,6 @@ void ConfigureDebug::SetConfiguration() {
36 ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args)); 36 ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args));
37 ui->reporting_services->setChecked(Settings::values.reporting_services); 37 ui->reporting_services->setChecked(Settings::values.reporting_services);
38 ui->quest_flag->setChecked(Settings::values.quest_flag); 38 ui->quest_flag->setChecked(Settings::values.quest_flag);
39 ui->disable_cpu_opt->setChecked(Settings::values.disable_cpu_opt);
40 ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn()); 39 ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn());
41 ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug); 40 ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug);
42 ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); 41 ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
@@ -51,7 +50,6 @@ void ConfigureDebug::ApplyConfiguration() {
51 Settings::values.program_args = ui->homebrew_args_edit->text().toStdString(); 50 Settings::values.program_args = ui->homebrew_args_edit->text().toStdString();
52 Settings::values.reporting_services = ui->reporting_services->isChecked(); 51 Settings::values.reporting_services = ui->reporting_services->isChecked();
53 Settings::values.quest_flag = ui->quest_flag->isChecked(); 52 Settings::values.quest_flag = ui->quest_flag->isChecked();
54 Settings::values.disable_cpu_opt = ui->disable_cpu_opt->isChecked();
55 Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); 53 Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked();
56 Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); 54 Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
57 Debugger::ToggleConsole(); 55 Debugger::ToggleConsole();
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 46f0208c6..272bdd6b8 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -228,13 +228,6 @@
228 </property> 228 </property>
229 </widget> 229 </widget>
230 </item> 230 </item>
231 <item>
232 <widget class="QCheckBox" name="disable_cpu_opt">
233 <property name="text">
234 <string>Disable CPU JIT optimizations</string>
235 </property>
236 </widget>
237 </item>
238 </layout> 231 </layout>
239 </widget> 232 </widget>
240 </item> 233 </item>
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 5918e9972..a5afb354f 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -42,6 +42,8 @@ void ConfigureDialog::ApplyConfiguration() {
42 ui->filesystemTab->applyConfiguration(); 42 ui->filesystemTab->applyConfiguration();
43 ui->inputTab->ApplyConfiguration(); 43 ui->inputTab->ApplyConfiguration();
44 ui->hotkeysTab->ApplyConfiguration(registry); 44 ui->hotkeysTab->ApplyConfiguration(registry);
45 ui->cpuTab->ApplyConfiguration();
46 ui->cpuDebugTab->ApplyConfiguration();
45 ui->graphicsTab->ApplyConfiguration(); 47 ui->graphicsTab->ApplyConfiguration();
46 ui->graphicsAdvancedTab->ApplyConfiguration(); 48 ui->graphicsAdvancedTab->ApplyConfiguration();
47 ui->audioTab->ApplyConfiguration(); 49 ui->audioTab->ApplyConfiguration();
@@ -76,9 +78,10 @@ void ConfigureDialog::RetranslateUI() {
76Q_DECLARE_METATYPE(QList<QWidget*>); 78Q_DECLARE_METATYPE(QList<QWidget*>);
77 79
78void ConfigureDialog::PopulateSelectionList() { 80void ConfigureDialog::PopulateSelectionList() {
79 const std::array<std::pair<QString, QList<QWidget*>>, 5> items{ 81 const std::array<std::pair<QString, QList<QWidget*>>, 6> items{
80 {{tr("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}}, 82 {{tr("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}},
81 {tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}}, 83 {tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}},
84 {tr("CPU"), {ui->cpuTab, ui->cpuDebugTab}},
82 {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}}, 85 {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}},
83 {tr("Audio"), {ui->audioTab}}, 86 {tr("Audio"), {ui->audioTab}},
84 {tr("Controls"), {ui->inputTab, ui->hotkeysTab}}}, 87 {tr("Controls"), {ui->inputTab, ui->hotkeysTab}}},
@@ -107,6 +110,8 @@ void ConfigureDialog::UpdateVisibleTabs() {
107 {ui->profileManagerTab, tr("Profiles")}, 110 {ui->profileManagerTab, tr("Profiles")},
108 {ui->inputTab, tr("Input")}, 111 {ui->inputTab, tr("Input")},
109 {ui->hotkeysTab, tr("Hotkeys")}, 112 {ui->hotkeysTab, tr("Hotkeys")},
113 {ui->cpuTab, tr("CPU")},
114 {ui->cpuDebugTab, tr("Debug")},
110 {ui->graphicsTab, tr("Graphics")}, 115 {ui->graphicsTab, tr("Graphics")},
111 {ui->graphicsAdvancedTab, tr("Advanced")}, 116 {ui->graphicsAdvancedTab, tr("Advanced")},
112 {ui->audioTab, tr("Audio")}, 117 {ui->audioTab, tr("Audio")},
diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp
index 835ee821c..a089f5733 100644
--- a/src/yuzu/configuration/configure_filesystem.cpp
+++ b/src/yuzu/configuration/configure_filesystem.cpp
@@ -11,19 +11,6 @@
11#include "yuzu/configuration/configure_filesystem.h" 11#include "yuzu/configuration/configure_filesystem.h"
12#include "yuzu/uisettings.h" 12#include "yuzu/uisettings.h"
13 13
14namespace {
15
16template <typename T>
17void SetComboBoxFromData(QComboBox* combo_box, T data) {
18 const auto index = combo_box->findData(QVariant::fromValue(static_cast<u64>(data)));
19 if (index >= combo_box->count() || index < 0)
20 return;
21
22 combo_box->setCurrentIndex(index);
23}
24
25} // Anonymous namespace
26
27ConfigureFilesystem::ConfigureFilesystem(QWidget* parent) 14ConfigureFilesystem::ConfigureFilesystem(QWidget* parent)
28 : QWidget(parent), ui(std::make_unique<Ui::ConfigureFilesystem>()) { 15 : QWidget(parent), ui(std::make_unique<Ui::ConfigureFilesystem>()) {
29 ui->setupUi(this); 16 ui->setupUi(this);
@@ -73,11 +60,6 @@ void ConfigureFilesystem::setConfiguration() {
73 60
74 ui->cache_game_list->setChecked(UISettings::values.cache_game_list); 61 ui->cache_game_list->setChecked(UISettings::values.cache_game_list);
75 62
76 SetComboBoxFromData(ui->nand_size, Settings::values.nand_total_size);
77 SetComboBoxFromData(ui->usrnand_size, Settings::values.nand_user_size);
78 SetComboBoxFromData(ui->sysnand_size, Settings::values.nand_system_size);
79 SetComboBoxFromData(ui->sdmc_size, Settings::values.sdmc_size);
80
81 UpdateEnabledControls(); 63 UpdateEnabledControls();
82} 64}
83 65
@@ -98,15 +80,6 @@ void ConfigureFilesystem::applyConfiguration() {
98 Settings::values.dump_nso = ui->dump_nso->isChecked(); 80 Settings::values.dump_nso = ui->dump_nso->isChecked();
99 81
100 UISettings::values.cache_game_list = ui->cache_game_list->isChecked(); 82 UISettings::values.cache_game_list = ui->cache_game_list->isChecked();
101
102 Settings::values.nand_total_size = static_cast<Settings::NANDTotalSize>(
103 ui->nand_size->itemData(ui->nand_size->currentIndex()).toULongLong());
104 Settings::values.nand_system_size = static_cast<Settings::NANDSystemSize>(
105 ui->nand_size->itemData(ui->sysnand_size->currentIndex()).toULongLong());
106 Settings::values.nand_user_size = static_cast<Settings::NANDUserSize>(
107 ui->nand_size->itemData(ui->usrnand_size->currentIndex()).toULongLong());
108 Settings::values.sdmc_size = static_cast<Settings::SDMCSize>(
109 ui->nand_size->itemData(ui->sdmc_size->currentIndex()).toULongLong());
110} 83}
111 84
112void ConfigureFilesystem::SetDirectory(DirectoryTarget target, QLineEdit* edit) { 85void ConfigureFilesystem::SetDirectory(DirectoryTarget target, QLineEdit* edit) {
diff --git a/src/yuzu/configuration/configure_filesystem.ui b/src/yuzu/configuration/configure_filesystem.ui
index 58cd07f52..84bea0600 100644
--- a/src/yuzu/configuration/configure_filesystem.ui
+++ b/src/yuzu/configuration/configure_filesystem.ui
@@ -116,127 +116,6 @@
116 </widget> 116 </widget>
117 </item> 117 </item>
118 <item> 118 <item>
119 <widget class="QGroupBox" name="groupBox_3">
120 <property name="title">
121 <string>Storage Sizes</string>
122 </property>
123 <layout class="QGridLayout" name="gridLayout_3">
124 <item row="3" column="0">
125 <widget class="QLabel" name="label_5">
126 <property name="text">
127 <string>SD Card</string>
128 </property>
129 </widget>
130 </item>
131 <item row="1" column="0">
132 <widget class="QLabel" name="label_4">
133 <property name="text">
134 <string>System NAND</string>
135 </property>
136 </widget>
137 </item>
138 <item row="1" column="1">
139 <widget class="QComboBox" name="sysnand_size">
140 <item>
141 <property name="text">
142 <string>2.5 GB</string>
143 </property>
144 </item>
145 </widget>
146 </item>
147 <item row="3" column="1">
148 <widget class="QComboBox" name="sdmc_size">
149 <property name="currentText">
150 <string>32 GB</string>
151 </property>
152 <item>
153 <property name="text">
154 <string>1 GB</string>
155 </property>
156 </item>
157 <item>
158 <property name="text">
159 <string>2 GB</string>
160 </property>
161 </item>
162 <item>
163 <property name="text">
164 <string>4 GB</string>
165 </property>
166 </item>
167 <item>
168 <property name="text">
169 <string>8 GB</string>
170 </property>
171 </item>
172 <item>
173 <property name="text">
174 <string>16 GB</string>
175 </property>
176 </item>
177 <item>
178 <property name="text">
179 <string>32 GB</string>
180 </property>
181 </item>
182 <item>
183 <property name="text">
184 <string>64 GB</string>
185 </property>
186 </item>
187 <item>
188 <property name="text">
189 <string>128 GB</string>
190 </property>
191 </item>
192 <item>
193 <property name="text">
194 <string>256 GB</string>
195 </property>
196 </item>
197 <item>
198 <property name="text">
199 <string>1 TB</string>
200 </property>
201 </item>
202 </widget>
203 </item>
204 <item row="2" column="1">
205 <widget class="QComboBox" name="usrnand_size">
206 <item>
207 <property name="text">
208 <string>26 GB</string>
209 </property>
210 </item>
211 </widget>
212 </item>
213 <item row="2" column="0">
214 <widget class="QLabel" name="label_6">
215 <property name="text">
216 <string>User NAND</string>
217 </property>
218 </widget>
219 </item>
220 <item row="0" column="0">
221 <widget class="QLabel" name="label_7">
222 <property name="text">
223 <string>NAND</string>
224 </property>
225 </widget>
226 </item>
227 <item row="0" column="1">
228 <widget class="QComboBox" name="nand_size">
229 <item>
230 <property name="text">
231 <string>29.1 GB</string>
232 </property>
233 </item>
234 </widget>
235 </item>
236 </layout>
237 </widget>
238 </item>
239 <item>
240 <widget class="QGroupBox" name="groupBox_4"> 119 <widget class="QGroupBox" name="groupBox_4">
241 <property name="title"> 120 <property name="title">
242 <string>Patch Manager</string> 121 <string>Patch Manager</string>
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 1fb62d1cf..20316c9cc 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -65,6 +65,8 @@ void ConfigureGeneral::ApplyConfiguration() {
65 Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() == 65 Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() ==
66 Qt::Checked); 66 Qt::Checked);
67 Settings::values.frame_limit.SetValue(ui->frame_limit->value()); 67 Settings::values.frame_limit.SetValue(ui->frame_limit->value());
68 }
69 if (Settings::values.use_multi_core.UsingGlobal()) {
68 Settings::values.use_multi_core.SetValue(ui->use_multi_core->isChecked()); 70 Settings::values.use_multi_core.SetValue(ui->use_multi_core->isChecked());
69 } 71 }
70 } else { 72 } else {
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 432379705..9f758605a 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -279,17 +279,21 @@ GMainWindow::~GMainWindow() {
279} 279}
280 280
281void GMainWindow::ProfileSelectorSelectProfile() { 281void GMainWindow::ProfileSelectorSelectProfile() {
282 QtProfileSelectionDialog dialog(this); 282 const Service::Account::ProfileManager manager;
283 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | 283 int index = 0;
284 Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); 284 if (manager.GetUserCount() != 1) {
285 dialog.setWindowModality(Qt::WindowModal); 285 QtProfileSelectionDialog dialog(this);
286 if (dialog.exec() == QDialog::Rejected) { 286 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
287 emit ProfileSelectorFinishedSelection(std::nullopt); 287 Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
288 return; 288 dialog.setWindowModality(Qt::WindowModal);
289 if (dialog.exec() == QDialog::Rejected) {
290 emit ProfileSelectorFinishedSelection(std::nullopt);
291 return;
292 }
293 index = dialog.GetIndex();
289 } 294 }
290 295
291 Service::Account::ProfileManager manager; 296 const auto uuid = manager.GetUser(static_cast<std::size_t>(index));
292 const auto uuid = manager.GetUser(static_cast<std::size_t>(dialog.GetIndex()));
293 if (!uuid.has_value()) { 297 if (!uuid.has_value()) {
294 emit ProfileSelectorFinishedSelection(std::nullopt); 298 emit ProfileSelectorFinishedSelection(std::nullopt);
295 return; 299 return;
@@ -1755,7 +1759,7 @@ InstallResult GMainWindow::InstallNSPXCI(const QString& filename) {
1755 *nsp, true, qt_raw_copy); 1759 *nsp, true, qt_raw_copy);
1756 if (res == FileSys::InstallResult::Success) { 1760 if (res == FileSys::InstallResult::Success) {
1757 return InstallResult::Success; 1761 return InstallResult::Success;
1758 } else if (res == FileSys::InstallResult::ErrorAlreadyExists) { 1762 } else if (res == FileSys::InstallResult::OverwriteExisting) {
1759 return InstallResult::Overwrite; 1763 return InstallResult::Overwrite;
1760 } else { 1764 } else {
1761 return InstallResult::Failure; 1765 return InstallResult::Failure;
@@ -1842,7 +1846,7 @@ InstallResult GMainWindow::InstallNCA(const QString& filename) {
1842 1846
1843 if (res == FileSys::InstallResult::Success) { 1847 if (res == FileSys::InstallResult::Success) {
1844 return InstallResult::Success; 1848 return InstallResult::Success;
1845 } else if (res == FileSys::InstallResult::ErrorAlreadyExists) { 1849 } else if (res == FileSys::InstallResult::OverwriteExisting) {
1846 return InstallResult::Overwrite; 1850 return InstallResult::Overwrite;
1847 } else { 1851 } else {
1848 return InstallResult::Failure; 1852 return InstallResult::Failure;
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 23763144f..7773228c8 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -335,15 +335,6 @@ void Config::ReadValues() {
335 Settings::values.gamecard_current_game = 335 Settings::values.gamecard_current_game =
336 sdl2_config->GetBoolean("Data Storage", "gamecard_current_game", false); 336 sdl2_config->GetBoolean("Data Storage", "gamecard_current_game", false);
337 Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", ""); 337 Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", "");
338 Settings::values.nand_total_size = static_cast<Settings::NANDTotalSize>(sdl2_config->GetInteger(
339 "Data Storage", "nand_total_size", static_cast<long>(Settings::NANDTotalSize::S29_1GB)));
340 Settings::values.nand_user_size = static_cast<Settings::NANDUserSize>(sdl2_config->GetInteger(
341 "Data Storage", "nand_user_size", static_cast<long>(Settings::NANDUserSize::S26GB)));
342 Settings::values.nand_system_size = static_cast<Settings::NANDSystemSize>(
343 sdl2_config->GetInteger("Data Storage", "nand_system_size",
344 static_cast<long>(Settings::NANDSystemSize::S2_5GB)));
345 Settings::values.sdmc_size = static_cast<Settings::SDMCSize>(sdl2_config->GetInteger(
346 "Data Storage", "sdmc_size", static_cast<long>(Settings::SDMCSize::S16GB)));
347 338
348 // System 339 // System
349 Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false); 340 Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false);
@@ -437,8 +428,6 @@ void Config::ReadValues() {
437 Settings::values.reporting_services = 428 Settings::values.reporting_services =
438 sdl2_config->GetBoolean("Debugging", "reporting_services", false); 429 sdl2_config->GetBoolean("Debugging", "reporting_services", false);
439 Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false); 430 Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false);
440 Settings::values.disable_cpu_opt =
441 sdl2_config->GetBoolean("Debugging", "disable_cpu_opt", false);
442 Settings::values.disable_macro_jit = 431 Settings::values.disable_macro_jit =
443 sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false); 432 sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false);
444 433
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 45c07ed5d..5bed47fd7 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -97,6 +97,39 @@ udp_pad_index=
97# 0 (default): Disabled, 1: Enabled 97# 0 (default): Disabled, 1: Enabled
98use_multi_core= 98use_multi_core=
99 99
100[Cpu]
101# Enable inline page tables optimization (faster guest memory access)
102# 0: Disabled, 1 (default): Enabled
103cpuopt_page_tables =
104
105# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
106# 0: Disabled, 1 (default): Enabled
107cpuopt_block_linking =
108
109# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
110# 0: Disabled, 1 (default): Enabled
111cpuopt_return_stack_buffer =
112
113# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
114# 0: Disabled, 1 (default): Enabled
115cpuopt_fast_dispatcher =
116
117# Enable context elimination CPU Optimization (reduce host memory use for guest context)
118# 0: Disabled, 1 (default): Enabled
119cpuopt_context_elimination =
120
121# Enable constant propagation CPU optimization (basic IR optimization)
122# 0: Disabled, 1 (default): Enabled
123cpuopt_const_prop =
124
125# Enable miscellaneous CPU optimizations (basic IR optimization)
126# 0: Disabled, 1 (default): Enabled
127cpuopt_misc_ir =
128
129# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
130# 0: Disabled, 1 (default): Enabled
131cpuopt_reduce_misalign_checks =
132
100[Renderer] 133[Renderer]
101# Which backend API to use. 134# Which backend API to use.
102# 0 (default): OpenGL, 1: Vulkan 135# 0 (default): OpenGL, 1: Vulkan
@@ -283,9 +316,6 @@ dump_nso=false
283# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode 316# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
284# false: Retail/Normal Mode (default), true: Kiosk Mode 317# false: Retail/Normal Mode (default), true: Kiosk Mode
285quest_flag = 318quest_flag =
286# Determines whether or not JIT CPU optimizations are enabled
287# false: Optimizations Enabled, true: Optimizations Disabled
288disable_cpu_opt =
289# Enables/Disables the macro JIT compiler 319# Enables/Disables the macro JIT compiler
290disable_macro_jit=false 320disable_macro_jit=false
291 321
diff --git a/src/yuzu_tester/default_ini.h b/src/yuzu_tester/default_ini.h
index 41bbbbf60..3eb64e9d7 100644
--- a/src/yuzu_tester/default_ini.h
+++ b/src/yuzu_tester/default_ini.h
@@ -12,6 +12,39 @@ const char* sdl2_config_file = R"(
12# 0 (default): Disabled, 1: Enabled 12# 0 (default): Disabled, 1: Enabled
13use_multi_core= 13use_multi_core=
14 14
15[Cpu]
16# Enable inline page tables optimization (faster guest memory access)
17# 0: Disabled, 1 (default): Enabled
18cpuopt_page_tables =
19
20# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
21# 0: Disabled, 1 (default): Enabled
22cpuopt_block_linking =
23
24# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
25# 0: Disabled, 1 (default): Enabled
26cpuopt_return_stack_buffer =
27
28# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
29# 0: Disabled, 1 (default): Enabled
30cpuopt_fast_dispatcher =
31
32# Enable context elimination CPU Optimization (reduce host memory use for guest context)
33# 0: Disabled, 1 (default): Enabled
34cpuopt_context_elimination =
35
36# Enable constant propagation CPU optimization (basic IR optimization)
37# 0: Disabled, 1 (default): Enabled
38cpuopt_const_prop =
39
40# Enable miscellaneous CPU optimizations (basic IR optimization)
41# 0: Disabled, 1 (default): Enabled
42cpuopt_misc_ir =
43
44# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
45# 0: Disabled, 1 (default): Enabled
46cpuopt_reduce_misalign_checks =
47
15[Renderer] 48[Renderer]
16# Whether to use software or hardware rendering. 49# Whether to use software or hardware rendering.
17# 0: Software, 1 (default): Hardware 50# 0: Software, 1 (default): Hardware