summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-12-24 13:30:07 -0500
committerGravatar Zach Hilman2019-04-25 08:07:57 -0400
commitf0db2e3ef36a77f2f3eaf2dca15ddfe8851edecb (patch)
tree9a89f82fd9ac54d69bf7c4a2412689fe816aba41 /src
parentmii: Implement IDatabaseService commands using MiiManager (diff)
downloadyuzu-f0db2e3ef36a77f2f3eaf2dca15ddfe8851edecb.tar.gz
yuzu-f0db2e3ef36a77f2f3eaf2dca15ddfe8851edecb.tar.xz
yuzu-f0db2e3ef36a77f2f3eaf2dca15ddfe8851edecb.zip
mii_manager: Cleanup and optimization
Diffstat (limited to 'src')
-rw-r--r--src/common/uuid.cpp2
-rw-r--r--src/common/uuid.h6
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp8
-rw-r--r--src/core/hle/service/mii/mii_manager.cpp68
-rw-r--r--src/core/hle/service/mii/mii_manager.h10
5 files changed, 55 insertions, 39 deletions
diff --git a/src/common/uuid.cpp b/src/common/uuid.cpp
index 8e63b58b8..26db03fba 100644
--- a/src/common/uuid.cpp
+++ b/src/common/uuid.cpp
@@ -1,4 +1,4 @@
1// Copyright 2018 Citra Emulator Project 1// Copyright 2018 yuzu Emulator Project
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
diff --git a/src/common/uuid.h b/src/common/uuid.h
index 4a5e5fa7c..b8864b34f 100644
--- a/src/common/uuid.h
+++ b/src/common/uuid.h
@@ -1,9 +1,11 @@
1// Copyright 2018 Citra Emulator Project 1// Copyright 2018 yuzu Emulator Project
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#pragma once 5#pragma once
6 6
7#include <string>
8
7#include "common/common_types.h" 9#include "common/common_types.h"
8 10
9namespace Common { 11namespace Common {
@@ -33,7 +35,7 @@ struct UUID {
33 static UUID Generate(); 35 static UUID Generate();
34 36
35 // Set the UUID to {0,0} to be considered an invalid user 37 // Set the UUID to {0,0} to be considered an invalid user
36 void Invalidate() { 38 constexpr void Invalidate() {
37 uuid = INVALID_UUID; 39 uuid = INVALID_UUID;
38 } 40 }
39 41
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp
index 767523dbc..49aa5908b 100644
--- a/src/core/hle/service/acc/profile_manager.cpp
+++ b/src/core/hle/service/acc/profile_manager.cpp
@@ -13,7 +13,7 @@
13 13
14namespace Service::Account { 14namespace Service::Account {
15 15
16using namespace Common; 16using Common::UUID;
17 17
18struct UserRaw { 18struct UserRaw {
19 UUID uuid; 19 UUID uuid;
@@ -199,7 +199,7 @@ bool ProfileManager::UserExists(UUID uuid) const {
199bool ProfileManager::UserExistsIndex(std::size_t index) const { 199bool ProfileManager::UserExistsIndex(std::size_t index) const {
200 if (index >= MAX_USERS) 200 if (index >= MAX_USERS)
201 return false; 201 return false;
202 return profiles[index].user_uuid.uuid != INVALID_UUID; 202 return profiles[index].user_uuid.uuid != Common::INVALID_UUID;
203} 203}
204 204
205/// Opens a specific user 205/// Opens a specific user
@@ -293,7 +293,7 @@ bool ProfileManager::RemoveUser(UUID uuid) {
293 293
294bool ProfileManager::SetProfileBase(UUID uuid, const ProfileBase& profile_new) { 294bool ProfileManager::SetProfileBase(UUID uuid, const ProfileBase& profile_new) {
295 const auto index = GetUserIndex(uuid); 295 const auto index = GetUserIndex(uuid);
296 if (!index || profile_new.user_uuid == UUID(INVALID_UUID)) { 296 if (!index || profile_new.user_uuid == UUID(Common::INVALID_UUID)) {
297 return false; 297 return false;
298 } 298 }
299 299
@@ -324,7 +324,7 @@ void ProfileManager::ParseUserSaveFile() {
324 } 324 }
325 325
326 for (const auto& user : data.users) { 326 for (const auto& user : data.users) {
327 if (user.uuid == UUID(INVALID_UUID)) { 327 if (user.uuid == UUID(Common::INVALID_UUID)) {
328 continue; 328 continue;
329 } 329 }
330 330
diff --git a/src/core/hle/service/mii/mii_manager.cpp b/src/core/hle/service/mii/mii_manager.cpp
index 25dfd8d48..083c62b1e 100644
--- a/src/core/hle/service/mii/mii_manager.cpp
+++ b/src/core/hle/service/mii/mii_manager.cpp
@@ -12,8 +12,10 @@
12 12
13namespace Service::Mii { 13namespace Service::Mii {
14 14
15namespace {
16
15constexpr char MII_SAVE_DATABASE_PATH[] = "/system/save/8000000000000030/MiiDatabase.dat"; 17constexpr char MII_SAVE_DATABASE_PATH[] = "/system/save/8000000000000030/MiiDatabase.dat";
16constexpr std::array<char16_t, 11> DEFAULT_MII_NAME = {'y', 'u', 'z', 'u', '\0'}; 18constexpr std::array<char16_t, 11> DEFAULT_MII_NAME = {u'y', u'u', u'z', u'u', u'\0'};
17 19
18// This value was retrieved from HW test 20// This value was retrieved from HW test
19constexpr MiiStoreData DEFAULT_MII = { 21constexpr MiiStoreData DEFAULT_MII = {
@@ -30,10 +32,10 @@ constexpr MiiStoreData DEFAULT_MII = {
30// Default values taken from multiple real databases 32// Default values taken from multiple real databases
31const MiiDatabase DEFAULT_MII_DATABASE{Common::MakeMagic('N', 'F', 'D', 'B'), {}, {1}, 0, 0}; 33const MiiDatabase DEFAULT_MII_DATABASE{Common::MakeMagic('N', 'F', 'D', 'B'), {}, {1}, 0, 0};
32 34
33template <typename T, std::size_t s1, std::size_t s2> 35template <typename T, std::size_t SourceArraySize, std::size_t DestArraySize>
34std::array<T, s2> ResizeArray(const std::array<T, s1>& in) { 36std::array<T, DestArraySize> ResizeArray(const std::array<T, SourceArraySize>& in) {
35 std::array<T, s2> out{}; 37 std::array<T, DestArraySize> out{};
36 std::memcpy(out.data(), in.data(), sizeof(T) * std::min(s1, s2)); 38 std::memcpy(out.data(), in.data(), sizeof(T) * std::min(SourceArraySize, DestArraySize));
37 return out; 39 return out;
38} 40}
39 41
@@ -163,12 +165,14 @@ MiiStoreData ConvertInfoToStoreData(const MiiInfo& info) {
163 return out; 165 return out;
164} 166}
165 167
168} // namespace
169
166std::u16string MiiInfo::Name() const { 170std::u16string MiiInfo::Name() const {
167 return Common::UTF16StringFromFixedZeroTerminatedBuffer(name.data(), name.size()); 171 return Common::UTF16StringFromFixedZeroTerminatedBuffer(name.data(), name.size());
168} 172}
169 173
170bool operator==(const MiiInfo& lhs, const MiiInfo& rhs) { 174bool operator==(const MiiInfo& lhs, const MiiInfo& rhs) {
171 return std::memcmp(&lhs, &rhs, sizeof(MiiInfo)); 175 return std::memcmp(&lhs, &rhs, sizeof(MiiInfo)) == 0;
172} 176}
173 177
174bool operator!=(const MiiInfo& lhs, const MiiInfo& rhs) { 178bool operator!=(const MiiInfo& lhs, const MiiInfo& rhs) {
@@ -188,27 +192,15 @@ MiiInfo MiiManager::CreateRandom(RandomParameters params) {
188 "(STUBBED) called with params={:08X}{:08X}{:08X}, returning default Mii", 192 "(STUBBED) called with params={:08X}{:08X}{:08X}, returning default Mii",
189 params.unknown_1, params.unknown_2, params.unknown_3); 193 params.unknown_1, params.unknown_2, params.unknown_3);
190 194
191 auto new_mii = DEFAULT_MII; 195 return ConvertStoreDataToInfo(CreateMiiWithUniqueUUID());
192
193 do {
194 new_mii.uuid = Common::UUID::Generate();
195 } while (IndexOf(new_mii.uuid) == INVALID_INDEX);
196
197 return ConvertStoreDataToInfo(new_mii);
198} 196}
199 197
200MiiInfo MiiManager::CreateDefault(u32 index) { 198MiiInfo MiiManager::CreateDefault(u32 index) {
201 auto new_mii = DEFAULT_MII; 199 const auto new_mii = CreateMiiWithUniqueUUID();
202
203 do {
204 new_mii.uuid = Common::UUID::Generate();
205 } while (IndexOf(new_mii.uuid) == INVALID_INDEX);
206 200
207 ASSERT(index < MAX_MIIS); 201 database.miis.at(index) = new_mii;
208 database.miis[index] = new_mii;
209 std::stable_partition(database.miis.begin(), database.miis.end(),
210 [](const MiiStoreData& elem) { return elem.uuid; });
211 202
203 EnsureDatabasePartition();
212 return ConvertStoreDataToInfo(new_mii); 204 return ConvertStoreDataToInfo(new_mii);
213} 205}
214 206
@@ -253,8 +245,7 @@ bool MiiManager::Remove(Common::UUID uuid) {
253 return false; 245 return false;
254 246
255 *iter = MiiStoreData{}; 247 *iter = MiiStoreData{};
256 std::stable_partition(database.miis.begin(), database.miis.end(), 248 EnsureDatabasePartition();
257 [](const MiiStoreData& elem) { return elem.uuid; });
258 return true; 249 return true;
259} 250}
260 251
@@ -268,9 +259,9 @@ u32 MiiManager::IndexOf(Common::UUID uuid) const {
268 return static_cast<u32>(std::distance(database.miis.begin(), iter)); 259 return static_cast<u32>(std::distance(database.miis.begin(), iter));
269} 260}
270 261
271u32 MiiManager::IndexOf(MiiInfo info) const { 262u32 MiiManager::IndexOf(const MiiInfo& info) const {
272 const auto iter = 263 const auto iter =
273 std::find_if(database.miis.begin(), database.miis.end(), [info](const MiiStoreData& elem) { 264 std::find_if(database.miis.begin(), database.miis.end(), [&info](const MiiStoreData& elem) {
274 return ConvertStoreDataToInfo(elem) == info; 265 return ConvertStoreDataToInfo(elem) == info;
275 }); 266 });
276 267
@@ -296,12 +287,11 @@ bool MiiManager::Move(Common::UUID uuid, u32 new_index) {
296 database.miis[new_index] = moving; 287 database.miis[new_index] = moving;
297 } 288 }
298 289
299 std::stable_partition(database.miis.begin(), database.miis.end(), 290 EnsureDatabasePartition();
300 [](const MiiStoreData& elem) { return elem.uuid; });
301 return true; 291 return true;
302} 292}
303 293
304bool MiiManager::AddOrReplace(MiiStoreData data) { 294bool MiiManager::AddOrReplace(const MiiStoreData& data) {
305 const auto index = IndexOf(data.uuid); 295 const auto index = IndexOf(data.uuid);
306 296
307 if (index == INVALID_INDEX) { 297 if (index == INVALID_INDEX) {
@@ -341,7 +331,11 @@ void MiiManager::WriteToFile() {
341 } 331 }
342 332
343 save.Resize(sizeof(MiiDatabase)); 333 save.Resize(sizeof(MiiDatabase));
344 save.WriteBytes(&database, sizeof(MiiDatabase)); 334 if (save.WriteBytes(&database, sizeof(MiiDatabase)) != sizeof(MiiDatabase)) {
335 LOG_WARNING(Service_Mii, "Failed to write all data to save file... Data may be malformed "
336 "and/or regenerated on next run.");
337 save.Resize(0);
338 }
345} 339}
346 340
347void MiiManager::ReadFromFile() { 341void MiiManager::ReadFromFile() {
@@ -362,6 +356,20 @@ void MiiManager::ReadFromFile() {
362 return; 356 return;
363 } 357 }
364 358
359 EnsureDatabasePartition();
360}
361
362MiiStoreData MiiManager::CreateMiiWithUniqueUUID() const {
363 auto new_mii = DEFAULT_MII;
364
365 do {
366 new_mii.uuid = Common::UUID::Generate();
367 } while (IndexOf(new_mii.uuid) == INVALID_INDEX);
368
369 return new_mii;
370}
371
372void MiiManager::EnsureDatabasePartition() {
365 std::stable_partition(database.miis.begin(), database.miis.end(), 373 std::stable_partition(database.miis.begin(), database.miis.end(),
366 [](const MiiStoreData& elem) { return elem.uuid; }); 374 [](const MiiStoreData& elem) { return elem.uuid; });
367} 375}
diff --git a/src/core/hle/service/mii/mii_manager.h b/src/core/hle/service/mii/mii_manager.h
index 069247cb6..f7e3d2cf9 100644
--- a/src/core/hle/service/mii/mii_manager.h
+++ b/src/core/hle/service/mii/mii_manager.h
@@ -84,6 +84,8 @@ struct MiiInfo {
84 std::u16string Name() const; 84 std::u16string Name() const;
85}; 85};
86static_assert(sizeof(MiiInfo) == 0x58, "MiiInfo has incorrect size."); 86static_assert(sizeof(MiiInfo) == 0x58, "MiiInfo has incorrect size.");
87static_assert(std::has_unique_object_representations_v<MiiInfo>,
88 "All bits of MiiInfo must contribute to its value.");
87 89
88bool operator==(const MiiInfo& lhs, const MiiInfo& rhs); 90bool operator==(const MiiInfo& lhs, const MiiInfo& rhs);
89bool operator!=(const MiiInfo& lhs, const MiiInfo& rhs); 91bool operator!=(const MiiInfo& lhs, const MiiInfo& rhs);
@@ -238,15 +240,19 @@ public:
238 240
239 bool Remove(Common::UUID uuid); 241 bool Remove(Common::UUID uuid);
240 u32 IndexOf(Common::UUID uuid) const; 242 u32 IndexOf(Common::UUID uuid) const;
241 u32 IndexOf(MiiInfo info) const; 243 u32 IndexOf(const MiiInfo& info) const;
242 244
243 bool Move(Common::UUID uuid, u32 new_index); 245 bool Move(Common::UUID uuid, u32 new_index);
244 bool AddOrReplace(MiiStoreData data); 246 bool AddOrReplace(const MiiStoreData& data);
245 247
246private: 248private:
247 void WriteToFile(); 249 void WriteToFile();
248 void ReadFromFile(); 250 void ReadFromFile();
249 251
252 MiiStoreData CreateMiiWithUniqueUUID() const;
253
254 void EnsureDatabasePartition();
255
250 MiiDatabase database; 256 MiiDatabase database;
251}; 257};
252 258