summaryrefslogtreecommitdiffstats
path: root/src/core/file_sys
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/file_sys')
-rw-r--r--src/core/file_sys/control_metadata.cpp42
-rw-r--r--src/core/file_sys/control_metadata.h81
-rw-r--r--src/core/file_sys/mode.h6
-rw-r--r--src/core/file_sys/vfs_real.cpp47
4 files changed, 156 insertions, 20 deletions
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp
new file mode 100644
index 000000000..3ddc9f162
--- /dev/null
+++ b/src/core/file_sys/control_metadata.cpp
@@ -0,0 +1,42 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/string_util.h"
+#include "common/swap.h"
+#include "core/file_sys/control_metadata.h"
+
+namespace FileSys {
+
+std::string LanguageEntry::GetApplicationName() const {
+ return Common::StringFromFixedZeroTerminatedBuffer(application_name.data(), 0x200);
+}
+
+std::string LanguageEntry::GetDeveloperName() const {
+ return Common::StringFromFixedZeroTerminatedBuffer(developer_name.data(), 0x100);
+}
+
+NACP::NACP(VirtualFile file_) : file(std::move(file_)), raw(std::make_unique<RawNACP>()) {
+ file->ReadObject(raw.get());
+}
+
+const LanguageEntry& NACP::GetLanguageEntry(Language language) const {
+ return raw->language_entries.at(static_cast<u8>(language));
+}
+
+std::string NACP::GetApplicationName(Language language) const {
+ return GetLanguageEntry(language).GetApplicationName();
+}
+
+std::string NACP::GetDeveloperName(Language language) const {
+ return GetLanguageEntry(language).GetDeveloperName();
+}
+
+u64 NACP::GetTitleId() const {
+ return raw->title_id;
+}
+
+std::string NACP::GetVersionString() const {
+ return Common::StringFromFixedZeroTerminatedBuffer(raw->version_string.data(), 0x10);
+}
+} // namespace FileSys
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h
new file mode 100644
index 000000000..cc3b745f7
--- /dev/null
+++ b/src/core/file_sys/control_metadata.h
@@ -0,0 +1,81 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <memory>
+#include <string>
+#include "common/common_funcs.h"
+#include "core/file_sys/vfs.h"
+
+namespace FileSys {
+
+// A localized entry containing strings within the NACP.
+// One for each language of type Language.
+struct LanguageEntry {
+ std::array<char, 0x200> application_name;
+ std::array<char, 0x100> developer_name;
+
+ std::string GetApplicationName() const;
+ std::string GetDeveloperName() const;
+};
+static_assert(sizeof(LanguageEntry) == 0x300, "LanguageEntry has incorrect size.");
+
+// The raw file format of a NACP file.
+struct RawNACP {
+ std::array<LanguageEntry, 16> language_entries;
+ INSERT_PADDING_BYTES(0x38);
+ u64_le title_id;
+ INSERT_PADDING_BYTES(0x20);
+ std::array<char, 0x10> version_string;
+ u64_le dlc_base_title_id;
+ u64_le title_id_2;
+ INSERT_PADDING_BYTES(0x28);
+ u64_le product_code;
+ u64_le title_id_3;
+ std::array<u64_le, 0x7> title_id_array;
+ INSERT_PADDING_BYTES(0x8);
+ u64_le title_id_update;
+ std::array<u8, 0x40> bcat_passphrase;
+ INSERT_PADDING_BYTES(0xEC0);
+};
+static_assert(sizeof(RawNACP) == 0x4000, "RawNACP has incorrect size.");
+
+// A language on the NX. These are for names and icons.
+enum class Language : u8 {
+ AmericanEnglish = 0,
+ BritishEnglish = 1,
+ Japanese = 2,
+ French = 3,
+ German = 4,
+ LatinAmericanSpanish = 5,
+ Spanish = 6,
+ Italian = 7,
+ Dutch = 8,
+ CanadianFrench = 9,
+ Portugese = 10,
+ Russian = 11,
+ Korean = 12,
+ Taiwanese = 13,
+ Chinese = 14,
+};
+
+// A class representing the format used by NX metadata files, typically named Control.nacp.
+// These store application name, dev name, title id, and other miscellaneous data.
+class NACP {
+public:
+ explicit NACP(VirtualFile file);
+ const LanguageEntry& GetLanguageEntry(Language language = Language::AmericanEnglish) const;
+ std::string GetApplicationName(Language language = Language::AmericanEnglish) const;
+ std::string GetDeveloperName(Language language = Language::AmericanEnglish) const;
+ u64 GetTitleId() const;
+ std::string GetVersionString() const;
+
+private:
+ VirtualFile file;
+ std::unique_ptr<RawNACP> raw;
+};
+
+} // namespace FileSys
diff --git a/src/core/file_sys/mode.h b/src/core/file_sys/mode.h
index b4363152a..c95205668 100644
--- a/src/core/file_sys/mode.h
+++ b/src/core/file_sys/mode.h
@@ -11,7 +11,13 @@ namespace FileSys {
enum class Mode : u32 {
Read = 1,
Write = 2,
+ ReadWrite = 3,
Append = 4,
+ WriteAppend = 6,
};
+inline u32 operator&(Mode lhs, Mode rhs) {
+ return static_cast<u32>(lhs) & static_cast<u32>(rhs);
+}
+
} // namespace FileSys
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp
index 095fec77e..9ce2e1efa 100644
--- a/src/core/file_sys/vfs_real.cpp
+++ b/src/core/file_sys/vfs_real.cpp
@@ -13,24 +13,31 @@
namespace FileSys {
-static std::string PermissionsToCharArray(Mode perms) {
- std::string out;
- switch (perms) {
- case Mode::Read:
- out += "r";
- break;
- case Mode::Write:
- out += "r+";
- break;
- case Mode::Append:
- out += "a";
- break;
+static std::string ModeFlagsToString(Mode mode) {
+ std::string mode_str;
+
+ // Calculate the correct open mode for the file.
+ if (mode & Mode::Read && mode & Mode::Write) {
+ if (mode & Mode::Append)
+ mode_str = "a+";
+ else
+ mode_str = "r+";
+ } else {
+ if (mode & Mode::Read)
+ mode_str = "r";
+ else if (mode & Mode::Append)
+ mode_str = "a";
+ else if (mode & Mode::Write)
+ mode_str = "w";
}
- return out + "b";
+
+ mode_str += "b";
+
+ return mode_str;
}
RealVfsFile::RealVfsFile(const std::string& path_, Mode perms_)
- : backing(path_, PermissionsToCharArray(perms_).c_str()), path(path_),
+ : backing(path_, ModeFlagsToString(perms_).c_str()), path(path_),
parent_path(FileUtil::GetParentPath(path_)),
path_components(FileUtil::SplitPathComponents(path_)),
parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)),
@@ -53,11 +60,11 @@ std::shared_ptr<VfsDirectory> RealVfsFile::GetContainingDirectory() const {
}
bool RealVfsFile::IsWritable() const {
- return perms == Mode::Append || perms == Mode::Write;
+ return (perms & Mode::WriteAppend) != 0;
}
bool RealVfsFile::IsReadable() const {
- return perms == Mode::Read || perms == Mode::Write;
+ return (perms & Mode::ReadWrite) != 0;
}
size_t RealVfsFile::Read(u8* data, size_t length, size_t offset) const {
@@ -79,7 +86,7 @@ bool RealVfsFile::Rename(std::string_view name) {
path = (parent_path + DIR_SEP).append(name);
path_components = parent_components;
path_components.push_back(std::move(name_str));
- backing = FileUtil::IOFile(path, PermissionsToCharArray(perms).c_str());
+ backing = FileUtil::IOFile(path, ModeFlagsToString(perms).c_str());
return out;
}
@@ -93,7 +100,7 @@ RealVfsDirectory::RealVfsDirectory(const std::string& path_, Mode perms_)
path_components(FileUtil::SplitPathComponents(path)),
parent_components(FileUtil::SliceVector(path_components, 0, path_components.size() - 1)),
perms(perms_) {
- if (!FileUtil::Exists(path) && (perms == Mode::Write || perms == Mode::Append))
+ if (!FileUtil::Exists(path) && perms & Mode::WriteAppend)
FileUtil::CreateDir(path);
if (perms == Mode::Append)
@@ -120,11 +127,11 @@ std::vector<std::shared_ptr<VfsDirectory>> RealVfsDirectory::GetSubdirectories()
}
bool RealVfsDirectory::IsWritable() const {
- return perms == Mode::Write || perms == Mode::Append;
+ return (perms & Mode::WriteAppend) != 0;
}
bool RealVfsDirectory::IsReadable() const {
- return perms == Mode::Read || perms == Mode::Write;
+ return (perms & Mode::ReadWrite) != 0;
}
std::string RealVfsDirectory::GetName() const {