am: Implement GetSaveDataSize and ExtendSaveData
These functions come in a pair and are needed by Smash Ultimate, Minecraft, and Skyrim, amongst others.
This commit is contained in:
parent
2e6b67a079
commit
c643f364b4
|
@ -36,7 +36,7 @@ std::string LanguageEntry::GetDeveloperName() const {
|
||||||
developer_name.size());
|
developer_name.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
NACP::NACP() : raw{} {}
|
NACP::NACP() = default;
|
||||||
|
|
||||||
NACP::NACP(VirtualFile file) {
|
NACP::NACP(VirtualFile file) {
|
||||||
file->ReadObject(&raw);
|
file->ReadObject(&raw);
|
||||||
|
|
|
@ -100,7 +100,7 @@ public:
|
||||||
std::vector<u8> GetRawBytes() const;
|
std::vector<u8> GetRawBytes() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RawNACP raw;
|
RawNACP raw{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace FileSys {
|
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 {
|
std::string SaveDataDescriptor::DebugInfo() const {
|
||||||
return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}]",
|
return fmt::format("[type={:02X}, title_id={:016X}, user_id={:016X}{:016X}, save_id={:016X}]",
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include "audio_core/audio_renderer.h"
|
#include "audio_core/audio_renderer.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/file_sys/savedata_factory.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
|
@ -865,8 +866,8 @@ IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationF
|
||||||
{22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
|
{22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
|
||||||
{23, &IApplicationFunctions::GetDisplayVersion, "GetDisplayVersion"},
|
{23, &IApplicationFunctions::GetDisplayVersion, "GetDisplayVersion"},
|
||||||
{24, nullptr, "GetLaunchStorageInfoForDebug"},
|
{24, nullptr, "GetLaunchStorageInfoForDebug"},
|
||||||
{25, nullptr, "ExtendSaveData"},
|
{25, &IApplicationFunctions::ExtendSaveData, "ExtendSaveData"},
|
||||||
{26, nullptr, "GetSaveDataSize"},
|
{26, &IApplicationFunctions::GetSaveDataSize, "GetSaveDataSize"},
|
||||||
{30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"},
|
{30, &IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed, "BeginBlockingHomeButtonShortAndLongPressed"},
|
||||||
{31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
|
{31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
|
||||||
{32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
|
{32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
|
||||||
|
@ -1043,6 +1044,48 @@ void IApplicationFunctions::GetPseudoDeviceId(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push<u64>(0);
|
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,
|
void InstallInterfaces(SM::ServiceManager& service_manager,
|
||||||
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
|
std::shared_ptr<NVFlinger::NVFlinger> nvflinger) {
|
||||||
auto message_queue = std::make_shared<AppletMessageQueue>();
|
auto message_queue = std::make_shared<AppletMessageQueue>();
|
||||||
|
|
|
@ -206,6 +206,8 @@ private:
|
||||||
void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx);
|
void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx);
|
||||||
void NotifyRunning(Kernel::HLERequestContext& ctx);
|
void NotifyRunning(Kernel::HLERequestContext& ctx);
|
||||||
void GetPseudoDeviceId(Kernel::HLERequestContext& ctx);
|
void GetPseudoDeviceId(Kernel::HLERequestContext& ctx);
|
||||||
|
void ExtendSaveData(Kernel::HLERequestContext& ctx);
|
||||||
|
void GetSaveDataSize(Kernel::HLERequestContext& ctx);
|
||||||
void BeginBlockingHomeButtonShortAndLongPressed(Kernel::HLERequestContext& ctx);
|
void BeginBlockingHomeButtonShortAndLongPressed(Kernel::HLERequestContext& ctx);
|
||||||
void EndBlockingHomeButtonShortAndLongPressed(Kernel::HLERequestContext& ctx);
|
void EndBlockingHomeButtonShortAndLongPressed(Kernel::HLERequestContext& ctx);
|
||||||
void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx);
|
void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx);
|
||||||
|
|
|
@ -108,9 +108,9 @@ void ConfigurePerGameGeneral::loadConfiguration() {
|
||||||
if (loader->ReadTitle(title) == Loader::ResultStatus::Success)
|
if (loader->ReadTitle(title) == Loader::ResultStatus::Success)
|
||||||
ui->display_name->setText(QString::fromStdString(title));
|
ui->display_name->setText(QString::fromStdString(title));
|
||||||
|
|
||||||
std::string developer;
|
FileSys::NACP nacp;
|
||||||
if (loader->ReadDeveloper(developer) == Loader::ResultStatus::Success)
|
if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success)
|
||||||
ui->display_developer->setText(QString::fromStdString(developer));
|
ui->display_developer->setText(QString::fromStdString(nacp.GetDeveloperName()));
|
||||||
|
|
||||||
ui->display_version->setText(QStringLiteral("1.0.0"));
|
ui->display_version->setText(QStringLiteral("1.0.0"));
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue