mirror of
https://github.com/PabloMK7/citra.git
synced 2025-11-30 12:28:47 +00:00
Artic Base: Implement DLC support and other fixes (#173)
* Artic Base: Implement DLC support and other fixes * Fix per game settings not working with artic loader * Fix compilation error
This commit is contained in:
parent
1e2be72e5e
commit
4780a7134d
16 changed files with 992 additions and 236 deletions
File diff suppressed because it is too large
Load diff
|
|
@ -20,6 +20,7 @@
|
|||
#include "core/hle/kernel/mutex.h"
|
||||
#include "core/hle/result.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "network/artic_base/artic_base_client.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
|
|
@ -245,7 +246,13 @@ public:
|
|||
return am;
|
||||
}
|
||||
|
||||
void UseArticClient(std::shared_ptr<Network::ArticBase::Client>& client) {
|
||||
artic_client = client;
|
||||
}
|
||||
|
||||
protected:
|
||||
void GetProgramInfosImpl(Kernel::HLERequestContext& ctx, bool ignore_platform);
|
||||
|
||||
/**
|
||||
* AM::GetNumPrograms service function
|
||||
* Gets the number of installed titles in the requested media type
|
||||
|
|
@ -753,6 +760,9 @@ public:
|
|||
|
||||
protected:
|
||||
std::shared_ptr<Module> am;
|
||||
|
||||
// Placed on the interface level so that only am:net and am:app have it.
|
||||
std::shared_ptr<Network::ArticBase::Client> artic_client = nullptr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ void Module::Interface::GetTransferableId(Kernel::HLERequestContext& ctx) {
|
|||
|
||||
std::array<u8, 12> buffer;
|
||||
const Result result =
|
||||
cfg->GetConfigBlock(ConsoleUniqueID2BlockID, 8, AccessFlag::SystemRead, buffer.data());
|
||||
cfg->GetConfigBlock(ConsoleUniqueID2BlockID, 8, AccessFlag::Global, buffer.data());
|
||||
rb.Push(result);
|
||||
if (result.IsSuccess()) {
|
||||
std::memcpy(&buffer[8], &app_id_salt, sizeof(u32));
|
||||
|
|
@ -502,11 +502,42 @@ ResultVal<void*> Module::GetConfigBlockPointer(u32 block_id, u32 size, AccessFla
|
|||
}
|
||||
|
||||
Result Module::GetConfigBlock(u32 block_id, u32 size, AccessFlag accesss_flag, void* output) {
|
||||
void* pointer = nullptr;
|
||||
CASCADE_RESULT(pointer, GetConfigBlockPointer(block_id, size, accesss_flag));
|
||||
std::memcpy(output, pointer, size);
|
||||
bool get_from_artic =
|
||||
block_id == ConsoleUniqueID2BlockID &&
|
||||
(static_cast<u16>(accesss_flag) & static_cast<u16>(AccessFlag::UserRead)) != 0;
|
||||
|
||||
return ResultSuccess;
|
||||
if (get_from_artic && artic_client.get()) {
|
||||
auto req = artic_client->NewRequest("CFGU_GetConfigInfoBlk2");
|
||||
|
||||
req.AddParameterS32(block_id);
|
||||
req.AddParameterU32(size);
|
||||
|
||||
auto resp = artic_client->Send(req);
|
||||
|
||||
if (!resp.has_value() || !resp->Succeeded())
|
||||
return Result(-1);
|
||||
|
||||
auto res = Result(static_cast<u32>(resp->GetMethodResult()));
|
||||
if (res.IsError())
|
||||
return res;
|
||||
|
||||
auto buff = resp->GetResponseBuffer(0);
|
||||
if (!buff.has_value())
|
||||
return Result(-1);
|
||||
size_t actually_read = buff->second;
|
||||
if (actually_read > size)
|
||||
return Result(-1);
|
||||
|
||||
memcpy(output, buff->first, actually_read);
|
||||
return ResultSuccess;
|
||||
|
||||
} else {
|
||||
void* pointer = nullptr;
|
||||
CASCADE_RESULT(pointer, GetConfigBlockPointer(block_id, size, accesss_flag));
|
||||
std::memcpy(output, pointer, size);
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
Result Module::SetConfigBlock(u32 block_id, u32 size, AccessFlag accesss_flag, const void* input) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <utility>
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/service/service.h"
|
||||
#include "network/artic_base/artic_base_client.h"
|
||||
|
||||
namespace FileSys {
|
||||
class ArchiveBackend;
|
||||
|
|
@ -210,6 +211,10 @@ public:
|
|||
|
||||
std::shared_ptr<Module> GetModule() const;
|
||||
|
||||
void UseArticClient(std::shared_ptr<Network::ArticBase::Client>& client) {
|
||||
GetModule()->artic_client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* CFG::GetCountryCodeString service function
|
||||
* Inputs:
|
||||
|
|
@ -680,6 +685,8 @@ private:
|
|||
bool preferred_region_chosen = false;
|
||||
MCUData mcu_data{};
|
||||
|
||||
std::shared_ptr<Network::ArticBase::Client> artic_client = nullptr;
|
||||
|
||||
template <class Archive>
|
||||
void serialize(Archive& ar, const unsigned int);
|
||||
friend class boost::serialization::access;
|
||||
|
|
|
|||
|
|
@ -298,18 +298,22 @@ Result ArchiveManager::DeleteSystemSaveData(u32 high, u32 low) {
|
|||
return ResultSuccess;
|
||||
}
|
||||
|
||||
Result ArchiveManager::CreateSystemSaveData(u32 high, u32 low) {
|
||||
// Construct the binary path to the archive first
|
||||
const FileSys::Path path = FileSys::ConstructSystemSaveDataBinaryPath(high, low);
|
||||
Result ArchiveManager::CreateSystemSaveData(u32 high, u32 low, u32 total_size, u32 block_size,
|
||||
u32 number_directories, u32 number_files,
|
||||
u32 number_directory_buckets, u32 number_file_buckets,
|
||||
u8 duplicate_data) {
|
||||
|
||||
const std::string& nand_directory = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
|
||||
const std::string base_path = FileSys::GetSystemSaveDataContainerPath(nand_directory);
|
||||
const std::string systemsavedata_path = FileSys::GetSystemSaveDataPath(base_path, path);
|
||||
if (!FileUtil::CreateFullPath(systemsavedata_path)) {
|
||||
return ResultUnknown; // TODO(Subv): Find the right error code
|
||||
auto archive = id_code_map.find(ArchiveIdCode::SystemSaveData);
|
||||
|
||||
if (archive == id_code_map.end()) {
|
||||
return UnimplementedFunction(ErrorModule::FS); // TODO(Subv): Find the right error
|
||||
}
|
||||
|
||||
return ResultSuccess;
|
||||
auto sys_savedata = static_cast<FileSys::ArchiveFactory_SystemSaveData*>(archive->second.get());
|
||||
|
||||
return sys_savedata->FormatAsSysData(high, low, total_size, block_size, number_directories,
|
||||
number_files, number_directory_buckets,
|
||||
number_file_buckets, duplicate_data);
|
||||
}
|
||||
|
||||
ResultVal<ArchiveResource> ArchiveManager::GetArchiveResource(MediaType media_type) const {
|
||||
|
|
@ -454,6 +458,16 @@ void ArchiveManager::RegisterArticNCCH(std::shared_ptr<Network::ArticBase::Clien
|
|||
reinterpret_cast<FileSys::ArchiveFactory_NCCH*>(itr->second.get())->RegisterArtic(client);
|
||||
}
|
||||
|
||||
void ArchiveManager::RegisterArticSystemSaveData(
|
||||
std::shared_ptr<Network::ArticBase::Client>& client) {
|
||||
auto itr = id_code_map.find(ArchiveIdCode::SystemSaveData);
|
||||
if (itr == id_code_map.end() || itr->second.get() == nullptr) {
|
||||
return;
|
||||
}
|
||||
reinterpret_cast<FileSys::ArchiveFactory_SystemSaveData*>(itr->second.get())
|
||||
->RegisterArtic(client);
|
||||
}
|
||||
|
||||
ArchiveManager::ArchiveManager(Core::System& system) : system(system) {
|
||||
RegisterArchiveTypes();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -264,11 +264,12 @@ public:
|
|||
|
||||
/**
|
||||
* Creates the SystemSaveData archive folder for the specified save data id
|
||||
* @param high The high word of the SystemSaveData archive to create
|
||||
* @param low The low word of the SystemSaveData archive to create
|
||||
* @return Result 0 on success or the corresponding code on error
|
||||
*/
|
||||
Result CreateSystemSaveData(u32 high, u32 low);
|
||||
Result CreateSystemSaveData(u32 high, u32 low, u32 total_size, u32 block_size,
|
||||
u32 number_directories, u32 number_files,
|
||||
u32 number_directory_buckets, u32 number_file_buckets,
|
||||
u8 duplicate_data);
|
||||
|
||||
/**
|
||||
* Returns capacity and free space information about the given media type.
|
||||
|
|
@ -296,6 +297,8 @@ public:
|
|||
|
||||
void RegisterArticNCCH(std::shared_ptr<Network::ArticBase::Client>& client);
|
||||
|
||||
void RegisterArticSystemSaveData(std::shared_ptr<Network::ArticBase::Client>& client);
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
|
||||
|
|
|
|||
|
|
@ -1026,7 +1026,9 @@ void FS_USER::CreateSystemSaveData(Kernel::HLERequestContext& ctx) {
|
|||
file_buckets, duplicate);
|
||||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
rb.Push(archives.CreateSystemSaveData(savedata_high, savedata_low));
|
||||
rb.Push(archives.CreateSystemSaveData(savedata_high, savedata_low, total_size, block_size,
|
||||
directories, files, directory_buckets, file_buckets,
|
||||
duplicate ? 1 : 0));
|
||||
}
|
||||
|
||||
void FS_USER::CreateLegacySystemSaveData(Kernel::HLERequestContext& ctx) {
|
||||
|
|
@ -1048,7 +1050,8 @@ void FS_USER::CreateLegacySystemSaveData(Kernel::HLERequestContext& ctx) {
|
|||
|
||||
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
|
||||
// With this command, the SystemSaveData always has save_high = 0 (Always created in the NAND)
|
||||
rb.Push(archives.CreateSystemSaveData(0, savedata_id));
|
||||
rb.Push(archives.CreateSystemSaveData(0, savedata_id, total_size, block_size, directories,
|
||||
files, directory_buckets, file_buckets, duplicate));
|
||||
}
|
||||
|
||||
void FS_USER::InitializeWithSdkVersion(Kernel::HLERequestContext& ctx) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue