From c643f364b4c81543782009ce4bb5a87021fe35ed Mon Sep 17 00:00:00 2001
From: Zach Hilman <zachhilman@gmail.com>
Date: Mon, 10 Dec 2018 22:17:45 -0500
Subject: [PATCH] am: Implement GetSaveDataSize and ExtendSaveData

These functions come in a pair and are needed by Smash Ultimate, Minecraft, and Skyrim, amongst others.
---
 src/core/file_sys/control_metadata.cpp        |  2 +-
 src/core/file_sys/control_metadata.h          |  2 +-
 src/core/file_sys/savedata_factory.cpp        |  2 +-
 src/core/hle/service/am/am.cpp                | 47 ++++++++++++++++++-
 src/core/hle/service/am/am.h                  |  2 +
 .../configuration/configure_per_general.cpp   |  6 +--
 6 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp
index 9624df054c..83c184750b 100644
--- a/src/core/file_sys/control_metadata.cpp
+++ b/src/core/file_sys/control_metadata.cpp
@@ -36,7 +36,7 @@ std::string LanguageEntry::GetDeveloperName() const {
                                                        developer_name.size());
 }
 
-NACP::NACP() : raw{} {}
+NACP::NACP() = default;
 
 NACP::NACP(VirtualFile file) {
     file->ReadObject(&raw);
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h
index 9bc2720c9b..7b9cdc9105 100644
--- a/src/core/file_sys/control_metadata.h
+++ b/src/core/file_sys/control_metadata.h
@@ -100,7 +100,7 @@ public:
     std::vector<u8> GetRawBytes() const;
 
 private:
-    RawNACP raw;
+    RawNACP raw{};
 };
 
 } // namespace FileSys
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp
index 54f5b698a3..1913dc956c 100644
--- a/src/core/file_sys/savedata_factory.cpp
+++ b/src/core/file_sys/savedata_factory.cpp
@@ -13,7 +13,7 @@
 
 namespace FileSys {
 
-constexpr const char* SAVE_DATA_SIZE_FILENAME = ".yuzu_save_size";
+constexpr char SAVE_DATA_SIZE_FILENAME[] = ".yuzu_save_size";
 
 std::string SaveDataDescriptor::DebugInfo() const {
     return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}]",
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 5fc02a5211..d13ce4dca2 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -8,6 +8,7 @@
 #include <stack>
 #include "audio_core/audio_renderer.h"
 #include "core/core.h"
+#include "core/file_sys/savedata_factory.h"
 #include "core/hle/ipc_helpers.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/process.h"
@@ -865,8 +866,8 @@ IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationF
         {22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
         {23, &IApplicationFunctions::GetDisplayVersion, "GetDisplayVersion"},
         {24, nullptr, "GetLaunchStorageInfoForDebug"},
-        {25, nullptr, "ExtendSaveData"},
-        {26, nullptr, "GetSaveDataSize"},
+        {25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"},
+        {26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"},
         {30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"},
         {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
         {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
@@ -1043,6 +1044,48 @@ void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
     rb.Push<u64>(0);
 }
 
+void IApplicationFunctions::ExtendSaveData(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto type{rp.PopRaw<FileSys::SaveDataType>()};
+    rp.Skip(1, false);
+    const auto user_id{rp.PopRaw<u128>()};
+    const auto new_normal_size{rp.PopRaw<u64>()};
+    const auto new_journal_size{rp.PopRaw<u64>()};
+
+    LOG_DEBUG(Service_AM,
+              "called with type={:02X}, user_id={:016X}{:016X}, new_normal={:016X}, "
+              "new_journal={:016X}",
+              static_cast<u8>(type), user_id[1], user_id[0], new_normal_size, new_journal_size);
+
+    FileSystem::WriteSaveDataSize(type, Core::CurrentProcess()->GetTitleID(), user_id,
+                                  {new_normal_size, new_journal_size});
+
+    IPC::ResponseBuilder rb{ctx, 4};
+    rb.Push(RESULT_SUCCESS);
+
+    // The following value is used upon failure to help the system recover.
+    // Since we always succeed, this should be 0.
+    rb.Push<u64>(0);
+}
+
+void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) {
+    IPC::RequestParser rp{ctx};
+    const auto type{rp.PopRaw<FileSys::SaveDataType>()};
+    rp.Skip(1, false);
+    const auto user_id{rp.PopRaw<u128>()};
+
+    LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", static_cast<u8>(type),
+              user_id[1], user_id[0]);
+
+    const auto size =
+        FileSystem::ReadSaveDataSize(type, Core::CurrentProcess()->GetTitleID(), user_id);
+
+    IPC::ResponseBuilder rb{ctx, 6};
+    rb.Push(RESULT_SUCCESS);
+    rb.Push(size.normal);
+    rb.Push(size.journal);
+}
+
 void InstallInterfaces(SM::ServiceManager& service_manager,
                        std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
     auto message_queue = std::make_shared<AppletMessageQueue>();
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index 34c45fadf0..b6113cfdd1 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -206,6 +206,8 @@ private:
     void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx);
     void NotifyRunning(Kernel::HLERequestContext& ctx);
     void GetPseudoDeviceId(Kernel::HLERequestContext& ctx);
+    void ExtendSaveData(Kernel::HLERequestContext& ctx);
+    void GetSaveDataSize(Kernel::HLERequestContext& ctx);
     void BeginBlockingHomeButtonShortAndLongPressed(Kernel::HLERequestContext& ctx);
     void EndBlockingHomeButtonShortAndLongPressed(Kernel::HLERequestContext& ctx);
     void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx);
diff --git a/src/yuzu/configuration/configure_per_general.cpp b/src/yuzu/configuration/configure_per_general.cpp
index 5ca493b6df..dffaba5ed2 100644
--- a/src/yuzu/configuration/configure_per_general.cpp
+++ b/src/yuzu/configuration/configure_per_general.cpp
@@ -108,9 +108,9 @@ void ConfigurePerGameGeneral::loadConfiguration() {
         if (loader->ReadTitle(title) == Loader::ResultStatus::Success)
             ui->display_name->setText(QString::fromStdString(title));
 
-        std::string developer;
-        if (loader->ReadDeveloper(developer) == Loader::ResultStatus::Success)
-            ui->display_developer->setText(QString::fromStdString(developer));
+        FileSys::NACP nacp;
+        if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success)
+            ui->display_developer->setText(QString::fromStdString(nacp.GetDeveloperName()));
 
         ui->display_version->setText(QStringLiteral("1.0.0"));
     }
-- 
GitLab