early-access version 1638

This commit is contained in:
pineappleEA 2021-04-28 05:28:56 +02:00
parent 50c03c71ee
commit 435ad5492f
23 changed files with 265 additions and 180 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 1637. This is the source code for early-access 1638.
## Legal Notice ## Legal Notice

View file

@ -77,10 +77,10 @@ void Controller_ConsoleSixAxis::OnLoadInputDevices() {
Input::CreateDevice<Input::MotionDevice>); Input::CreateDevice<Input::MotionDevice>);
} }
void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem_1) { void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem) {
is_transfer_memory_set = true; is_transfer_memory_set = true;
transfer_memory = t_mem_1; transfer_memory = t_mem;
}; }
void Controller_ConsoleSixAxis::ResetTimestamp() { void Controller_ConsoleSixAxis::ResetTimestamp() {
auto& cur_entry = seven_six_axis.sevensixaxis_states[seven_six_axis.header.last_entry_index]; auto& cur_entry = seven_six_axis.sevensixaxis_states[seven_six_axis.header.last_entry_index];

View file

@ -30,7 +30,7 @@ public:
void OnLoadInputDevices() override; void OnLoadInputDevices() override;
// Called on InitializeSevenSixAxisSensor // Called on InitializeSevenSixAxisSensor
void SetTransferMemoryPointer(u8* t_mem_1); void SetTransferMemoryPointer(u8* t_mem);
// Called on ResetSevenSixAxisSensorTimestamp // Called on ResetSevenSixAxisSensorTimestamp
void ResetTimestamp(); void ResetTimestamp();
@ -71,8 +71,8 @@ private:
using MotionArray = using MotionArray =
std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>; std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>;
u8* transfer_memory;
MotionArray motions; MotionArray motions;
u8* transfer_memory = nullptr;
bool is_transfer_memory_set = false; bool is_transfer_memory_set = false;
ConsoleSharedMemory console_six_axis{}; ConsoleSharedMemory console_six_axis{};
SevenSixAxisMemory seven_six_axis{}; SevenSixAxisMemory seven_six_axis{};

View file

@ -24,10 +24,10 @@ namespace Loader {
AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_, AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_,
bool override_update) bool override_update)
: AppLoader(std::move(file_)), override_update(override_update) { : AppLoader(std::move(file_)), override_update(override_update) {
const auto dir = file->GetContainingDirectory(); const auto file_dir = file->GetContainingDirectory();
// Title ID // Title ID
const auto npdm = dir->GetFile("main.npdm"); const auto npdm = file_dir->GetFile("main.npdm");
if (npdm != nullptr) { if (npdm != nullptr) {
const auto res = metadata.Load(npdm); const auto res = metadata.Load(npdm);
if (res == ResultStatus::Success) if (res == ResultStatus::Success)
@ -37,7 +37,7 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys
// Icon // Icon
FileSys::VirtualFile icon_file = nullptr; FileSys::VirtualFile icon_file = nullptr;
for (const auto& language : FileSys::LANGUAGE_NAMES) { for (const auto& language : FileSys::LANGUAGE_NAMES) {
icon_file = dir->GetFile("icon_" + std::string(language) + ".dat"); icon_file = file_dir->GetFile("icon_" + std::string(language) + ".dat");
if (icon_file != nullptr) { if (icon_file != nullptr) {
icon_data = icon_file->ReadAllBytes(); icon_data = icon_file->ReadAllBytes();
break; break;
@ -46,7 +46,7 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys
if (icon_data.empty()) { if (icon_data.empty()) {
// Any png, jpeg, or bmp file // Any png, jpeg, or bmp file
const auto& files = dir->GetFiles(); const auto& files = file_dir->GetFiles();
const auto icon_iter = const auto icon_iter =
std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) {
return file->GetExtension() == "png" || file->GetExtension() == "jpg" || return file->GetExtension() == "png" || file->GetExtension() == "jpg" ||
@ -57,9 +57,9 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys
} }
// Metadata // Metadata
FileSys::VirtualFile nacp_file = dir->GetFile("control.nacp"); FileSys::VirtualFile nacp_file = file_dir->GetFile("control.nacp");
if (nacp_file == nullptr) { if (nacp_file == nullptr) {
const auto& files = dir->GetFiles(); const auto& files = file_dir->GetFiles();
const auto nacp_iter = const auto nacp_iter =
std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) { std::find_if(files.begin(), files.end(), [](const FileSys::VirtualFile& file) {
return file->GetExtension() == "nacp"; return file->GetExtension() == "nacp";
@ -200,17 +200,21 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect
LoadParameters{metadata.GetMainThreadPriority(), metadata.GetMainThreadStackSize()}}; LoadParameters{metadata.GetMainThreadPriority(), metadata.GetMainThreadStackSize()}};
} }
ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& dir) { ResultStatus AppLoader_DeconstructedRomDirectory::ReadRomFS(FileSys::VirtualFile& out_dir) {
if (romfs == nullptr) if (romfs == nullptr) {
return ResultStatus::ErrorNoRomFS; return ResultStatus::ErrorNoRomFS;
dir = romfs; }
out_dir = romfs;
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& buffer) { ResultStatus AppLoader_DeconstructedRomDirectory::ReadIcon(std::vector<u8>& out_buffer) {
if (icon_data.empty()) if (icon_data.empty()) {
return ResultStatus::ErrorNoIcon; return ResultStatus::ErrorNoIcon;
buffer = icon_data; }
out_buffer = icon_data;
return ResultStatus::Success; return ResultStatus::Success;
} }
@ -219,10 +223,12 @@ ResultStatus AppLoader_DeconstructedRomDirectory::ReadProgramId(u64& out_program
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& title) { ResultStatus AppLoader_DeconstructedRomDirectory::ReadTitle(std::string& out_title) {
if (name.empty()) if (name.empty()) {
return ResultStatus::ErrorNoControl; return ResultStatus::ErrorNoControl;
title = name; }
out_title = name;
return ResultStatus::Success; return ResultStatus::Success;
} }
@ -230,12 +236,12 @@ bool AppLoader_DeconstructedRomDirectory::IsRomFSUpdatable() const {
return false; return false;
} }
ResultStatus AppLoader_DeconstructedRomDirectory::ReadNSOModules(Modules& modules) { ResultStatus AppLoader_DeconstructedRomDirectory::ReadNSOModules(Modules& out_modules) {
if (!is_loaded) { if (!is_loaded) {
return ResultStatus::ErrorNotInitialized; return ResultStatus::ErrorNotInitialized;
} }
modules = this->modules; out_modules = this->modules;
return ResultStatus::Success; return ResultStatus::Success;
} }

View file

@ -43,13 +43,13 @@ public:
LoadResult Load(Kernel::Process& process, Core::System& system) override; LoadResult Load(Kernel::Process& process, Core::System& system) override;
ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_dir) override;
ResultStatus ReadIcon(std::vector<u8>& buffer) override; ResultStatus ReadIcon(std::vector<u8>& out_buffer) override;
ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadProgramId(u64& out_program_id) override;
ResultStatus ReadTitle(std::string& title) override; ResultStatus ReadTitle(std::string& title) override;
bool IsRomFSUpdatable() const override; bool IsRomFSUpdatable() const override;
ResultStatus ReadNSOModules(Modules& modules) override; ResultStatus ReadNSOModules(Modules& out_modules) override;
private: private:
FileSys::ProgramMetadata metadata; FileSys::ProgramMetadata metadata;

View file

@ -364,21 +364,24 @@ SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const
namespace Loader { namespace Loader {
AppLoader_ELF::AppLoader_ELF(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} AppLoader_ELF::AppLoader_ELF(FileSys::VirtualFile file_) : AppLoader(std::move(file_)) {}
FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& file) { FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& elf_file) {
static constexpr u16 ELF_MACHINE_ARM{0x28}; static constexpr u16 ELF_MACHINE_ARM{0x28};
u32 magic = 0; u32 magic = 0;
if (4 != file->ReadObject(&magic)) if (4 != elf_file->ReadObject(&magic)) {
return FileType::Error; return FileType::Error;
}
u16 machine = 0; u16 machine = 0;
if (2 != file->ReadObject(&machine, 18)) if (2 != elf_file->ReadObject(&machine, 18)) {
return FileType::Error; return FileType::Error;
}
if (Common::MakeMagic('\x7f', 'E', 'L', 'F') == magic && ELF_MACHINE_ARM == machine) if (Common::MakeMagic('\x7f', 'E', 'L', 'F') == magic && ELF_MACHINE_ARM == machine) {
return FileType::ELF; return FileType::ELF;
}
return FileType::Error; return FileType::Error;
} }

View file

@ -20,11 +20,13 @@ public:
explicit AppLoader_ELF(FileSys::VirtualFile file); explicit AppLoader_ELF(FileSys::VirtualFile file);
/** /**
* Returns the type of the file * Identifies whether or not the given file is an ELF file.
* @param file open file *
* @return FileType found, or FileType::Error if this loader doesn't know it * @param elf_file The file to identify.
*
* @return FileType::ELF, or FileType::Error if the file is not an ELF file.
*/ */
static FileType IdentifyType(const FileSys::VirtualFile& file); static FileType IdentifyType(const FileSys::VirtualFile& elf_file);
FileType GetFileType() const override { FileType GetFileType() const override {
return IdentifyType(file); return IdentifyType(file);

View file

@ -24,9 +24,9 @@ AppLoader_KIP::AppLoader_KIP(FileSys::VirtualFile file_)
AppLoader_KIP::~AppLoader_KIP() = default; AppLoader_KIP::~AppLoader_KIP() = default;
FileType AppLoader_KIP::IdentifyType(const FileSys::VirtualFile& file) { FileType AppLoader_KIP::IdentifyType(const FileSys::VirtualFile& in_file) {
u32_le magic{}; u32_le magic{};
if (file->GetSize() < sizeof(u32) || file->ReadObject(&magic) != sizeof(u32)) { if (in_file->GetSize() < sizeof(u32) || in_file->ReadObject(&magic) != sizeof(u32)) {
return FileType::Error; return FileType::Error;
} }
@ -56,10 +56,10 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process,
return {kip->GetStatus(), {}}; return {kip->GetStatus(), {}};
} }
const auto get_kip_address_space_type = [](const auto& kip) { const auto get_kip_address_space_type = [](const auto& kip_type) {
return kip.Is64Bit() return kip_type.Is64Bit()
? (kip.Is39BitAddressSpace() ? FileSys::ProgramAddressSpaceType::Is39Bit ? (kip_type.Is39BitAddressSpace() ? FileSys::ProgramAddressSpaceType::Is39Bit
: FileSys::ProgramAddressSpaceType::Is36Bit) : FileSys::ProgramAddressSpaceType::Is36Bit)
: FileSys::ProgramAddressSpaceType::Is32Bit; : FileSys::ProgramAddressSpaceType::Is32Bit;
}; };

View file

@ -22,11 +22,13 @@ public:
~AppLoader_KIP() override; ~AppLoader_KIP() override;
/** /**
* Returns the type of the file * Identifies whether or not the given file is a KIP.
* @param file open file *
* @return FileType found, or FileType::Error if this loader doesn't know it * @param in_file The file to identify.
*
* @return FileType::KIP if found, or FileType::Error if unknown.
*/ */
static FileType IdentifyType(const FileSys::VirtualFile& file); static FileType IdentifyType(const FileSys::VirtualFile& in_file);
FileType GetFileType() const override; FileType GetFileType() const override;

View file

@ -152,21 +152,26 @@ public:
/** /**
* Returns the type of this file * Returns the type of this file
*
* @return FileType corresponding to the loaded file * @return FileType corresponding to the loaded file
*/ */
virtual FileType GetFileType() const = 0; virtual FileType GetFileType() const = 0;
/** /**
* Load the application and return the created Process instance * Load the application and return the created Process instance
*
* @param process The newly created process. * @param process The newly created process.
* @param system The system that this process is being loaded under. * @param system The system that this process is being loaded under.
*
* @return The status result of the operation. * @return The status result of the operation.
*/ */
virtual LoadResult Load(Kernel::Process& process, Core::System& system) = 0; virtual LoadResult Load(Kernel::Process& process, Core::System& system) = 0;
/** /**
* Get the code (typically .code section) of the application * Get the code (typically .code section) of the application
* @param buffer Reference to buffer to store data *
* @param[out] buffer Reference to buffer to store data
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadCode(std::vector<u8>& buffer) { virtual ResultStatus ReadCode(std::vector<u8>& buffer) {
@ -175,7 +180,9 @@ public:
/** /**
* Get the icon (typically icon section) of the application * Get the icon (typically icon section) of the application
* @param buffer Reference to buffer to store data *
* @param[out] buffer Reference to buffer to store data
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadIcon(std::vector<u8>& buffer) { virtual ResultStatus ReadIcon(std::vector<u8>& buffer) {
@ -186,7 +193,9 @@ public:
* Get the banner (typically banner section) of the application * Get the banner (typically banner section) of the application
* In the context of NX, this is the animation that displays in the bottom right of the screen * In the context of NX, this is the animation that displays in the bottom right of the screen
* when a game boots. Stored in GIF format. * when a game boots. Stored in GIF format.
* @param buffer Reference to buffer to store data *
* @param[out] buffer Reference to buffer to store data
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadBanner(std::vector<u8>& buffer) { virtual ResultStatus ReadBanner(std::vector<u8>& buffer) {
@ -197,7 +206,9 @@ public:
* Get the logo (typically logo section) of the application * Get the logo (typically logo section) of the application
* In the context of NX, this is the static image that displays in the top left of the screen * In the context of NX, this is the static image that displays in the top left of the screen
* when a game boots. Stored in JPEG format. * when a game boots. Stored in JPEG format.
* @param buffer Reference to buffer to store data *
* @param[out] buffer Reference to buffer to store data
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadLogo(std::vector<u8>& buffer) { virtual ResultStatus ReadLogo(std::vector<u8>& buffer) {
@ -206,7 +217,9 @@ public:
/** /**
* Get the program id of the application * Get the program id of the application
* @param out_program_id Reference to store program id into *
* @param[out] out_program_id Reference to store program id into
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadProgramId(u64& out_program_id) { virtual ResultStatus ReadProgramId(u64& out_program_id) {
@ -216,19 +229,23 @@ public:
/** /**
* Get the RomFS of the application * Get the RomFS of the application
* Since the RomFS can be huge, we return a file reference instead of copying to a buffer * Since the RomFS can be huge, we return a file reference instead of copying to a buffer
* @param file The directory containing the RomFS *
* @param[out] out_file The directory containing the RomFS
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadRomFS(FileSys::VirtualFile& file) { virtual ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) {
return ResultStatus::ErrorNotImplemented; return ResultStatus::ErrorNotImplemented;
} }
/** /**
* Get the raw update of the application, should it come packed with one * Get the raw update of the application, should it come packed with one
* @param file The raw update NCA file (Program-type *
* @param[out] out_file The raw update NCA file (Program-type)
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadUpdateRaw(FileSys::VirtualFile& file) { virtual ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) {
return ResultStatus::ErrorNotImplemented; return ResultStatus::ErrorNotImplemented;
} }
@ -236,7 +253,8 @@ public:
* Get whether or not updates can be applied to the RomFS. * Get whether or not updates can be applied to the RomFS.
* By default, this is true, however for formats where it cannot be guaranteed that the RomFS is * By default, this is true, however for formats where it cannot be guaranteed that the RomFS is
* the base game it should be set to false. * the base game it should be set to false.
* @return bool whether or not updatable. *
* @return bool indicating whether or not the RomFS is updatable.
*/ */
virtual bool IsRomFSUpdatable() const { virtual bool IsRomFSUpdatable() const {
return true; return true;
@ -244,8 +262,9 @@ public:
/** /**
* Gets the difference between the start of the IVFC header and the start of level 6 (RomFS) * Gets the difference between the start of the IVFC header and the start of level 6 (RomFS)
* data. Needed for bktr patching. * data. Needed for BKTR patching.
* @return IVFC offset for romfs. *
* @return IVFC offset for RomFS.
*/ */
virtual u64 ReadRomFSIVFCOffset() const { virtual u64 ReadRomFSIVFCOffset() const {
return 0; return 0;
@ -253,7 +272,9 @@ public:
/** /**
* Get the title of the application * Get the title of the application
* @param title Reference to store the application title into *
* @param[out] title Reference to store the application title into
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadTitle(std::string& title) { virtual ResultStatus ReadTitle(std::string& title) {
@ -262,7 +283,9 @@ public:
/** /**
* Get the control data (CNMT) of the application * Get the control data (CNMT) of the application
* @param control Reference to store the application control data into *
* @param[out] control Reference to store the application control data into
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadControlData(FileSys::NACP& control) { virtual ResultStatus ReadControlData(FileSys::NACP& control) {
@ -271,10 +294,12 @@ public:
/** /**
* Get the RomFS of the manual of the application * Get the RomFS of the manual of the application
* @param file The raw manual RomFS of the game *
* @param[out] out_file The raw manual RomFS of the game
*
* @return ResultStatus result of function * @return ResultStatus result of function
*/ */
virtual ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) { virtual ResultStatus ReadManualRomFS(FileSys::VirtualFile& out_file) {
return ResultStatus::ErrorNotImplemented; return ResultStatus::ErrorNotImplemented;
} }

View file

@ -26,14 +26,14 @@ FileType IdentifyTypeImpl(const FileSys::NAX& nax) {
} }
} // Anonymous namespace } // Anonymous namespace
AppLoader_NAX::AppLoader_NAX(FileSys::VirtualFile file) AppLoader_NAX::AppLoader_NAX(FileSys::VirtualFile file_)
: AppLoader(file), nax(std::make_unique<FileSys::NAX>(file)), : AppLoader(file_), nax(std::make_unique<FileSys::NAX>(file_)),
nca_loader(std::make_unique<AppLoader_NCA>(nax->GetDecrypted())) {} nca_loader(std::make_unique<AppLoader_NCA>(nax->GetDecrypted())) {}
AppLoader_NAX::~AppLoader_NAX() = default; AppLoader_NAX::~AppLoader_NAX() = default;
FileType AppLoader_NAX::IdentifyType(const FileSys::VirtualFile& file) { FileType AppLoader_NAX::IdentifyType(const FileSys::VirtualFile& nax_file) {
const FileSys::NAX nax(file); const FileSys::NAX nax(nax_file);
return IdentifyTypeImpl(nax); return IdentifyTypeImpl(nax);
} }
@ -41,8 +41,7 @@ FileType AppLoader_NAX::GetFileType() const {
return IdentifyTypeImpl(*nax); return IdentifyTypeImpl(*nax);
} }
AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::Process& process, AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::Process& process, Core::System& system) {
[[maybe_unused]] Core::System& system) {
if (is_loaded) { if (is_loaded) {
return {ResultStatus::ErrorAlreadyLoaded, {}}; return {ResultStatus::ErrorAlreadyLoaded, {}};
} }

View file

@ -23,15 +23,17 @@ class AppLoader_NCA;
/// Loads a NAX file /// Loads a NAX file
class AppLoader_NAX final : public AppLoader { class AppLoader_NAX final : public AppLoader {
public: public:
explicit AppLoader_NAX(FileSys::VirtualFile file); explicit AppLoader_NAX(FileSys::VirtualFile file_);
~AppLoader_NAX() override; ~AppLoader_NAX() override;
/** /**
* Returns the type of the file * Identifies whether or not the given file is a NAX file.
* @param file open file *
* @return FileType found, or FileType::Error if this loader doesn't know it * @param nax_file The file to identify.
*
* @return FileType::NAX, or FileType::Error if the file is not a NAX file.
*/ */
static FileType IdentifyType(const FileSys::VirtualFile& file); static FileType IdentifyType(const FileSys::VirtualFile& nax_file);
FileType GetFileType() const override; FileType GetFileType() const override;

View file

@ -21,12 +21,13 @@ AppLoader_NCA::AppLoader_NCA(FileSys::VirtualFile file_)
AppLoader_NCA::~AppLoader_NCA() = default; AppLoader_NCA::~AppLoader_NCA() = default;
FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& file) { FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& nca_file) {
FileSys::NCA nca(file); const FileSys::NCA nca(nca_file);
if (nca.GetStatus() == ResultStatus::Success && if (nca.GetStatus() == ResultStatus::Success &&
nca.GetType() == FileSys::NCAContentType::Program) nca.GetType() == FileSys::NCAContentType::Program) {
return FileType::NCA; return FileType::NCA;
}
return FileType::Error; return FileType::Error;
} }
@ -67,43 +68,59 @@ AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::Process& process, Core::Sy
} }
ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) { ResultStatus AppLoader_NCA::ReadRomFS(FileSys::VirtualFile& dir) {
if (nca == nullptr) if (nca == nullptr) {
return ResultStatus::ErrorNotInitialized; return ResultStatus::ErrorNotInitialized;
if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) }
if (nca->GetRomFS() == nullptr || nca->GetRomFS()->GetSize() == 0) {
return ResultStatus::ErrorNoRomFS; return ResultStatus::ErrorNoRomFS;
}
dir = nca->GetRomFS(); dir = nca->GetRomFS();
return ResultStatus::Success; return ResultStatus::Success;
} }
u64 AppLoader_NCA::ReadRomFSIVFCOffset() const { u64 AppLoader_NCA::ReadRomFSIVFCOffset() const {
if (nca == nullptr) if (nca == nullptr) {
return 0; return 0;
}
return nca->GetBaseIVFCOffset(); return nca->GetBaseIVFCOffset();
} }
ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) {
if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) {
return ResultStatus::ErrorNotInitialized; return ResultStatus::ErrorNotInitialized;
}
out_program_id = nca->GetTitleId(); out_program_id = nca->GetTitleId();
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_NCA::ReadBanner(std::vector<u8>& buffer) { ResultStatus AppLoader_NCA::ReadBanner(std::vector<u8>& buffer) {
if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) {
return ResultStatus::ErrorNotInitialized; return ResultStatus::ErrorNotInitialized;
}
const auto logo = nca->GetLogoPartition(); const auto logo = nca->GetLogoPartition();
if (logo == nullptr) if (logo == nullptr) {
return ResultStatus::ErrorNoIcon; return ResultStatus::ErrorNoIcon;
}
buffer = logo->GetFile("StartupMovie.gif")->ReadAllBytes(); buffer = logo->GetFile("StartupMovie.gif")->ReadAllBytes();
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_NCA::ReadLogo(std::vector<u8>& buffer) { ResultStatus AppLoader_NCA::ReadLogo(std::vector<u8>& buffer) {
if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) {
return ResultStatus::ErrorNotInitialized; return ResultStatus::ErrorNotInitialized;
}
const auto logo = nca->GetLogoPartition(); const auto logo = nca->GetLogoPartition();
if (logo == nullptr) if (logo == nullptr) {
return ResultStatus::ErrorNoIcon; return ResultStatus::ErrorNoIcon;
}
buffer = logo->GetFile("NintendoLogo.png")->ReadAllBytes(); buffer = logo->GetFile("NintendoLogo.png")->ReadAllBytes();
return ResultStatus::Success; return ResultStatus::Success;
} }

View file

@ -23,15 +23,17 @@ class AppLoader_DeconstructedRomDirectory;
/// Loads an NCA file /// Loads an NCA file
class AppLoader_NCA final : public AppLoader { class AppLoader_NCA final : public AppLoader {
public: public:
explicit AppLoader_NCA(FileSys::VirtualFile file); explicit AppLoader_NCA(FileSys::VirtualFile file_);
~AppLoader_NCA() override; ~AppLoader_NCA() override;
/** /**
* Returns the type of the file * Identifies whether or not the given file is an NCA file.
* @param file open file *
* @return FileType found, or FileType::Error if this loader doesn't know it * @param nca_file The file to identify.
*
* @return FileType::NCA, or FileType::Error if the file is not an NCA file.
*/ */
static FileType IdentifyType(const FileSys::VirtualFile& file); static FileType IdentifyType(const FileSys::VirtualFile& nca_file);
FileType GetFileType() const override { FileType GetFileType() const override {
return IdentifyType(file); return IdentifyType(file);

View file

@ -72,7 +72,7 @@ struct AssetHeader {
}; };
static_assert(sizeof(AssetHeader) == 0x38, "AssetHeader has incorrect size."); static_assert(sizeof(AssetHeader) == 0x38, "AssetHeader has incorrect size.");
AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file) : AppLoader(file) { AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file_) : AppLoader(std::move(file_)) {
NroHeader nro_header{}; NroHeader nro_header{};
if (file->ReadObject(&nro_header) != sizeof(NroHeader)) { if (file->ReadObject(&nro_header) != sizeof(NroHeader)) {
return; return;
@ -114,10 +114,10 @@ AppLoader_NRO::AppLoader_NRO(FileSys::VirtualFile file) : AppLoader(file) {
AppLoader_NRO::~AppLoader_NRO() = default; AppLoader_NRO::~AppLoader_NRO() = default;
FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& file) { FileType AppLoader_NRO::IdentifyType(const FileSys::VirtualFile& nro_file) {
// Read NSO header // Read NSO header
NroHeader nro_header{}; NroHeader nro_header{};
if (sizeof(NroHeader) != file->ReadObject(&nro_header)) { if (sizeof(NroHeader) != nro_file->ReadObject(&nro_header)) {
return FileType::Error; return FileType::Error;
} }
if (nro_header.magic == Common::MakeMagic('N', 'R', 'O', '0')) { if (nro_header.magic == Common::MakeMagic('N', 'R', 'O', '0')) {
@ -130,8 +130,7 @@ static constexpr u32 PageAlignSize(u32 size) {
return static_cast<u32>((size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK); return static_cast<u32>((size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK);
} }
static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data, static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data) {
const std::string& name) {
if (data.size() < sizeof(NroHeader)) { if (data.size() < sizeof(NroHeader)) {
return {}; return {};
} }
@ -200,8 +199,8 @@ static bool LoadNroImpl(Kernel::Process& process, const std::vector<u8>& data,
return true; return true;
} }
bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& file) { bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& nro_file) {
return LoadNroImpl(process, file.ReadAllBytes(), file.GetName()); return LoadNroImpl(process, nro_file.ReadAllBytes());
} }
AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::Process& process, Core::System& system) { AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::Process& process, Core::System& system) {

View file

@ -27,15 +27,17 @@ namespace Loader {
/// Loads an NRO file /// Loads an NRO file
class AppLoader_NRO final : public AppLoader { class AppLoader_NRO final : public AppLoader {
public: public:
explicit AppLoader_NRO(FileSys::VirtualFile file); explicit AppLoader_NRO(FileSys::VirtualFile file_);
~AppLoader_NRO() override; ~AppLoader_NRO() override;
/** /**
* Returns the type of the file * Identifies whether or not the given file is an NRO file.
* @param file open file *
* @return FileType found, or FileType::Error if this loader doesn't know it * @param nro_file The file to identify.
*
* @return FileType::NRO, or FileType::Error if the file is not an NRO file.
*/ */
static FileType IdentifyType(const FileSys::VirtualFile& file); static FileType IdentifyType(const FileSys::VirtualFile& nro_file);
FileType GetFileType() const override { FileType GetFileType() const override {
return IdentifyType(file); return IdentifyType(file);
@ -51,7 +53,7 @@ public:
bool IsRomFSUpdatable() const override; bool IsRomFSUpdatable() const override;
private: private:
bool LoadNro(Kernel::Process& process, const FileSys::VfsFile& file); bool LoadNro(Kernel::Process& process, const FileSys::VfsFile& nro_file);
std::vector<u8> icon_data; std::vector<u8> icon_data;
std::unique_ptr<FileSys::NACP> nacp; std::unique_ptr<FileSys::NACP> nacp;

View file

@ -56,11 +56,11 @@ bool NSOHeader::IsSegmentCompressed(size_t segment_num) const {
return ((flags >> segment_num) & 1) != 0; return ((flags >> segment_num) & 1) != 0;
} }
AppLoader_NSO::AppLoader_NSO(FileSys::VirtualFile file) : AppLoader(std::move(file)) {} AppLoader_NSO::AppLoader_NSO(FileSys::VirtualFile file_) : AppLoader(std::move(file_)) {}
FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& file) { FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& in_file) {
u32 magic = 0; u32 magic = 0;
if (file->ReadObject(&magic) != sizeof(magic)) { if (in_file->ReadObject(&magic) != sizeof(magic)) {
return FileType::Error; return FileType::Error;
} }
@ -72,15 +72,15 @@ FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& file) {
} }
std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::System& system, std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::System& system,
const FileSys::VfsFile& file, VAddr load_base, const FileSys::VfsFile& nso_file, VAddr load_base,
bool should_pass_arguments, bool load_into_process, bool should_pass_arguments, bool load_into_process,
std::optional<FileSys::PatchManager> pm) { std::optional<FileSys::PatchManager> pm) {
if (file.GetSize() < sizeof(NSOHeader)) { if (nso_file.GetSize() < sizeof(NSOHeader)) {
return std::nullopt; return std::nullopt;
} }
NSOHeader nso_header{}; NSOHeader nso_header{};
if (sizeof(NSOHeader) != file.ReadObject(&nso_header)) { if (sizeof(NSOHeader) != nso_file.ReadObject(&nso_header)) {
return std::nullopt; return std::nullopt;
} }
@ -92,8 +92,8 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::S
Kernel::CodeSet codeset; Kernel::CodeSet codeset;
Kernel::PhysicalMemory program_image; Kernel::PhysicalMemory program_image;
for (std::size_t i = 0; i < nso_header.segments.size(); ++i) { for (std::size_t i = 0; i < nso_header.segments.size(); ++i) {
std::vector<u8> data = std::vector<u8> data = nso_file.ReadBytes(nso_header.segments_compressed_size[i],
file.ReadBytes(nso_header.segments_compressed_size[i], nso_header.segments[i].offset); nso_header.segments[i].offset);
if (nso_header.IsSegmentCompressed(i)) { if (nso_header.IsSegmentCompressed(i)) {
data = DecompressSegment(data, nso_header.segments[i]); data = DecompressSegment(data, nso_header.segments[i]);
} }
@ -136,7 +136,7 @@ std::optional<VAddr> AppLoader_NSO::LoadModule(Kernel::Process& process, Core::S
pi_header.insert(pi_header.begin() + sizeof(NSOHeader), program_image.data(), pi_header.insert(pi_header.begin() + sizeof(NSOHeader), program_image.data(),
program_image.data() + program_image.size()); program_image.data() + program_image.size());
pi_header = pm->PatchNSO(pi_header, file.GetName()); pi_header = pm->PatchNSO(pi_header, nso_file.GetName());
std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.data()); std::copy(pi_header.begin() + sizeof(NSOHeader), pi_header.end(), program_image.data());
} }
@ -183,8 +183,8 @@ AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::Process& process, Core::Sy
Core::Memory::DEFAULT_STACK_SIZE}}; Core::Memory::DEFAULT_STACK_SIZE}};
} }
ResultStatus AppLoader_NSO::ReadNSOModules(Modules& modules) { ResultStatus AppLoader_NSO::ReadNSOModules(Modules& out_modules) {
modules = this->modules; out_modules = this->modules;
return ResultStatus::Success; return ResultStatus::Success;
} }

View file

@ -71,27 +71,29 @@ static_assert(sizeof(NSOArgumentHeader) == 0x20, "NSOArgumentHeader has incorrec
/// Loads an NSO file /// Loads an NSO file
class AppLoader_NSO final : public AppLoader { class AppLoader_NSO final : public AppLoader {
public: public:
explicit AppLoader_NSO(FileSys::VirtualFile file); explicit AppLoader_NSO(FileSys::VirtualFile file_);
/** /**
* Returns the type of the file * Identifies whether or not the given file is a form of NSO file.
* @param file open file *
* @return FileType found, or FileType::Error if this loader doesn't know it * @param in_file The file to be identified.
*
* @return FileType::NSO if found, or FileType::Error if some other type of file.
*/ */
static FileType IdentifyType(const FileSys::VirtualFile& file); static FileType IdentifyType(const FileSys::VirtualFile& in_file);
FileType GetFileType() const override { FileType GetFileType() const override {
return IdentifyType(file); return IdentifyType(file);
} }
static std::optional<VAddr> LoadModule(Kernel::Process& process, Core::System& system, static std::optional<VAddr> LoadModule(Kernel::Process& process, Core::System& system,
const FileSys::VfsFile& file, VAddr load_base, const FileSys::VfsFile& nso_file, VAddr load_base,
bool should_pass_arguments, bool load_into_process, bool should_pass_arguments, bool load_into_process,
std::optional<FileSys::PatchManager> pm = {}); std::optional<FileSys::PatchManager> pm = {});
LoadResult Load(Kernel::Process& process, Core::System& system) override; LoadResult Load(Kernel::Process& process, Core::System& system) override;
ResultStatus ReadNSOModules(Modules& modules) override; ResultStatus ReadNSOModules(Modules& out_modules) override;
private: private:
Modules modules; Modules modules;

View file

@ -21,11 +21,11 @@
namespace Loader { namespace Loader {
AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file, AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file_,
const Service::FileSystem::FileSystemController& fsc, const Service::FileSystem::FileSystemController& fsc,
const FileSys::ContentProvider& content_provider, const FileSys::ContentProvider& content_provider,
std::size_t program_index) std::size_t program_index)
: AppLoader(file), nsp(std::make_unique<FileSys::NSP>(file, program_index)), : AppLoader(file_), nsp(std::make_unique<FileSys::NSP>(file_, program_index)),
title_id(nsp->GetProgramTitleID()) { title_id(nsp->GetProgramTitleID()) {
if (nsp->GetStatus() != ResultStatus::Success) { if (nsp->GetStatus() != ResultStatus::Success) {
@ -57,8 +57,8 @@ AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file,
AppLoader_NSP::~AppLoader_NSP() = default; AppLoader_NSP::~AppLoader_NSP() = default;
FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& file) { FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& nsp_file) {
FileSys::NSP nsp(file); const FileSys::NSP nsp(nsp_file);
if (nsp.GetStatus() == ResultStatus::Success) { if (nsp.GetStatus() == ResultStatus::Success) {
// Extracted Type case // Extracted Type case
@ -121,67 +121,80 @@ AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::Process& process, Core::Sy
return result; return result;
} }
ResultStatus AppLoader_NSP::ReadRomFS(FileSys::VirtualFile& file) { ResultStatus AppLoader_NSP::ReadRomFS(FileSys::VirtualFile& out_file) {
return secondary_loader->ReadRomFS(file); return secondary_loader->ReadRomFS(out_file);
} }
u64 AppLoader_NSP::ReadRomFSIVFCOffset() const { u64 AppLoader_NSP::ReadRomFSIVFCOffset() const {
return secondary_loader->ReadRomFSIVFCOffset(); return secondary_loader->ReadRomFSIVFCOffset();
} }
ResultStatus AppLoader_NSP::ReadUpdateRaw(FileSys::VirtualFile& file) { ResultStatus AppLoader_NSP::ReadUpdateRaw(FileSys::VirtualFile& out_file) {
if (nsp->IsExtractedType()) if (nsp->IsExtractedType()) {
return ResultStatus::ErrorNoPackedUpdate; return ResultStatus::ErrorNoPackedUpdate;
}
const auto read = const auto read =
nsp->GetNCAFile(FileSys::GetUpdateTitleID(title_id), FileSys::ContentRecordType::Program); nsp->GetNCAFile(FileSys::GetUpdateTitleID(title_id), FileSys::ContentRecordType::Program);
if (read == nullptr) if (read == nullptr) {
return ResultStatus::ErrorNoPackedUpdate; return ResultStatus::ErrorNoPackedUpdate;
}
const auto nca_test = std::make_shared<FileSys::NCA>(read); const auto nca_test = std::make_shared<FileSys::NCA>(read);
if (nca_test->GetStatus() != ResultStatus::ErrorMissingBKTRBaseRomFS) {
if (nca_test->GetStatus() != ResultStatus::ErrorMissingBKTRBaseRomFS)
return nca_test->GetStatus(); return nca_test->GetStatus();
}
file = read; out_file = read;
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_NSP::ReadProgramId(u64& out_program_id) { ResultStatus AppLoader_NSP::ReadProgramId(u64& out_program_id) {
if (title_id == 0) if (title_id == 0) {
return ResultStatus::ErrorNotInitialized; return ResultStatus::ErrorNotInitialized;
}
out_program_id = title_id; out_program_id = title_id;
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_NSP::ReadIcon(std::vector<u8>& buffer) { ResultStatus AppLoader_NSP::ReadIcon(std::vector<u8>& buffer) {
if (icon_file == nullptr) if (icon_file == nullptr) {
return ResultStatus::ErrorNoControl; return ResultStatus::ErrorNoControl;
}
buffer = icon_file->ReadAllBytes(); buffer = icon_file->ReadAllBytes();
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_NSP::ReadTitle(std::string& title) { ResultStatus AppLoader_NSP::ReadTitle(std::string& title) {
if (nacp_file == nullptr) if (nacp_file == nullptr) {
return ResultStatus::ErrorNoControl; return ResultStatus::ErrorNoControl;
}
title = nacp_file->GetApplicationName(); title = nacp_file->GetApplicationName();
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_NSP::ReadControlData(FileSys::NACP& nacp) { ResultStatus AppLoader_NSP::ReadControlData(FileSys::NACP& nacp) {
if (nacp_file == nullptr) if (nacp_file == nullptr) {
return ResultStatus::ErrorNoControl; return ResultStatus::ErrorNoControl;
}
nacp = *nacp_file; nacp = *nacp_file;
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_NSP::ReadManualRomFS(FileSys::VirtualFile& file) { ResultStatus AppLoader_NSP::ReadManualRomFS(FileSys::VirtualFile& out_file) {
const auto nca = const auto nca =
nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::HtmlDocument); nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::HtmlDocument);
if (nsp->GetStatus() != ResultStatus::Success || nca == nullptr) if (nsp->GetStatus() != ResultStatus::Success || nca == nullptr) {
return ResultStatus::ErrorNoRomFS; return ResultStatus::ErrorNoRomFS;
file = nca->GetRomFS(); }
return file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success;
out_file = nca->GetRomFS();
return out_file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success;
} }
ResultStatus AppLoader_NSP::ReadBanner(std::vector<u8>& buffer) { ResultStatus AppLoader_NSP::ReadBanner(std::vector<u8>& buffer) {

View file

@ -26,18 +26,20 @@ class AppLoader_NCA;
/// Loads an XCI file /// Loads an XCI file
class AppLoader_NSP final : public AppLoader { class AppLoader_NSP final : public AppLoader {
public: public:
explicit AppLoader_NSP(FileSys::VirtualFile file, explicit AppLoader_NSP(FileSys::VirtualFile file_,
const Service::FileSystem::FileSystemController& fsc, const Service::FileSystem::FileSystemController& fsc,
const FileSys::ContentProvider& content_provider, const FileSys::ContentProvider& content_provider,
std::size_t program_index); std::size_t program_index);
~AppLoader_NSP() override; ~AppLoader_NSP() override;
/** /**
* Returns the type of the file * Identifies whether or not the given file is an NSP file.
* @param file open file *
* @return FileType found, or FileType::Error if this loader doesn't know it * @param nsp_file The file to identify.
*
* @return FileType::NSP, or FileType::Error if the file is not an NSP.
*/ */
static FileType IdentifyType(const FileSys::VirtualFile& file); static FileType IdentifyType(const FileSys::VirtualFile& nsp_file);
FileType GetFileType() const override { FileType GetFileType() const override {
return IdentifyType(file); return IdentifyType(file);
@ -45,14 +47,14 @@ public:
LoadResult Load(Kernel::Process& process, Core::System& system) override; LoadResult Load(Kernel::Process& process, Core::System& system) override;
ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override;
u64 ReadRomFSIVFCOffset() const override; u64 ReadRomFSIVFCOffset() const override;
ResultStatus ReadUpdateRaw(FileSys::VirtualFile& file) override; ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override;
ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadProgramId(u64& out_program_id) override;
ResultStatus ReadIcon(std::vector<u8>& buffer) override; ResultStatus ReadIcon(std::vector<u8>& buffer) override;
ResultStatus ReadTitle(std::string& title) override; ResultStatus ReadTitle(std::string& title) override;
ResultStatus ReadControlData(FileSys::NACP& nacp) override; ResultStatus ReadControlData(FileSys::NACP& nacp) override;
ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) override; ResultStatus ReadManualRomFS(FileSys::VirtualFile& out_file) override;
ResultStatus ReadBanner(std::vector<u8>& buffer) override; ResultStatus ReadBanner(std::vector<u8>& buffer) override;
ResultStatus ReadLogo(std::vector<u8>& buffer) override; ResultStatus ReadLogo(std::vector<u8>& buffer) override;

View file

@ -20,11 +20,11 @@
namespace Loader { namespace Loader {
AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file, AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file_,
const Service::FileSystem::FileSystemController& fsc, const Service::FileSystem::FileSystemController& fsc,
const FileSys::ContentProvider& content_provider, const FileSys::ContentProvider& content_provider,
std::size_t program_index) std::size_t program_index)
: AppLoader(file), xci(std::make_unique<FileSys::XCI>(file, program_index)), : AppLoader(file_), xci(std::make_unique<FileSys::XCI>(file_, program_index)),
nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) { nca_loader(std::make_unique<AppLoader_NCA>(xci->GetProgramNCAFile())) {
if (xci->GetStatus() != ResultStatus::Success) { if (xci->GetStatus() != ResultStatus::Success) {
return; return;
@ -43,8 +43,8 @@ AppLoader_XCI::AppLoader_XCI(FileSys::VirtualFile file,
AppLoader_XCI::~AppLoader_XCI() = default; AppLoader_XCI::~AppLoader_XCI() = default;
FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& file) { FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& xci_file) {
FileSys::XCI xci(file); const FileSys::XCI xci(xci_file);
if (xci.GetStatus() == ResultStatus::Success && if (xci.GetStatus() == ResultStatus::Success &&
xci.GetNCAByType(FileSys::NCAContentType::Program) != nullptr && xci.GetNCAByType(FileSys::NCAContentType::Program) != nullptr &&
@ -87,31 +87,33 @@ AppLoader_XCI::LoadResult AppLoader_XCI::Load(Kernel::Process& process, Core::Sy
return result; return result;
} }
ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& file) { ResultStatus AppLoader_XCI::ReadRomFS(FileSys::VirtualFile& out_file) {
return nca_loader->ReadRomFS(file); return nca_loader->ReadRomFS(out_file);
} }
u64 AppLoader_XCI::ReadRomFSIVFCOffset() const { u64 AppLoader_XCI::ReadRomFSIVFCOffset() const {
return nca_loader->ReadRomFSIVFCOffset(); return nca_loader->ReadRomFSIVFCOffset();
} }
ResultStatus AppLoader_XCI::ReadUpdateRaw(FileSys::VirtualFile& file) { ResultStatus AppLoader_XCI::ReadUpdateRaw(FileSys::VirtualFile& out_file) {
u64 program_id{}; u64 program_id{};
nca_loader->ReadProgramId(program_id); nca_loader->ReadProgramId(program_id);
if (program_id == 0) if (program_id == 0) {
return ResultStatus::ErrorXCIMissingProgramNCA; return ResultStatus::ErrorXCIMissingProgramNCA;
}
const auto read = xci->GetSecurePartitionNSP()->GetNCAFile( const auto read = xci->GetSecurePartitionNSP()->GetNCAFile(
FileSys::GetUpdateTitleID(program_id), FileSys::ContentRecordType::Program); FileSys::GetUpdateTitleID(program_id), FileSys::ContentRecordType::Program);
if (read == nullptr) {
if (read == nullptr)
return ResultStatus::ErrorNoPackedUpdate; return ResultStatus::ErrorNoPackedUpdate;
}
const auto nca_test = std::make_shared<FileSys::NCA>(read); const auto nca_test = std::make_shared<FileSys::NCA>(read);
if (nca_test->GetStatus() != ResultStatus::ErrorMissingBKTRBaseRomFS) {
if (nca_test->GetStatus() != ResultStatus::ErrorMissingBKTRBaseRomFS)
return nca_test->GetStatus(); return nca_test->GetStatus();
}
file = read; out_file = read;
return ResultStatus::Success; return ResultStatus::Success;
} }
@ -120,33 +122,41 @@ ResultStatus AppLoader_XCI::ReadProgramId(u64& out_program_id) {
} }
ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) { ResultStatus AppLoader_XCI::ReadIcon(std::vector<u8>& buffer) {
if (icon_file == nullptr) if (icon_file == nullptr) {
return ResultStatus::ErrorNoControl; return ResultStatus::ErrorNoControl;
}
buffer = icon_file->ReadAllBytes(); buffer = icon_file->ReadAllBytes();
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_XCI::ReadTitle(std::string& title) { ResultStatus AppLoader_XCI::ReadTitle(std::string& title) {
if (nacp_file == nullptr) if (nacp_file == nullptr) {
return ResultStatus::ErrorNoControl; return ResultStatus::ErrorNoControl;
}
title = nacp_file->GetApplicationName(); title = nacp_file->GetApplicationName();
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_XCI::ReadControlData(FileSys::NACP& control) { ResultStatus AppLoader_XCI::ReadControlData(FileSys::NACP& control) {
if (nacp_file == nullptr) if (nacp_file == nullptr) {
return ResultStatus::ErrorNoControl; return ResultStatus::ErrorNoControl;
}
control = *nacp_file; control = *nacp_file;
return ResultStatus::Success; return ResultStatus::Success;
} }
ResultStatus AppLoader_XCI::ReadManualRomFS(FileSys::VirtualFile& file) { ResultStatus AppLoader_XCI::ReadManualRomFS(FileSys::VirtualFile& out_file) {
const auto nca = xci->GetSecurePartitionNSP()->GetNCA(xci->GetProgramTitleID(), const auto nca = xci->GetSecurePartitionNSP()->GetNCA(xci->GetProgramTitleID(),
FileSys::ContentRecordType::HtmlDocument); FileSys::ContentRecordType::HtmlDocument);
if (xci->GetStatus() != ResultStatus::Success || nca == nullptr) if (xci->GetStatus() != ResultStatus::Success || nca == nullptr) {
return ResultStatus::ErrorXCIMissingPartition; return ResultStatus::ErrorXCIMissingPartition;
file = nca->GetRomFS(); }
return file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success;
out_file = nca->GetRomFS();
return out_file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success;
} }
ResultStatus AppLoader_XCI::ReadBanner(std::vector<u8>& buffer) { ResultStatus AppLoader_XCI::ReadBanner(std::vector<u8>& buffer) {

View file

@ -26,18 +26,20 @@ class AppLoader_NCA;
/// Loads an XCI file /// Loads an XCI file
class AppLoader_XCI final : public AppLoader { class AppLoader_XCI final : public AppLoader {
public: public:
explicit AppLoader_XCI(FileSys::VirtualFile file, explicit AppLoader_XCI(FileSys::VirtualFile file_,
const Service::FileSystem::FileSystemController& fsc, const Service::FileSystem::FileSystemController& fsc,
const FileSys::ContentProvider& content_provider, const FileSys::ContentProvider& content_provider,
std::size_t program_index); std::size_t program_index);
~AppLoader_XCI() override; ~AppLoader_XCI() override;
/** /**
* Returns the type of the file * Identifies whether or not the given file is an XCI file.
* @param file open file *
* @return FileType found, or FileType::Error if this loader doesn't know it * @param xci_file The file to identify.
*
* @return FileType::XCI, or FileType::Error if the file is not an XCI file.
*/ */
static FileType IdentifyType(const FileSys::VirtualFile& file); static FileType IdentifyType(const FileSys::VirtualFile& xci_file);
FileType GetFileType() const override { FileType GetFileType() const override {
return IdentifyType(file); return IdentifyType(file);
@ -45,14 +47,14 @@ public:
LoadResult Load(Kernel::Process& process, Core::System& system) override; LoadResult Load(Kernel::Process& process, Core::System& system) override;
ResultStatus ReadRomFS(FileSys::VirtualFile& file) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override;
u64 ReadRomFSIVFCOffset() const override; u64 ReadRomFSIVFCOffset() const override;
ResultStatus ReadUpdateRaw(FileSys::VirtualFile& file) override; ResultStatus ReadUpdateRaw(FileSys::VirtualFile& out_file) override;
ResultStatus ReadProgramId(u64& out_program_id) override; ResultStatus ReadProgramId(u64& out_program_id) override;
ResultStatus ReadIcon(std::vector<u8>& buffer) override; ResultStatus ReadIcon(std::vector<u8>& buffer) override;
ResultStatus ReadTitle(std::string& title) override; ResultStatus ReadTitle(std::string& title) override;
ResultStatus ReadControlData(FileSys::NACP& control) override; ResultStatus ReadControlData(FileSys::NACP& control) override;
ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) override; ResultStatus ReadManualRomFS(FileSys::VirtualFile& out_file) override;
ResultStatus ReadBanner(std::vector<u8>& buffer) override; ResultStatus ReadBanner(std::vector<u8>& buffer) override;
ResultStatus ReadLogo(std::vector<u8>& buffer) override; ResultStatus ReadLogo(std::vector<u8>& buffer) override;

View file

@ -155,19 +155,16 @@ void Adapter::UpdateStateAxes(std::size_t port, const AdapterPayload& adapter_pa
for (const PadAxes axis : axes) { for (const PadAxes axis : axes) {
const auto index = static_cast<std::size_t>(axis); const auto index = static_cast<std::size_t>(axis);
const u8 axis_value = adapter_payload[offset + 3 + index]; const u8 axis_value = adapter_payload[offset + 3 + index];
if (pads[port].reset_origin_counter <= 3) { if (pads[port].reset_origin_counter <= 18) {
if (pads[port].axis_origin[index] != axis_value) { if (pads[port].axis_origin[index] != axis_value) {
pads[port].reset_origin_counter = 0; pads[port].reset_origin_counter = 0;
} }
pads[port].axis_origin[index] = axis_value; pads[port].axis_origin[index] = axis_value;
pads[port].reset_origin_counter++;
} }
pads[port].axis_values[index] = pads[port].axis_values[index] =
static_cast<s16>(axis_value - pads[port].axis_origin[index]); static_cast<s16>(axis_value - pads[port].axis_origin[index]);
} }
if (pads[port].reset_origin_counter <= 3) {
pads[port].reset_origin_counter++;
}
} }
void Adapter::UpdateYuzuSettings(std::size_t port) { void Adapter::UpdateYuzuSettings(std::size_t port) {