summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/hex_util.cpp2
-rw-r--r--src/common/hex_util.h2
-rw-r--r--src/core/file_sys/ips_layer.cpp48
-rw-r--r--src/core/file_sys/ips_layer.h14
-rw-r--r--src/core/file_sys/patch_manager.cpp6
5 files changed, 39 insertions, 33 deletions
diff --git a/src/common/hex_util.cpp b/src/common/hex_util.cpp
index e516e5bbd..5b63f9e81 100644
--- a/src/common/hex_util.cpp
+++ b/src/common/hex_util.cpp
@@ -30,7 +30,7 @@ std::vector<u8> HexStringToVector(std::string_view str, bool little_endian) {
30 return out; 30 return out;
31} 31}
32 32
33std::string HexVectorToString(std::vector<u8> vector, bool upper) { 33std::string HexVectorToString(const std::vector<u8>& vector, bool upper) {
34 std::string out; 34 std::string out;
35 for (u8 c : vector) 35 for (u8 c : vector)
36 out += fmt::format(upper ? "{:02X}" : "{:02x}", c); 36 out += fmt::format(upper ? "{:02X}" : "{:02x}", c);
diff --git a/src/common/hex_util.h b/src/common/hex_util.h
index 0b7d3592a..68f003cb6 100644
--- a/src/common/hex_util.h
+++ b/src/common/hex_util.h
@@ -30,7 +30,7 @@ std::array<u8, Size> HexStringToArray(std::string_view str) {
30 return out; 30 return out;
31} 31}
32 32
33std::string HexVectorToString(std::vector<u8> vector, bool upper = true); 33std::string HexVectorToString(const std::vector<u8>& vector, bool upper = true);
34 34
35template <std::size_t Size> 35template <std::size_t Size>
36std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) { 36std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) {
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp
index 6c5535f83..abe3dcf62 100644
--- a/src/core/file_sys/ips_layer.cpp
+++ b/src/core/file_sys/ips_layer.cpp
@@ -17,9 +17,10 @@ enum class IPSFileType {
17 Error, 17 Error,
18}; 18};
19 19
20const std::map<const char*, const char*> ESCAPE_CHARACTER_MAP{ 20constexpr std::array<std::pair<const char*, const char*>, 11> ESCAPE_CHARACTER_MAP{
21 {"\\a", "\a"}, {"\\b", "\b"}, {"\\f", "\f"}, {"\\n", "\n"}, {"\\r", "\r"}, {"\\t", "\t"}, 21 std::pair{"\\a", "\a"}, {"\\b", "\b"}, {"\\f", "\f"}, {"\\n", "\n"},
22 {"\\v", "\v"}, {"\\\\", "\\"}, {"\\\'", "\'"}, {"\\\"", "\""}, {"\\\?", "\?"}, 22 {"\\r", "\r"}, {"\\t", "\t"}, {"\\v", "\v"}, {"\\\\", "\\"},
23 {"\\\'", "\'"}, {"\\\"", "\""}, {"\\\?", "\?"},
23}; 24};
24 25
25static IPSFileType IdentifyMagic(const std::vector<u8>& magic) { 26static IPSFileType IdentifyMagic(const std::vector<u8>& magic) {
@@ -92,12 +93,12 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
92 return std::make_shared<VectorVfsFile>(in_data, in->GetName(), in->GetContainingDirectory()); 93 return std::make_shared<VectorVfsFile>(in_data, in->GetName(), in->GetContainingDirectory());
93} 94}
94 95
95IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) 96IPSwitchCompiler::IPSwitchCompiler(VirtualFile patch_text_) : patch_text(std::move(patch_text_)) {
96 : valid(false), patch_text(std::move(patch_text_)), nso_build_id{}, is_little_endian(false),
97 offset_shift(0), print_values(false), last_comment("") {
98 Parse(); 97 Parse();
99} 98}
100 99
100IPSwitchCompiler::~IPSwitchCompiler() = default;
101
101std::array<u8, 32> IPSwitchCompiler::GetBuildID() const { 102std::array<u8, 32> IPSwitchCompiler::GetBuildID() const {
102 return nso_build_id; 103 return nso_build_id;
103} 104}
@@ -106,7 +107,7 @@ bool IPSwitchCompiler::IsValid() const {
106 return valid; 107 return valid;
107} 108}
108 109
109static bool StartsWith(const std::string& base, const std::string& check) { 110static bool StartsWith(std::string_view base, std::string_view check) {
110 return base.size() >= check.size() && base.substr(0, check.size()) == check; 111 return base.size() >= check.size() && base.substr(0, check.size()) == check;
111} 112}
112 113
@@ -128,21 +129,22 @@ void IPSwitchCompiler::Parse() {
128 s.write(reinterpret_cast<const char*>(bytes.data()), bytes.size()); 129 s.write(reinterpret_cast<const char*>(bytes.data()), bytes.size());
129 130
130 std::vector<std::string> lines; 131 std::vector<std::string> lines;
131 std::string line; 132 std::string stream_line;
132 while (std::getline(s, line)) { 133 while (std::getline(s, stream_line)) {
133 // Remove a trailing \r 134 // Remove a trailing \r
134 if (!line.empty() && line[line.size() - 1] == '\r') 135 if (!stream_line.empty() && stream_line.back() == '\r')
135 line = line.substr(0, line.size() - 1); 136 stream_line.pop_back();
136 lines.push_back(line); 137 lines.push_back(std::move(stream_line));
137 } 138 }
138 139
139 for (std::size_t i = 0; i < lines.size(); ++i) { 140 for (std::size_t i = 0; i < lines.size(); ++i) {
140 auto line = lines[i]; 141 auto line = lines[i];
141 142
142 // Remove midline comments 143 // Remove midline comments
143 if (!StartsWith(line, "//") && line.find("//") != std::string::npos) { 144 const auto comment_index = line.find("//");
144 last_comment = line.substr(line.find("//") + 2); 145 if (!StartsWith(line, "//") && comment_index != std::string::npos) {
145 line = line.substr(0, line.find("//")); 146 last_comment = line.substr(comment_index + 2);
147 line = line.substr(0, comment_index);
146 } 148 }
147 149
148 if (StartsWith(line, "@stop")) { 150 if (StartsWith(line, "@stop")) {
@@ -191,28 +193,28 @@ void IPSwitchCompiler::Parse() {
191 while (true) { 193 while (true) {
192 if (i + 1 >= lines.size()) 194 if (i + 1 >= lines.size())
193 break; 195 break;
194 line = lines[++i]; 196 const auto patch_line = lines[++i];
195 197
196 // 11 - 8 hex digit offset + space + minimum two digit overwrite val 198 // 11 - 8 hex digit offset + space + minimum two digit overwrite val
197 if (line.length() < 11) 199 if (patch_line.length() < 11)
198 break; 200 break;
199 auto offset = std::stoul(line.substr(0, 8), nullptr, 16); 201 auto offset = std::stoul(patch_line.substr(0, 8), nullptr, 16);
200 offset += offset_shift; 202 offset += offset_shift;
201 203
202 std::vector<u8> replace; 204 std::vector<u8> replace;
203 // 9 - first char of replacement val 205 // 9 - first char of replacement val
204 if (line[9] == '\"') { 206 if (patch_line[9] == '\"') {
205 // string replacement 207 // string replacement
206 const auto end_index = line.find('\"', 10); 208 const auto end_index = patch_line.find('\"', 10);
207 if (end_index == std::string::npos || end_index < 10) 209 if (end_index == std::string::npos || end_index < 10)
208 return; 210 return;
209 auto value = line.substr(10, end_index - 10); 211 auto value = patch_line.substr(10, end_index - 10);
210 value = EscapeStringSequences(value); 212 value = EscapeStringSequences(value);
211 replace.reserve(value.size()); 213 replace.reserve(value.size());
212 std::copy(value.begin(), value.end(), std::back_inserter(replace)); 214 std::copy(value.begin(), value.end(), std::back_inserter(replace));
213 } else { 215 } else {
214 // hex replacement 216 // hex replacement
215 const auto value = line.substr(9); 217 const auto value = patch_line.substr(9);
216 replace.reserve(value.size() / 2); 218 replace.reserve(value.size() / 2);
217 replace = Common::HexStringToVector(value, is_little_endian); 219 replace = Common::HexStringToVector(value, is_little_endian);
218 } 220 }
@@ -224,7 +226,7 @@ void IPSwitchCompiler::Parse() {
224 patch_text->GetName(), offset, Common::HexVectorToString(replace)); 226 patch_text->GetName(), offset, Common::HexVectorToString(replace));
225 } 227 }
226 228
227 patch.records.emplace(offset, replace); 229 patch.records.emplace(offset, std::move(replace));
228 } 230 }
229 231
230 patches.push_back(std::move(patch)); 232 patches.push_back(std::move(patch));
diff --git a/src/core/file_sys/ips_layer.h b/src/core/file_sys/ips_layer.h
index 847e9bf3c..b07cc5673 100644
--- a/src/core/file_sys/ips_layer.h
+++ b/src/core/file_sys/ips_layer.h
@@ -15,6 +15,8 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips);
15class IPSwitchCompiler { 15class IPSwitchCompiler {
16public: 16public:
17 explicit IPSwitchCompiler(VirtualFile patch_text); 17 explicit IPSwitchCompiler(VirtualFile patch_text);
18 ~IPSwitchCompiler();
19
18 std::array<u8, 0x20> GetBuildID() const; 20 std::array<u8, 0x20> GetBuildID() const;
19 bool IsValid() const; 21 bool IsValid() const;
20 VirtualFile Apply(const VirtualFile& in) const; 22 VirtualFile Apply(const VirtualFile& in) const;
@@ -22,7 +24,7 @@ public:
22private: 24private:
23 void Parse(); 25 void Parse();
24 26
25 bool valid; 27 bool valid = false;
26 28
27 struct IPSwitchPatch { 29 struct IPSwitchPatch {
28 std::string name; 30 std::string name;
@@ -32,11 +34,11 @@ private:
32 34
33 VirtualFile patch_text; 35 VirtualFile patch_text;
34 std::vector<IPSwitchPatch> patches; 36 std::vector<IPSwitchPatch> patches;
35 std::array<u8, 0x20> nso_build_id; 37 std::array<u8, 0x20> nso_build_id{};
36 bool is_little_endian; 38 bool is_little_endian = false;
37 s64 offset_shift; 39 s64 offset_shift = 0;
38 bool print_values; 40 bool print_values = false;
39 std::string last_comment; 41 std::string last_comment = "";
40}; 42};
41 43
42} // namespace FileSys 44} // namespace FileSys
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index f148e7719..03df24906 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -273,11 +273,13 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam
273 if (mod_dir != nullptr && mod_dir->GetSize() > 0) { 273 if (mod_dir != nullptr && mod_dir->GetSize() > 0) {
274 for (const auto& mod : mod_dir->GetSubdirectories()) { 274 for (const auto& mod : mod_dir->GetSubdirectories()) {
275 std::string types; 275 std::string types;
276 if (IsDirValidAndNonEmpty(mod->GetSubdirectory("exefs"))) { 276
277 const auto exefs_dir = mod->GetSubdirectory("exefs");
278 if (IsDirValidAndNonEmpty(exefs_dir)) {
277 bool ips = false; 279 bool ips = false;
278 bool ipswitch = false; 280 bool ipswitch = false;
279 281
280 for (const auto& file : mod->GetSubdirectory("exefs")->GetFiles()) { 282 for (const auto& file : exefs_dir->GetFiles()) {
281 if (file->GetExtension() == "ips") 283 if (file->GetExtension() == "ips")
282 ips = true; 284 ips = true;
283 else if (file->GetExtension() == "pchtxt") 285 else if (file->GetExtension() == "pchtxt")